summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-08-25 03:05:10 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-08-25 03:05:10 +0000
commit0cac724924ae8aadf9e12dd2aedc3eb0bf8de901 (patch)
tree1910a147296d1c2e6c6f1650227f205b50aa4f86
parent9126c2d2b1c1283bdf8b48c608ede572859fb5e4 (diff)
downloadgpsd-0cac724924ae8aadf9e12dd2aedc3eb0bf8de901.tar.gz
Change the way JSON parse templates are declared...
so that string lengths won't step on offsets.
-rw-r--r--json.c37
-rw-r--r--json.h7
-rw-r--r--test_json.c2
3 files changed, 30 insertions, 16 deletions
diff --git a/json.c b/json.c
index 8b204776..c5e5b4b2 100644
--- a/json.c
+++ b/json.c
@@ -31,13 +31,21 @@ elements of an array must be of the same type.
JSON object or a JSON array. JSON "float" quantities are actually
stored as doubles.
- The only really opaque part of the interface is structobjects.
-This is a way to parse a list of objects to a set of modifications to
-a corresponding array of C structs. The trick is that the array
-object initialization has to specify both the C struct array's base
-address and the stride length (the size of the C struct. If you
-initialize the offset fields with the correct offsetof() calls,
-everything will work.
+ This paraer processes object arrays in one of two different ways,
+defending on whether the array subtype is declared as object or structobject.
+
+ Object arrays take one base address per object subfield, and are
+mapped into parallel C arrays (one per subfield). Strings are not
+supported in this kind of array, as the don't have a "natural" size
+to use as an offset multiplier.
+
+ Structobjects arrays are a way to parse a list of objects to a set
+of modifications to a corresponding array of C structs. The trick is
+that the array object initialization has to specify both the C struct
+array's base address and the stride length (the size of the C struct.
+If you initialize the offset fields with the correct offsetof() calls,
+everything will work. Strings are suppported but all string storage
+has to be inline in the struct.
***************************************************************************/
#include <stdio.h>
@@ -69,7 +77,10 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a
cursor->addr.real[offset] = cursor->dflt.real;
break;
case string:
- cursor->addr.string.ptr[offset] = '\0';
+ if (offset > 0)
+ return JSON_ERR_NOPARSTR;
+ else
+ cursor->addr.string[0] = '\0';
break;
case boolean:
/* nullbool default says not to set the value at all */
@@ -202,7 +213,7 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a
break;
case in_val_string:
if (cursor->type == string)
- maxlen = cursor->addr.string.len - 1;
+ maxlen = cursor->len - 1;
else if (cursor->type == check)
maxlen = strlen(cursor->dflt.check);
if (*cp == '"') {
@@ -248,7 +259,10 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a
cursor->addr.real[offset] = atof(valbuf);
break;
case string:
- (void)strncpy(cursor->addr.string.ptr+offset, valbuf, cursor->addr.string.len);
+ if (offset > 0)
+ return JSON_ERR_NOPARSTR;
+ else
+ (void)strncpy(cursor->addr.string, valbuf, cursor->len);
break;
case boolean:
cursor->addr.boolean[offset] = (bool)!strcmp(valbuf, "true");
@@ -278,7 +292,7 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a
*((double *)lptr) = atof(valbuf);
break;
case string:
- (void)strncpy(lptr, valbuf, cursor->addr.string.len);
+ (void)strncpy(lptr, valbuf, cursor->len);
break;
case boolean:
*((bool *)lptr) = (bool)!strcmp(valbuf, "true");
@@ -450,6 +464,7 @@ const char *json_error_string(int err)
"error while string parsing",
"check attribute not matched",
"invalid flag token",
+ "can't support strings in aparalle. arrays",
};
if (err <= 0 || err >= (int)(sizeof(errors)/sizeof(errors[0])))
diff --git a/json.h b/json.h
index 0e830dce..e6505d69 100644
--- a/json.h
+++ b/json.h
@@ -32,10 +32,7 @@ struct json_attr_t {
union {
int *integer;
double *real;
- struct {
- char *ptr;
- int len;
- } string;
+ char *string;
bool *boolean;
struct json_array_t array;
size_t offset;
@@ -46,6 +43,7 @@ struct json_attr_t {
bool boolean;
char *check;
} dflt;
+ size_t len;
};
#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
@@ -72,5 +70,6 @@ const char *json_error_string(int);
#define JSON_ERR_BADSTRING 15 /* error while string parsing */
#define JSON_ERR_CHECKFAIL 16 /* check attribute not matched */
#define JSON_ERR_BADENUM 17 /* invalid flag token */
+#define JSON_ERR_NOPARSTR 18 /* can't support strings in aparalle. arrays */
/* json.h ends here */
diff --git a/test_json.c b/test_json.c
index ef92dca0..a71625e1 100644
--- a/test_json.c
+++ b/test_json.c
@@ -144,7 +144,7 @@ static int dumbcount;
static const struct json_attr_t json_attrs_6_subtype[] = {
{"name", string, .addr.offset = offsetof(struct dumbstruct_t, name),
- .addr.string.len = 64},
+ .len = 64},
{"flag", boolean, .addr.offset = offsetof(struct dumbstruct_t, flag),},
{"count", integer, .addr.offset = offsetof(struct dumbstruct_t, count),},
{NULL},