Changeset: 348cf55b433b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=348cf55b433b
Modified Files:
monetdb5/modules/atoms/json_atom.c
Branch: Jan2014
Log Message:
Fixed a bunch of buffer overruns.
diffs (truncated from 347 to 300 lines):
diff --git a/monetdb5/modules/atoms/json_atom.c
b/monetdb5/modules/atoms/json_atom.c
--- a/monetdb5/modules/atoms/json_atom.c
+++ b/monetdb5/modules/atoms/json_atom.c
@@ -41,7 +41,7 @@ int
JSONfromString(str src, int *len, json *j)
{
ssize_t slen = (ssize_t) strlen(src);
- if ((ssize_t) *len < slen)
+ if ((ssize_t) *len <= slen)
*j = GDKrealloc(*j, slen + 1);
*len = (int) slen;
if (GDKstrFromStr((unsigned char *) *j, (const unsigned char *) src,
slen) < 0) {
@@ -56,34 +56,38 @@ JSONfromString(str src, int *len, json *
int
JSONtoString(str *s, int *len, json src)
{
- size_t ll;
- int l, cnt = 0;
+ size_t cnt;
char *c, *dst;
if (GDK_STRNIL(src)) {
*s = GDKstrdup("null");
return 0;
}
+ /* count how much space we need for the output string */
+ cnt = 3; /* two time " plus \0 */
for (c = src; *c; c++)
switch (*c) {
case '"':
case '\\':
case '\n':
cnt++;
+ /* fall through */
+ default:
+ cnt++;
+ break;
}
- ll = strlen(src);
- assert(ll <= (size_t) INT_MAX);
- l = (int) ll + cnt + 3;
+ assert(cnt <= (size_t) INT_MAX);
- if (l >= *len) {
+ if (cnt > (size_t) *len) {
GDKfree(*s);
- *s = (str) GDKmalloc(l);
+ *s = (str) GDKmalloc(cnt);
if (*s == NULL)
return 0;
+ *len = (int) cnt;
}
dst = *s;
*dst++ = '"';
- for (c = src; *c; c++)
+ for (c = src; *c; c++) {
switch (*c) {
case '"':
case '\\':
@@ -97,10 +101,11 @@ JSONtoString(str *s, int *len, json src)
*dst++ = 'n';
break;
}
+ }
*dst++ = '"';
- *dst = 0;
- *len = l - 1;
- return *len;
+ *dst++ = 0;
+ assert((size_t) (dst - *s) == cnt);
+ return (int) (cnt - 1); /* length without \0 */
}
str
@@ -508,7 +513,7 @@ JSONfilterObjectInternal(json *ret, json
goto wrapup;
}
namebegin = j + 1;
- msg = JSONstringParser(j + 1, &j);
+ msg = JSONstringParser(namebegin, &j);
if (msg)
goto wrapup;
nameend = j - 1;
@@ -526,15 +531,16 @@ JSONfilterObjectInternal(json *ret, json
valueend = j;
// test for candidate member
- if (strncmp(*pat, namebegin, (l = nameend - namebegin)) == 0) {
- if (l + 2 > lim)
+ if (strncmp(*pat, namebegin, nameend - namebegin) == 0) {
+ l = valueend - valuebegin;
+ while (len + l + 2 > lim)
result = GDKrealloc(result, lim += BUFSIZ);
- if (strcmp("null", result) == 0) {
- strncpy(result + len, "nil", 3);
+ if (l == 4 && strncmp("null", valuebegin, 4) == 0) {
+ strcpy(result + len, "nil");
len += 3;
} else {
- strncpy(result + len, valuebegin, valueend -
valuebegin);
- len += valueend - valuebegin;
+ strncpy(result + len, valuebegin, l);
+ len += l;
}
result[len++] = ',';
result[len] = 0;
@@ -555,7 +561,7 @@ JSONfilterObjectInternal(json *ret, json
if (*j != ',')
msg = createException(MAL, "json.filter", "','
expected");
}
- found:
+ found:
if (result[1] == 0) {
result[1] = ']';
result[2] = 0;
@@ -612,14 +618,14 @@ JSONfilterArray(json *ret, json *js, int
// test for candidate member
if (idx == 0) {
l = valueend - valuebegin;
- if (l + 2 > lim - len)
+ while (len + l + 2 > lim)
result = GDKrealloc(result, lim += BUFSIZ);
- if (strcmp("null", result) == 0) {
- strncpy(result + len, "nil", 3);
+ if (l == 4 && strncmp("null", valuebegin, 4) == 0) {
+ strcpy(result + len, "nil");
len += 3;
} else {
- strncpy(result + len, valuebegin, valueend -
valuebegin);
- len += valueend - valuebegin;
+ strncpy(result + len, valuebegin, l);
+ len += l;
}
result[len++] = ']';
result[len] = 0;
@@ -714,9 +720,12 @@ JSONunnest(int *key, int *val, json *js)
goto wrapup;
nameend = j - 1;
l = nameend - namebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
- strncpy(result, namebegin, nameend - namebegin);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
+ strncpy(result, namebegin, l);
result[l] = 0;
BUNappend(bk, result, FALSE);
@@ -734,8 +743,11 @@ JSONunnest(int *key, int *val, json *js)
goto wrapup;
valueend = j;
l = valueend - valuebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
strncpy(result, valuebegin, l);
result[l] = 0;
BUNappend(bv, result, FALSE);
@@ -806,8 +818,11 @@ JSONunnestOne(int *val, json *js)
goto wrapup;
valueend = j;
l = valueend - valuebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
strncpy(result, valuebegin, l);
result[l] = 0;
BUNappend(bv, result, FALSE);
@@ -909,8 +924,11 @@ JSONunnestGrouped(int *grp, int *key, in
goto wrapup;
nameend = j - 1;
l = nameend - namebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
strncpy(result, namebegin, nameend - namebegin);
result[l] = 0;
BUNappend(bk, result, FALSE);
@@ -928,8 +946,11 @@ JSONunnestGrouped(int *grp, int *key, in
goto wrapup;
valueend = j;
l = valueend - valuebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
strncpy(result, valuebegin, l);
result[l] = 0;
BUNappend(bv, result, FALSE);
@@ -1002,9 +1023,12 @@ JSONkeys(int *ret, json *js)
goto wrapup;
nameend = j - 1;
l = nameend - namebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
- strncpy(result, namebegin, nameend - namebegin);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
+ strncpy(result, namebegin, l);
result[l] = 0;
BUNappend(bn, result, FALSE);
@@ -1068,7 +1092,7 @@ JSONkeyArray(json *ret, json *js)
if (msg)
goto wrapup;
nameend = j - 1;
- if (l + (size_t)(nameend-namebegin) + 5 > lim){
+ while (l + (size_t)(nameend-namebegin) + 5 > lim){
result = GDKrealloc(result, lim += BUFSIZ);
if ( result == NULL)
goto wrapup;
@@ -1153,7 +1177,7 @@ JSONvalueArray(json *ret, json *js)
if (msg)
goto wrapup;
nameend = j - 1;
- if (l + (size_t)(nameend-namebegin) + 5 > lim){
+ while (l + (size_t)(nameend-namebegin) + 5 > lim){
result = GDKrealloc(result, lim += BUFSIZ);
if ( result == NULL)
goto wrapup;
@@ -1207,8 +1231,11 @@ JSONarrayvalues(int *ret, BAT *bn, char
// test for candidate member
l = valueend - valuebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
strncpy(result, valuebegin, l);
result[l] = 0;
if (strcmp("null", result) == 0)
@@ -1282,9 +1309,12 @@ JSONvalues(int *ret, json *js)
goto wrapup;
valueend = j;
l = valueend - valuebegin;
- if (l + 2 > lim)
- result = GDKrealloc(result, lim += BUFSIZ);
- strncpy(result, valuebegin, valueend - valuebegin);
+ if (l + 2 > lim) {
+ GDKfree(result);
+ lim = l + 2;
+ result = GDKmalloc(lim);
+ }
+ strncpy(result, valuebegin, l);
result[l] = 0;
if (strcmp("null", result) == 0)
BUNappend(bn, str_nil, FALSE);
@@ -1349,7 +1379,7 @@ JSONrenderRowObject(BAT **bl, MalBlkPtr
if (strncmp(val, "nil", 3) == 0)
strcpy(val, "null");
l = strlen(name) + strlen(val);
- if (l > lim - len)
+ while (l > lim - len)
row = (char *) GDKrealloc(row, lim += BUFSIZ);
snprintf(row + len, lim - len, "\"%s\":%s,", name, val);
len += l + 4;
@@ -1391,9 +1421,9 @@ JSONrenderobject(Client cntxt, MalBlkPtr
for (j = 0; j < cnt; j++) {
row = JSONrenderRowObject(bl, mb, stk, pci, j);
l = strlen(row);
- if (l + 2 > lim - len)
+ while (l + 2 > lim - len)
row = (char *) GDKrealloc(row, lim = cnt * l <= lim ?
cnt * l : lim + BUFSIZ);
- strncpy(result + len, row, l + 1);
+ strcpy(result + len, row);
GDKfree(row);
len += l;
result[len++] = ',';
@@ -1427,7 +1457,7 @@ JSONrenderRowArray(BAT **bl, MalBlkPtr m
if (strncmp(val, "nil", 3) == 0)
strcpy(val, "null");
l = strlen(val);
- if (l > lim - len)
+ while (l > lim - len)
row = (char *) GDKrealloc(row, lim += BUFSIZ);
snprintf(row + len, lim - len, "%s,", val);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list