@@ -117,7 +117,7 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
117
117
}
118
118
else
119
119
{
120
- // Skip invalid characters
120
+ // Skip leading characters
121
121
str ++ ;
122
122
continue ;
123
123
}
@@ -132,59 +132,119 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
132
132
case '\t' : // Ignore tab character
133
133
case '\n' : // Ignore newline character
134
134
break ;
135
- case '{' :
136
- // Start dictionary
135
+ case '{' :;
136
+ // Start dictionary, allocate generic dictionary object
137
+ cJSON_Generic_t dictObj ;
138
+ dictObj = mallocGenObj (Dictionary );
139
+
140
+ // Check if start dictionary is possible
141
+ if (pFlags & CJP_DICT_VALUE_POSSIBLE )
142
+ {
143
+ cJSON_appendToDict (AS_DICT_PTR (GS_TOP (ObjectStack )), activeKey , dictObj );
144
+ }
145
+ else if (pFlags & CJP_LIST_VALUE_POSSIBLE )
146
+ {
147
+ cJSON_appendToList (AS_LIST_PTR (GS_TOP (ObjectStack )), dictObj );
148
+ }
149
+ else
150
+ {
151
+ // Dictionary at invalid location in structure, delete object stack, delete generic dictionary object and return error
152
+ GS_Delete (& ObjectStack );
153
+ cJSON_delGenObj (dictObj );
154
+ return cJSON_Structure_Error ;
155
+ }
156
+
157
+ // Push dictionary object to stack, check if JSON structure is within depth range
158
+ if (GS_Push (& ObjectStack , dictObj ) != GS_Ok )
159
+ {
160
+ // String's JSON structure depth is out of range, delete object stack and return error
161
+ GS_Delete (& ObjectStack );
162
+ return cJSON_DepthOutOfRange_Error ;
163
+ }
164
+
165
+ // Update flags
166
+ pFlags = CJP_DICT_END_POSSIBLE | CJP_DICT_KEY_POSSIBLE ;
137
167
break ;
138
168
case '}' :
139
169
// Check if end dictionary is possible
140
170
if (pFlags & CJP_DICT_END_POSSIBLE )
141
171
{
142
- // End dictionary
172
+ // End dictionary, remove generic dictionary object from stack
143
173
GS_Pop (& ObjectStack );
144
174
145
175
if (GS_IS_EMPTY (ObjectStack ))
146
176
{
147
177
// Clear parser flags, stack is empty, parsing complete, wait for string terminator
148
178
pFlags = 0 ;
149
179
}
180
+ else if (GS_TOP (ObjectStack ).type == Dictionary )
181
+ {
182
+ pFlags = CJP_DICT_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
183
+ }
150
184
else
151
185
{
152
- if (GS_TOP (ObjectStack ).type == Dictionary )
153
- {
154
- pFlags = CJP_DICT_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
155
- }
156
- else
157
- {
158
- pFlags = CJP_LIST_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
159
- }
186
+ pFlags = CJP_LIST_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
160
187
}
161
188
}
189
+ else
190
+ {
191
+ // Dictionary end at invalid location, delete object stack and return error
192
+ GS_Delete (& ObjectStack );
193
+ return cJSON_Structure_Error ;
194
+ }
162
195
break ;
163
- case '[' :
164
- // Start list
196
+ case '[' :;
197
+ // Start list, allocate generic list object
198
+ cJSON_Generic_t listObj ;
199
+ listObj = mallocGenObj (List );
200
+
201
+ // Check if start list is possible
202
+ if (pFlags & CJP_DICT_VALUE_POSSIBLE )
203
+ {
204
+ cJSON_appendToDict (AS_DICT_PTR (GS_TOP (ObjectStack )), activeKey , listObj );
205
+ }
206
+ else if (pFlags & CJP_LIST_VALUE_POSSIBLE )
207
+ {
208
+ cJSON_appendToList (AS_LIST_PTR (GS_TOP (ObjectStack )), listObj );
209
+ }
210
+ else
211
+ {
212
+ // List at invalid location in structure, delete object stack, delete generic list object and return error
213
+ GS_Delete (& ObjectStack );
214
+ cJSON_delGenObj (listObj );
215
+ return cJSON_Structure_Error ;
216
+ }
217
+
218
+ // Push list object to stack, check if JSON structure is within depth range
219
+ if (GS_Push (& ObjectStack , listObj ) != GS_Ok )
220
+ {
221
+ // JSON structure depth is out of range, delete object stack and return error
222
+ GS_Delete (& ObjectStack );
223
+ return cJSON_DepthOutOfRange_Error ;
224
+ }
225
+
226
+ // Update flags
227
+ pFlags = CJP_DICT_END_POSSIBLE | CJP_DICT_KEY_POSSIBLE ;
165
228
break ;
166
229
case ']' :
167
230
// Check if end list is possible
168
231
if (pFlags & CJP_DICT_END_POSSIBLE )
169
232
{
170
- // End list
233
+ // End list, remove generic list object from stack
171
234
GS_Pop (& ObjectStack );
172
235
173
236
if (GS_IS_EMPTY (ObjectStack ))
174
237
{
175
238
// Clear parser flags, stack is empty, parsing complete, wait for string terminator
176
239
pFlags = 0 ;
177
240
}
241
+ else if (GS_TOP (ObjectStack ).type == Dictionary )
242
+ {
243
+ pFlags = CJP_DICT_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
244
+ }
178
245
else
179
246
{
180
- if (GS_TOP (ObjectStack ).type == Dictionary )
181
- {
182
- pFlags = CJP_DICT_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
183
- }
184
- else
185
- {
186
- pFlags = CJP_LIST_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
187
- }
247
+ pFlags = CJP_LIST_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
188
248
}
189
249
}
190
250
break ;
@@ -200,7 +260,8 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
200
260
}
201
261
else
202
262
{
203
- // Item separator at illegal location detected
263
+ // Item separator at invalid location detected, delete object stack and return error
264
+ GS_Delete (& ObjectStack );
204
265
return cJSON_Structure_Error ;
205
266
}
206
267
break ;
@@ -213,7 +274,8 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
213
274
}
214
275
else
215
276
{
216
- // Dictionary key-value separator at illegal location detected
277
+ // Dictionary key-value separator at invalid location detected, delete object stack and return error
278
+ GS_Delete (& ObjectStack );
217
279
return cJSON_Structure_Error ;
218
280
}
219
281
break ;
@@ -252,12 +314,18 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
252
314
}
253
315
else
254
316
{
317
+ // String at invalid location detected, delete object stack and return error
318
+ GS_Delete (& ObjectStack );
255
319
return cJSON_Structure_Error ;
256
320
}
257
321
258
322
// Check if StringBuilder was successful
259
323
if (strBuilderResult != cJSON_Ok )
324
+ {
325
+ // StringBuilder exited unsuccessfully, delete object stack and return error
326
+ GS_Delete (& ObjectStack );
260
327
return strBuilderResult ;
328
+ }
261
329
break ;
262
330
case '-' :
263
331
case '0' :
@@ -286,13 +354,67 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
286
354
}
287
355
else
288
356
{
289
- // Number at invalid location in structure
357
+ // Number at invalid location in structure, delete object stack and return error
358
+ GS_Delete (& ObjectStack );
290
359
return cJSON_Structure_Error ;
291
360
}
292
361
break ;
293
- case 't' :
294
- case 'f' :
362
+ case 't' :;
363
+ case 'f' :;
295
364
// Check if boolean is possible
365
+ bool boolVal ;
366
+ cJSON_Generic_t boolObj ;
367
+
368
+ if ((LOWER_CASE_CHAR (* str ) == 't' )
369
+ && (LOWER_CASE_CHAR (* (str + 1 )) == 'r' )
370
+ && (LOWER_CASE_CHAR (* (str + 2 )) == 'u' )
371
+ && (LOWER_CASE_CHAR (* (str + 3 )) == 'e' ))
372
+ {
373
+ // Bool value is "true", skip "true" character sequence, store result
374
+ str += 3 ;
375
+ boolVal = true;
376
+ }
377
+ else if ((LOWER_CASE_CHAR (* str ) == 'f' )
378
+ && (LOWER_CASE_CHAR (* (str + 1 )) == 'a' )
379
+ && (LOWER_CASE_CHAR (* (str + 2 )) == 'l' )
380
+ && (LOWER_CASE_CHAR (* (str + 3 )) == 's' )
381
+ && (LOWER_CASE_CHAR (* (str + 4 )) == 'e' ))
382
+ {
383
+ // Bool value is "false", skip "false" character sequence, store result
384
+ str += 4 ;
385
+ boolVal = false;
386
+ }
387
+ else
388
+ {
389
+ // Invalid character sequence, delete object stack and return error
390
+ GS_Delete (& ObjectStack );
391
+ return cJSON_InvalidCharacterSequence_Error ;
392
+ }
393
+
394
+ // Create generic object from boolean
395
+ boolObj = mallocGenObj (Boolean );
396
+ AS_BOOL (boolObj ) = boolVal ;
397
+
398
+ // Valid character sequence
399
+ if (pFlags & CJP_DICT_VALUE_POSSIBLE )
400
+ {
401
+ cJSON_appendToDict (AS_DICT_PTR (GS_TOP (ObjectStack )), activeKey , boolObj );
402
+
403
+ pFlags = CJP_DICT_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
404
+ }
405
+ else if (pFlags & CJP_LIST_VALUE_POSSIBLE )
406
+ {
407
+ cJSON_appendToList (AS_LIST_PTR (GS_TOP (ObjectStack )), boolObj );
408
+
409
+ pFlags = CJP_LIST_END_POSSIBLE | CJP_ITEM_SEPT_POSSIBLE ;
410
+ }
411
+ else
412
+ {
413
+ // Boolean at invalid location in structure, delete object stack, delete generic bool object and return error
414
+ GS_Delete (& ObjectStack );
415
+ cJSON_delGenObj (boolObj );
416
+ return cJSON_Structure_Error ;
417
+ }
296
418
break ;
297
419
case 'n' :
298
420
// Extract null, check if whole string matches
@@ -317,18 +439,21 @@ cJSON_Result_t cJSON_parseStr(cJSON_Generic_t *GObjPtr, const char *str)
317
439
}
318
440
else
319
441
{
320
- // Null at invalid location in structure
442
+ // Null at invalid location in structure, delete object stack and return error
443
+ GS_Delete (& ObjectStack );
321
444
return cJSON_Structure_Error ;
322
445
}
323
446
}
324
447
else
325
448
{
326
- // Invalid character sequence
449
+ // Invalid character sequence, delete object stack and return error
450
+ GS_Delete (& ObjectStack );
327
451
return cJSON_InvalidCharacterSequence_Error ;
328
452
}
329
453
break ;
330
454
default :
331
- // Unknown structural character
455
+ // Unknown character at current location detected, delete object stack and return error
456
+ GS_Delete (& ObjectStack );
332
457
return cJSON_Structure_Error ;
333
458
}
334
459
}
0 commit comments