agoo 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of agoo might be problematic. Click here for more details.

data/ext/agoo/gqlcobj.h CHANGED
@@ -6,6 +6,11 @@
6
6
  #include "gqleval.h"
7
7
 
8
8
  struct _gqlCobj;
9
+ struct _gqlDoc;
10
+ struct _gqlField;
11
+ struct _gqlSel;
12
+ struct _gqlType;
13
+ struct _gqlValue;
9
14
 
10
15
  typedef struct _gqlCmethod {
11
16
  const char *key;
@@ -22,4 +27,13 @@ typedef struct _gqlCobj {
22
27
  void *ptr;
23
28
  } *gqlCobj;
24
29
 
30
+ extern struct _gqlType* gql_cobj_ref_type(gqlRef ref);
31
+ extern int gql_cobj_resolve(agooErr err,
32
+ struct _gqlDoc *doc,
33
+ gqlRef target,
34
+ struct _gqlField *field,
35
+ struct _gqlSel *sel,
36
+ struct _gqlValue *result,
37
+ int depth);
38
+
25
39
  #endif // AGOO_GQLCOBJ_H
data/ext/agoo/gqleval.c CHANGED
@@ -20,6 +20,7 @@
20
20
  #define MAX_RESOLVE_ARGS 16
21
21
 
22
22
  gqlRef gql_root = NULL;
23
+ gqlType _gql_root_type = NULL;
23
24
  gqlResolveFunc gql_resolve_func = NULL;
24
25
  gqlTypeFunc gql_type_func = NULL;
25
26
  gqlRef (*gql_root_op)(const char *op) = NULL;
@@ -31,6 +32,7 @@ static const char operation_name_str[] = "operationName";
31
32
  static const char query_str[] = "query";
32
33
  static const char variables_str[] = "variables";
33
34
 
35
+
34
36
  gqlValue (*gql_doc_eval_func)(agooErr err, gqlDoc doc) = NULL;
35
37
 
36
38
  // TBD errors should have message, location, and path
@@ -79,7 +81,9 @@ value_resp(agooRes res, gqlValue result, int status, int indent) {
79
81
 
80
82
  cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %ld\r\n\r\n",
81
83
  status, agoo_http_code_message(status), text->len);
82
- text = agoo_text_prepend(text, buf, cnt);
84
+ if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
85
+ agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
86
+ }
83
87
  agoo_res_set_message(res, text);
84
88
  }
85
89
 
@@ -176,7 +180,7 @@ frag_include(gqlDoc doc, gqlFrag frag, gqlRef ref) {
176
180
  int
177
181
  gql_set_typename(agooErr err, gqlType type, const char *key, gqlValue result) {
178
182
  gqlValue child;
179
-
183
+
180
184
  if (NULL == type) {
181
185
  return agoo_err_set(err, AGOO_ERR_EVAL, "Internal error, failed to determine the __typename.");
182
186
  }
@@ -193,7 +197,7 @@ gql_eval_sels(agooErr err, gqlDoc doc, gqlRef ref, gqlField field, gqlSel sels,
193
197
  gqlField sf = NULL;
194
198
 
195
199
  // TBD if depth over max then return an error
196
-
200
+
197
201
  for (sel = sels; NULL != sel; sel = sel->next) {
198
202
  if (NULL != field) {
199
203
  if (NULL == sel->name) {
@@ -231,6 +235,14 @@ gql_eval_sels(agooErr err, gqlDoc doc, gqlRef ref, gqlField field, gqlSel sels,
231
235
  return AGOO_ERR_OK;
232
236
  }
233
237
 
238
+ gqlType
239
+ gql_root_type() {
240
+ if (NULL == _gql_root_type && NULL != gql_type_func) {
241
+ _gql_root_type = gql_type_func(gql_root);
242
+ }
243
+ return _gql_root_type;
244
+ }
245
+
234
246
  gqlValue
235
247
  gql_doc_eval(agooErr err, gqlDoc doc) {
236
248
  gqlValue result;
@@ -241,7 +253,6 @@ gql_doc_eval(agooErr err, gqlDoc doc) {
241
253
  }
242
254
  if (NULL != (result = gql_object_create(err))) {
243
255
  const char *key;
244
- gqlType type;
245
256
  gqlField field = NULL;
246
257
  struct _gqlSel sel;
247
258
 
@@ -265,8 +276,11 @@ gql_doc_eval(agooErr err, gqlDoc doc) {
265
276
  return NULL;
266
277
  break;
267
278
  }
268
- if (NULL != (type = gql_type_get("schema"))) {
269
- field = gql_type_get_field(type, key);
279
+ if (NULL == _gql_root_type && NULL != gql_type_func) {
280
+ _gql_root_type = gql_type_func(gql_root);
281
+ }
282
+ if (NULL != _gql_root_type) {
283
+ field = gql_type_get_field(_gql_root_type, key);
270
284
  }
271
285
  if (NULL == field) {
272
286
  agoo_err_set(err, AGOO_ERR_EVAL, "GraphQL not initialized.");
@@ -274,7 +288,7 @@ gql_doc_eval(agooErr err, gqlDoc doc) {
274
288
  return NULL;
275
289
  }
276
290
  sel.name = key;
277
- sel.type = type;
291
+ sel.type = _gql_root_type;
278
292
  sel.dir = doc->op->dir;
279
293
  sel.sels = doc->op->sels;
280
294
  if (AGOO_ERR_OK != doc->funcs.resolve(err, doc, gql_root, field, &sel, result, 0)) {
@@ -290,7 +304,7 @@ parse_query_vars(agooErr err, const char *var_json, int vlen) {
290
304
  gqlValue vlist = NULL;
291
305
  gqlLink link;
292
306
  gqlVar vars = NULL;
293
-
307
+
294
308
  vlen = agoo_req_query_decode((char*)var_json, vlen);
295
309
  if (NULL == (vlist = gql_json_parse(err, var_json, vlen))) {
296
310
  goto DONE;
@@ -420,7 +434,7 @@ eval_post(agooErr err, agooReq req) {
420
434
  }
421
435
  } else if (0 == strncmp(json_content_type, s, sizeof(json_content_type) - 1)) {
422
436
  gqlLink m;
423
-
437
+
424
438
  if (NULL != (j = gql_json_parse(err, req->body.start, req->body.len))) {
425
439
  if (GQL_SCALAR_OBJECT != j->type->scalar_kind) {
426
440
  agoo_err_set(err, AGOO_ERR_TYPE, "JSON request must be an object");
@@ -496,7 +510,6 @@ gql_eval_post_hook(agooReq req) {
496
510
  if (NULL != (s = agoo_req_query_value(req, indent_str, sizeof(indent_str) - 1, &len))) {
497
511
  indent = (int)strtol(s, NULL, 10);
498
512
  }
499
-
500
513
  if (NULL == (result = eval_post(&err, req))) {
501
514
  err_resp(req->res, &err, 400);
502
515
  } else {
@@ -507,7 +520,7 @@ gql_eval_post_hook(agooReq req) {
507
520
  gqlValue
508
521
  gql_get_arg_value(gqlKeyVal args, const char *key) {
509
522
  gqlValue value = NULL;
510
-
523
+
511
524
  if (NULL != args) {
512
525
  for (; NULL != args->key; args++) {
513
526
  if (0 == strcmp(key, args->key)) {
data/ext/agoo/gqleval.h CHANGED
@@ -38,10 +38,12 @@ extern struct _gqlValue* gql_doc_eval(agooErr err, struct _gqlDoc *doc);
38
38
  extern struct _gqlValue* gql_get_arg_value(gqlKeyVal args, const char *key);
39
39
  extern int gql_eval_sels(agooErr err, struct _gqlDoc *doc, gqlRef ref, struct _gqlField *field, struct _gqlSel *sels, struct _gqlValue *result, int depth);
40
40
  extern int gql_set_typename(agooErr err, struct _gqlType *type, const char *key, struct _gqlValue *result);
41
+ extern struct _gqlType* gql_root_type();
41
42
 
42
43
  extern gqlRef gql_root;
43
44
  extern gqlResolveFunc gql_resolve_func;
44
45
  extern gqlTypeFunc gql_type_func;
46
+ extern struct _gqlType* _gql_root_type;
45
47
  extern gqlRef (*gql_root_op)(const char *op);
46
48
 
47
49
  extern struct _gqlValue* (*gql_doc_eval_func)(agooErr err, struct _gqlDoc *doc);
data/ext/agoo/gqlintro.c CHANGED
@@ -24,14 +24,14 @@ create_schema_type(agooErr err) {
24
24
  gqlType type_list;
25
25
  gqlType dir_type;
26
26
  gqlType dir_list;
27
-
27
+
28
28
  if (NULL == (type = gql_type_create(err, "__Schema", NULL, 0, NULL)) ||
29
29
 
30
30
  NULL == (type_type = gql_assure_type(err, "__Type")) ||
31
31
  NULL == (type_list = gql_assure_list(err, type_type, true)) ||
32
32
  NULL == (dir_type = gql_assure_type(err, "__Directive")) ||
33
33
  NULL == (dir_list = gql_assure_list(err, dir_type, true)) ||
34
-
34
+
35
35
  NULL == gql_type_field(err, type, "types", type_list, NULL, NULL, 0, true) ||
36
36
  NULL == gql_type_field(err, type, "queryType", type_type, NULL, NULL, 0, true) ||
37
37
  NULL == gql_type_field(err, type, "mutationType", type_type, NULL, NULL, 0, false) ||
@@ -41,7 +41,7 @@ create_schema_type(agooErr err) {
41
41
  return err->code;
42
42
  }
43
43
  type->core = true;
44
-
44
+
45
45
  return AGOO_ERR_OK;
46
46
  }
47
47
 
@@ -70,7 +70,7 @@ create_type_type(agooErr err) {
70
70
  gqlType enum_list;
71
71
  gqlType input_type;
72
72
  gqlType input_list;
73
-
73
+
74
74
  if (NULL == (type = gql_type_create(err, "__Type", NULL, 0, NULL)) ||
75
75
 
76
76
  NULL == (type_list = gql_assure_list(err, type, true)) ||
@@ -97,7 +97,7 @@ create_type_type(agooErr err) {
97
97
  type->core = true;
98
98
 
99
99
  if (NULL == (dv = gql_bool_create(err, false)) ||
100
-
100
+
101
101
  NULL == gql_field_arg(err, fields, "includeDeprecated", &gql_bool_type, NULL, 0, dv, false) ||
102
102
  NULL == (dv = gql_bool_create(err, false)) ||
103
103
  NULL == gql_field_arg(err, enum_values, "includeDeprecated", &gql_bool_type, NULL, 0, dv, false)) {
@@ -150,7 +150,7 @@ create_field_type(agooErr err) {
150
150
  gqlType type_type;
151
151
  gqlType input_type;
152
152
  gqlType input_list;
153
-
153
+
154
154
  if (NULL == (type = gql_type_create(err, "__Field", NULL, 0, NULL)) ||
155
155
 
156
156
  NULL == (type_type = gql_assure_type(err, "__Type")) ||
@@ -167,7 +167,7 @@ create_field_type(agooErr err) {
167
167
  return err->code;
168
168
  }
169
169
  type->core = true;
170
-
170
+
171
171
  return AGOO_ERR_OK;
172
172
  }
173
173
 
@@ -194,7 +194,7 @@ create_input_type(agooErr err) {
194
194
  return err->code;
195
195
  }
196
196
  type->core = true;
197
-
197
+
198
198
  return AGOO_ERR_OK;
199
199
  }
200
200
 
@@ -217,7 +217,7 @@ create_enum_type(agooErr err) {
217
217
  return err->code;
218
218
  }
219
219
  type->core = true;
220
-
220
+
221
221
  return AGOO_ERR_OK;
222
222
  }
223
223
 
@@ -234,7 +234,7 @@ create_directive_type(agooErr err) {
234
234
  gqlType input_list;
235
235
  gqlType loc_type;
236
236
  gqlType loc_list;
237
-
237
+
238
238
  if (NULL == (type = gql_type_create(err, "__Directive", NULL, 0, NULL)) ||
239
239
 
240
240
  NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
@@ -250,7 +250,7 @@ create_directive_type(agooErr err) {
250
250
  return err->code;
251
251
  }
252
252
  type->core = true;
253
-
253
+
254
254
  return AGOO_ERR_OK;
255
255
  }
256
256
 
@@ -374,7 +374,7 @@ extract_arg(agooErr err, gqlField field, gqlSel sel, const char *key) {
374
374
  if (NULL != sel->args) {
375
375
  gqlSelArg sa;
376
376
  gqlValue v = NULL;
377
-
377
+
378
378
  for (sa = sel->args; NULL != sa; sa = sa->next) {
379
379
  if (0 != strcmp(sa->name, key)) {
380
380
  continue;
@@ -386,7 +386,7 @@ extract_arg(agooErr err, gqlField field, gqlSel sel, const char *key) {
386
386
  }
387
387
  if (NULL != field) {
388
388
  gqlArg fa;
389
-
389
+
390
390
  for (fa = field->args; NULL != fa; fa = fa->next) {
391
391
  if (0 == strcmp(sa->name, fa->name)) {
392
392
  if (v->type != fa->type && GQL_SCALAR_VAR != v->type->scalar_kind) {
@@ -417,7 +417,7 @@ is_deprecated(gqlDirUse use) {
417
417
  static const char*
418
418
  deprecation_reason(gqlDirUse use) {
419
419
  const char *reason = NULL;
420
-
420
+
421
421
  for (; NULL != use; use = use->next) {
422
422
  if (0 == strcmp("deprecated", use->dir->name)) {
423
423
  gqlLink a;
@@ -470,7 +470,7 @@ input_value_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel se
470
470
  const char *key = sel->name;
471
471
  struct _gqlCobj child = { .clas = &type_class };
472
472
  gqlValue co;
473
-
473
+
474
474
  if (NULL != sel->alias) {
475
475
  key = sel->alias;
476
476
  }
@@ -492,7 +492,7 @@ input_value_default_value(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field,
492
492
  gqlArg a = (gqlArg)obj->ptr;
493
493
  const char *key = sel->name;
494
494
  gqlValue dv = a->default_value;
495
-
495
+
496
496
  if (NULL != sel->alias) {
497
497
  key = sel->alias;
498
498
  }
@@ -593,7 +593,7 @@ field_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gql
593
593
  const char *key = sel->name;
594
594
  struct _gqlCobj child = { .clas = &type_class };
595
595
  gqlValue co;
596
-
596
+
597
597
  if (NULL != sel->alias) {
598
598
  key = sel->alias;
599
599
  }
@@ -688,7 +688,7 @@ enum_value_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gql
688
688
  static int
689
689
  enum_value_is_deprecated(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
690
690
  const char *key = sel->name;
691
-
691
+
692
692
  if (NULL != sel->alias) {
693
693
  key = sel->alias;
694
694
  }
@@ -763,7 +763,7 @@ directive_locations(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
763
763
  gqlStrLink locs = d->locs;
764
764
  gqlValue list = gql_list_create(err, NULL);
765
765
  gqlValue c;
766
-
766
+
767
767
  if (NULL != sel->alias) {
768
768
  key = sel->alias;
769
769
  }
@@ -833,7 +833,7 @@ static int
833
833
  type_kind(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlValue result, int depth) {
834
834
  const char *kind = NULL;
835
835
  const char *key = sel->name;
836
-
836
+
837
837
  switch (((gqlType)obj->ptr)->kind) {
838
838
  case GQL_OBJECT: kind = "OBJECT"; break;
839
839
  case GQL_INPUT: kind = "INPUT_OBJECT"; break;
@@ -868,7 +868,7 @@ type_description(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel se
868
868
  gqlType type = (gqlType)obj->ptr;
869
869
  const char *key = sel->name;
870
870
  gqlValue desc;
871
-
871
+
872
872
  if (NULL != sel->alias) {
873
873
  key = sel->alias;
874
874
  }
@@ -895,7 +895,7 @@ type_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gq
895
895
  gqlValue a = extract_arg(err, field, sel, "includeDeprecated");
896
896
  bool inc_dep = false;
897
897
 
898
- if (GQL_OBJECT != type->kind && GQL_INTERFACE != type->kind) {
898
+ if (GQL_OBJECT != type->kind && GQL_SCHEMA != type->kind && GQL_INTERFACE != type->kind) {
899
899
  if (NULL == (co = gql_null_create(err)) ||
900
900
  AGOO_ERR_OK != gql_list_append(err, list, co)) {
901
901
  return err->code;
@@ -1006,7 +1006,7 @@ possible_cb(gqlType type, void *ctx) {
1006
1006
  }
1007
1007
  if (GQL_LIST != type->kind && has_interface(type, pc->interface)) {
1008
1008
  gqlValue co;
1009
-
1009
+
1010
1010
  if (NULL == (co = gql_object_create(pc->err)) ||
1011
1011
  AGOO_ERR_OK != gql_list_append(pc->err, pc->list, co)) {
1012
1012
  return;
@@ -1049,7 +1049,7 @@ type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
1049
1049
  .child = &child,
1050
1050
  .cf = &cf,
1051
1051
  };
1052
-
1052
+
1053
1053
  gql_type_iterate(possible_cb, &pc);
1054
1054
  break;
1055
1055
  }
@@ -1175,7 +1175,7 @@ type_of_type(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, g
1175
1175
  const char *key = sel->name;
1176
1176
  struct _gqlCobj child = { .clas = &type_class };
1177
1177
  gqlValue co;
1178
-
1178
+
1179
1179
  if (NULL != sel->alias) {
1180
1180
  key = sel->alias;
1181
1181
  }
@@ -1363,7 +1363,7 @@ root_schema(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gq
1363
1363
  struct _gqlCobj child = { .clas = &schema_class, .ptr = NULL };
1364
1364
  gqlValue co;
1365
1365
  const char *key = sel->name;
1366
-
1366
+
1367
1367
  if (NULL != sel->alias) {
1368
1368
  key = sel->alias;
1369
1369
  }
@@ -1418,34 +1418,11 @@ static struct _gqlCclass root_class = {
1418
1418
  .methods = root_methods,
1419
1419
  };
1420
1420
 
1421
- static gqlType
1422
- ref_type(gqlRef ref) {
1423
- gqlCobj obj = (gqlCobj)ref;
1424
-
1425
- if (NULL != obj && NULL != obj->clas) {
1426
- return gql_type_get(obj->clas->name);
1427
- }
1428
- return NULL;
1429
- }
1430
-
1431
- static int
1432
- resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlValue result, int depth) {
1433
- gqlCobj obj = (gqlCobj)target;
1434
- gqlCmethod method;
1435
-
1436
- for (method = obj->clas->methods; NULL != method->key; method++) {
1437
- if (0 == strcmp(method->key, sel->name)) {
1438
- return method->func(err, doc, obj, field, sel, result, depth);
1439
- }
1440
- }
1441
- return agoo_err_set(err, AGOO_ERR_EVAL, "%s is not a field on %s.", sel->name, obj->clas->name);
1442
- }
1443
-
1444
1421
  int
1445
1422
  gql_intro_eval(agooErr err, gqlDoc doc, gqlSel sel, gqlValue result, int depth) {
1446
1423
  struct _gqlField field;
1447
1424
  struct _gqlCobj obj;
1448
-
1425
+
1449
1426
  if (0 == strcmp("__type", sel->name)) {
1450
1427
  if (1 < depth) {
1451
1428
  return agoo_err_set(err, AGOO_ERR_EVAL, "__type can only be called from a query root.");
@@ -1465,9 +1442,8 @@ gql_intro_eval(agooErr err, gqlDoc doc, gqlSel sel, gqlValue result, int depth)
1465
1442
  field.name = sel->name;
1466
1443
  field.type = sel->type;
1467
1444
 
1468
- doc->funcs.resolve = resolve;
1469
- doc->funcs.type = ref_type;
1445
+ doc->funcs.resolve = gql_cobj_resolve;
1446
+ doc->funcs.type = gql_cobj_ref_type;
1470
1447
 
1471
- return resolve(err, doc, &obj, &field, sel, result, depth);
1448
+ return gql_cobj_resolve(err, doc, &obj, &field, sel, result, depth);
1472
1449
  }
1473
-
data/ext/agoo/gqljson.c CHANGED
@@ -38,7 +38,7 @@ parse_num(agooErr err, agooDoc doc) {
38
38
  bool neg = false;
39
39
  char c;
40
40
  const char *start = doc->cur;
41
-
41
+
42
42
  c = *doc->cur;
43
43
  if ('-' == c) {
44
44
  doc->cur++;
@@ -162,35 +162,38 @@ read_hex(agooErr err, agooDoc doc) {
162
162
  static agooText
163
163
  unicode_to_chars(agooErr err, agooText t, uint32_t code, agooDoc doc) {
164
164
  if (0x0000007F >= code) {
165
- agoo_text_append_char(t, (char)code);
165
+ t = agoo_text_append_char(t, (char)code);
166
166
  } else if (0x000007FF >= code) {
167
- agoo_text_append_char(t, 0xC0 | (code >> 6));
168
- agoo_text_append_char(t, 0x80 | (0x3F & code));
167
+ t = agoo_text_append_char(t, 0xC0 | (code >> 6));
168
+ t = agoo_text_append_char(t, 0x80 | (0x3F & code));
169
169
  } else if (0x0000FFFF >= code) {
170
- agoo_text_append_char(t, 0xE0 | (code >> 12));
171
- agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
172
- agoo_text_append_char(t, 0x80 | (0x3F & code));
170
+ t = agoo_text_append_char(t, 0xE0 | (code >> 12));
171
+ t = agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
172
+ t = agoo_text_append_char(t, 0x80 | (0x3F & code));
173
173
  } else if (0x001FFFFF >= code) {
174
- agoo_text_append_char(t, 0xF0 | (code >> 18));
175
- agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
176
- agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
177
- agoo_text_append_char(t, 0x80 | (0x3F & code));
174
+ t = agoo_text_append_char(t, 0xF0 | (code >> 18));
175
+ t = agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
176
+ t = agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
177
+ t = agoo_text_append_char(t, 0x80 | (0x3F & code));
178
178
  } else if (0x03FFFFFF >= code) {
179
- agoo_text_append_char(t, 0xF8 | (code >> 24));
180
- agoo_text_append_char(t, 0x80 | ((code >> 18) & 0x3F));
181
- agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
182
- agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
183
- agoo_text_append_char(t, 0x80 | (0x3F & code));
179
+ t = agoo_text_append_char(t, 0xF8 | (code >> 24));
180
+ t = agoo_text_append_char(t, 0x80 | ((code >> 18) & 0x3F));
181
+ t = agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
182
+ t = agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
183
+ t = agoo_text_append_char(t, 0x80 | (0x3F & code));
184
184
  } else if (0x7FFFFFFF >= code) {
185
- agoo_text_append_char(t, 0xFC | (code >> 30));
186
- agoo_text_append_char(t, 0x80 | ((code >> 24) & 0x3F));
187
- agoo_text_append_char(t, 0x80 | ((code >> 18) & 0x3F));
188
- agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
189
- agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
190
- agoo_text_append_char(t, 0x80 | (0x3F & code));
185
+ t = agoo_text_append_char(t, 0xFC | (code >> 30));
186
+ t = agoo_text_append_char(t, 0x80 | ((code >> 24) & 0x3F));
187
+ t = agoo_text_append_char(t, 0x80 | ((code >> 18) & 0x3F));
188
+ t = agoo_text_append_char(t, 0x80 | ((code >> 12) & 0x3F));
189
+ t = agoo_text_append_char(t, 0x80 | ((code >> 6) & 0x3F));
190
+ t = agoo_text_append_char(t, 0x80 | (0x3F & code));
191
191
  } else {
192
192
  agoo_doc_err(doc, err, "invalid unicode character");
193
193
  }
194
+ if (NULL == t) {
195
+ AGOO_ERR_MEM(err, "text");
196
+ }
194
197
  return t;
195
198
  }
196
199
 
@@ -236,7 +239,7 @@ parse_escaped(agooErr err, agooDoc doc) {
236
239
  c2 = (c2 - 0x0000DC00) & 0x000003FF;
237
240
  code = ((c1 << 10) | c2) + 0x00010000;
238
241
  }
239
- unicode_to_chars(err, t, code, doc);
242
+ t = unicode_to_chars(err, t, code, doc);
240
243
  if (AGOO_ERR_OK != err->code) {
241
244
  goto DONE;
242
245
  }
@@ -248,15 +251,16 @@ parse_escaped(agooErr err, agooDoc doc) {
248
251
  agoo_text_release(t);
249
252
  return NULL;
250
253
  }
251
- } else {
252
- t = agoo_text_append(t, doc->cur, 1);
254
+ } else if (NULL == (t = agoo_text_append(t, doc->cur, 1))) {
255
+ AGOO_ERR_MEM(err, "text");
256
+ return NULL;
253
257
  }
254
258
  }
255
259
  value = gql_string_create(err, t->text, t->len);
256
260
  doc->cur++; // past trailing "
257
261
  DONE:
258
262
  agoo_text_release(t);
259
-
263
+
260
264
  return value;
261
265
  }
262
266
 
@@ -277,7 +281,7 @@ parse_string(agooErr err, agooDoc doc) {
277
281
  }
278
282
  }
279
283
  doc->cur++;
280
-
284
+
281
285
  return gql_string_create(err, start, (int)(doc->cur - start - 1));
282
286
  }
283
287
 
@@ -288,14 +292,14 @@ return_parse_err(agooErr err, agooDoc doc, const char *msg, gqlValue value) {
288
292
 
289
293
  return NULL;
290
294
  }
291
-
295
+
292
296
  static gqlValue
293
297
  parse_object(agooErr err, agooDoc doc) {
294
298
  char key[256];
295
299
  gqlValue value = gql_object_create(err);
296
300
  gqlValue member;
297
301
  const char *start;
298
-
302
+
299
303
  if (NULL == value) {
300
304
  return NULL;
301
305
  }
@@ -353,7 +357,7 @@ static gqlValue
353
357
  parse_array(agooErr err, agooDoc doc) {
354
358
  gqlValue value = gql_list_create(err, NULL);
355
359
  gqlValue member;
356
-
360
+
357
361
  if (NULL == value) {
358
362
  return NULL;
359
363
  }
@@ -390,7 +394,7 @@ parse_array(agooErr err, agooDoc doc) {
390
394
  static gqlValue
391
395
  parse_value(agooErr err, agooDoc doc) {
392
396
  gqlValue value = NULL;
393
-
397
+
394
398
  agoo_doc_skip_jwhite(doc);
395
399
  switch (*doc->cur) {
396
400
  case '{':
@@ -453,7 +457,7 @@ parse_value(agooErr err, agooDoc doc) {
453
457
  gqlValue
454
458
  gql_json_parse(agooErr err, const char *json, size_t len) {
455
459
  struct _agooDoc doc;
456
-
460
+
457
461
  agoo_doc_init(&doc, json, len);
458
462
 
459
463
  return parse_value(err, &doc);