Changeset: da41913be745 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/da41913be745
Modified Files:
        gdk/gdk_atoms.c
        gdk/gdk_atoms.h
        gdk/gdk_string.c
        geom/monetdb5/geom_atoms.c
        monetdb5/modules/atoms/json.c
Branch: Dec2025
Log Message:

Fixed interface of atomRead function to read binary atoms from a stream.
If the function fails, it returns NULL and the buffer passed as argument
is unaffected.  Before, it was sometimes unaffected and sometimes freed.


diffs (truncated from 312 to 300 lines):

diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -869,19 +869,22 @@ TYPE##Read(allocator *ma, TYPE *A, size_
                if (ma) {                                               \
                        a = ma_realloc(ma, a, cnt * sizeof(TYPE), *dstlen); \
                } else {                                                \
-                       GDKfree(a);                                     \
                        a = GDKmalloc(cnt * sizeof(TYPE));              \
                }                                                       \
                if (a == NULL)                                          \
                        return NULL;                                    \
-               *dstlen = cnt * sizeof(TYPE);                           \
        }                                                               \
        if (mnstr_read##NAME##Array(s, (CAST *) a, cnt) == 0 ||         \
            mnstr_errnr(s) != MNSTR_NO__ERROR) {                        \
-               if (a != A)                                             \
+               if (ma == NULL && a != A)                               \
                        GDKfree(a);                                     \
                return NULL;                                            \
        }                                                               \
+       if (a != A) {                                                   \
+               if (ma == NULL)                                         \
+                       GDKfree(A);                                     \
+               *dstlen = cnt * sizeof(TYPE);                           \
+       }                                                               \
        return a;                                                       \
 }                                                                      \
 static gdk_return                                                      \
@@ -912,18 +915,21 @@ mskRead(allocator *ma, msk *A, size_t *d
                if (ma) {
                        a = ma_realloc(ma, a, 1, *dstlen);
                } else {
-                       GDKfree(a);
                        a = GDKmalloc(1);
                }
                if (a == NULL)
                        return NULL;
-               *dstlen = 1;
        }
        if (mnstr_readBte(s, &v) != 1) {
-               if (a != A)
+               if (ma == NULL && a != A)
                        GDKfree(a);
                return NULL;
        }
+       if (a != A) {
+               if (ma == NULL)
+                       GDKfree(A);
+               *dstlen = 1;
+       }
        *a = v != 0;
        return a;
 }
@@ -1350,18 +1356,21 @@ UUIDread(allocator *ma, void *U, size_t 
                if (ma) {
                        u = ma_realloc(ma, u, cnt * sizeof(uuid), *dstlen);
                } else {
-                       GDKfree(u);
                        u = GDKmalloc(cnt * sizeof(uuid));
                }
                if (u == NULL)
                        return NULL;
-               *dstlen = cnt * sizeof(uuid);
        }
        if (mnstr_read(s, u, UUID_SIZE, cnt) < (ssize_t) cnt) {
-               if (u != U)
+               if (ma == NULL && u != (uuid *) U)
                        GDKfree(u);
                return NULL;
        }
+       if (u != (uuid *) U) {
+               if (ma == NULL)
+                       GDKfree(U);
+               *dstlen = cnt * sizeof(uuid);
+       }
        return u;
 }
 
@@ -1500,18 +1509,21 @@ INET4read(allocator *ma, void *U, size_t
                if (ma) {
                        u = ma_realloc(ma, u, cnt * sizeof(inet4), *dstlen);
                } else {
-                       GDKfree(u);
                        u = GDKmalloc(cnt * sizeof(inet4));
                }
                if (u == NULL)
                        return NULL;
-               *dstlen = cnt * sizeof(inet4);
        }
-       if (mnstr_read(s, u, 4, cnt) < (ssize_t) cnt) {
-               if (u != U)
+       if (mnstr_read(s, u, sizeof(inet4), cnt) < (ssize_t) cnt) {
+               if (ma == NULL && u != (inet4 *) U)
                        GDKfree(u);
                return NULL;
        }
+       if (u != (inet4 *) U) {
+               if (ma == NULL)
+                       GDKfree(U);
+               *dstlen = cnt * sizeof(inet4);
+       }
        return u;
 }
 
@@ -1820,18 +1832,21 @@ INET6read(allocator *ma, void *U, size_t
                if (ma) {
                        u = ma_realloc(ma, u, cnt * sizeof(inet6), *dstlen);
                } else {
-                       GDKfree(u);
                        u = GDKmalloc(cnt * sizeof(inet6));
                }
                if (u == NULL)
                        return NULL;
-               *dstlen = cnt * sizeof(inet6);
        }
        if (mnstr_read(s, u, sizeof(inet6), cnt) < (ssize_t) cnt) {
-               if (u != U)
+               if (ma == NULL && u != (inet6 *) U)
                        GDKfree(u);
                return NULL;
        }
+       if (u != (inet6 *) U) {
+               if (ma == NULL)
+                       GDKfree(U);
+               *dstlen = cnt * sizeof(inet6);
+       }
        return u;
 }
 
@@ -2000,22 +2015,28 @@ BLOBread(allocator *ma, void *A, size_t 
 
        (void) cnt;
        assert(cnt == 1);
-       if (mnstr_readLng(s, &len) != 1 || len < 0)
+       if (mnstr_readLng(s, &len) != 1 || len < 0) {
                return NULL;
+       }
        if (a == NULL || (lng) *dstlen < len) {
                if (ma) {
                        a = ma_realloc(ma, a, (size_t) len, *dstlen);
                } else {
-                       GDKfree(a);
                        a = GDKmalloc((size_t) len);
                }
                if (a == NULL)
                        return NULL;
-               *dstlen = (size_t) len;
        }
        if (mnstr_read(s, (char *) a, (size_t) len, 1) != 1) {
+               if (ma == NULL && a != (blob *) A)
+                       GDKfree(a);
                return NULL;
        }
+       if (a != (blob *) A) {
+               if (ma == NULL)
+                       GDKfree(A);
+               *dstlen = (size_t) len;
+       }
        return a;
 }
 
diff --git a/gdk/gdk_atoms.h b/gdk/gdk_atoms.h
--- a/gdk/gdk_atoms.h
+++ b/gdk/gdk_atoms.h
@@ -24,12 +24,20 @@
  * points to.
  *
  * atomCmp returns a value less than zero/equal to zero/greater than
- * zer if the first argument points to a values which is deemed
+ * zero if the first argument points to a values which is deemed
  * smaller/equal to/larger than the value pointed to by the second
  * argument.
  *
  * atomHash calculates a hash function for the value pointed to by the
  * argument.
+ *
+ * atomRead reads cnt values from stream s and returns them in dst.  The
+ * available space in dst is given in *dstlen.  If dst is too small (or
+ * NULL), a new buffer is allocated and *dstlen is filled in with the
+ * allocated size.  atomRread returns a pointer to the buffer where the
+ * data was written.  On any kind of failure (usually either allocation
+ * or reading), the function returns NULL and dst and *dstlen are
+ * unaffected (i.e. similar to realloc).
  */
 
 #define IDLENGTH       64      /* maximum BAT id length */
diff --git a/gdk/gdk_string.c b/gdk/gdk_string.c
--- a/gdk/gdk_string.c
+++ b/gdk/gdk_string.c
@@ -755,9 +755,10 @@ strToStr(allocator *ma, char **restrict 
 }
 
 str
-strRead(allocator *ma, str a, size_t *dstlen, stream *s, size_t cnt)
+strRead(allocator *ma, str A, size_t *dstlen, stream *s, size_t cnt)
 {
        int len;
+       str a = A;
 
        (void) cnt;
        assert(cnt == 1);
@@ -767,17 +768,22 @@ strRead(allocator *ma, str a, size_t *ds
                if (ma) {
                        a = ma_realloc(ma, a, (size_t) len + 1, *dstlen);
                } else {
-                       GDKfree(a);
                        a = GDKmalloc((size_t) len + 1);
                }
                if (a == NULL)
                        return NULL;
-               *dstlen = len + 1;
        }
        if (len && mnstr_read(s, a, len, 1) != 1) {
+               if (ma == NULL && a != A)
+                       GDKfree(a);
                return NULL;
        }
        a[len] = 0;
+       if (a != A) {
+               if (ma == NULL)
+                       GDKfree(A);
+               *dstlen = len + 1;
+       }
        return a;
 }
 
diff --git a/geom/monetdb5/geom_atoms.c b/geom/monetdb5/geom_atoms.c
--- a/geom/monetdb5/geom_atoms.c
+++ b/geom/monetdb5/geom_atoms.c
@@ -186,18 +186,22 @@ wkbREAD(allocator *ma, void *A, size_t *
                if (ma) {
                        a = ma_realloc(ma, a, wkblen, *dstlen);
                } else {
-                       GDKfree(a);
                        a = GDKmalloc(wkblen);
                }
                if (a == NULL)
                        return NULL;
-               *dstlen = wkblen;
        }
        a->len = len;
        a->srid = srid;
        if (len > 0 && mnstr_read(s, (char *) a->data, len, 1) != 1) {
+               if (ma == NULL && a != (wkb *) A)
+                       GDKfree(a);
                return NULL;
        }
+       if (ma == NULL && a != (wkb *) A) {
+               GDKfree(A);
+               *dstlen = wkblen;
+       }
        return a;
 }
 
@@ -558,15 +562,15 @@ mbrREAD(allocator *ma, void *A, size_t *
                if (ma) {
                        a = ma_realloc(ma, a, cnt * sizeof(mbr), *dstlen);
                } else {
-                       GDKfree(a);
                        a = GDKmalloc(cnt * sizeof(mbr));
                }
                if (a == NULL)
                        return NULL;
-               *dstlen = cnt * sizeof(mbr);
        }
        for (i = 0, c = a; i < cnt; i++, c++) {
                if (!mnstr_readIntArray(s, v, 4)) {
+                       if (ma == NULL && a != (mbr *) A)
+                               GDKfree(a);
                        return NULL;
                }
                memcpy(vals, v, 4 * sizeof(int));
@@ -575,6 +579,10 @@ mbrREAD(allocator *ma, void *A, size_t *
                c->xmax = vals[2];
                c->ymax = vals[3];
        }
+       if (ma == NULL && a != (mbr *) A) {
+               GDKfree(A);
+               *dstlen = cnt * sizeof(mbr);
+       }
        return a;
 }
 
diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c
--- a/monetdb5/modules/atoms/json.c
+++ b/monetdb5/modules/atoms/json.c
@@ -609,15 +609,18 @@ jsonRead(allocator *ma, str a, size_t *d
        if ((a = BATatoms[TYPE_str].atomRead(ma, a, dstlen, s, cnt)) == NULL)
                return NULL;
 
-       msg = JSONstr2json_intern(ma, &out, &(size_t){0}, &(const char *){a});
-       if (ma == NULL)
-               GDKfree(a);
+       allocator *ta = MT_thread_getallocator();
+       allocator_state ta_state = ma_open(ta);
+       msg = JSONstr2json_intern(ta, &out, &(size_t){0}, &(const char *){a});
        if (msg != MAL_SUCCEED) {
+               ma_close(&ta_state);
+               if (ma == NULL)
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to