Skip to content

Build failure with gcc and -fanalyzer #542

@JCWasmx86

Description

@JCWasmx86

I ran gcc with the -fanalyzer argument to look for further issues and it gave me this warning:

cJSON_Utils.c: In function ‘apply_patch’:
cJSON_Utils.c:963:37: error: use of NULL ‘parent_pointer’ where non-null expected [CWE-690] [-Werror=analyzer-null-argument]
  963 |     child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/');
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ‘cJSONUtils_ApplyPatches’: events 1-8
    |
    | 1036 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches)
    |      |                   ^~~~~~~~~~~~~~~~~~~~~~~
    |      |                   |
    |      |                   (1) entry to ‘cJSONUtils_ApplyPatches’
    |......
    | 1041 |     if (!cJSON_IsArray(patches))
    |      |        ~           
    |      |        |
    |      |        (2) following ‘false’ branch...
    |......
    | 1047 |     if (patches != NULL)
    |      |        ~           
    |      |        |
    |      |        (3) ...to here
    |      |        (4) following ‘true’ branch (when ‘patches’ is non-NULL)...
    | 1048 |     {
    | 1049 |         current_patch = patches->child;
    |      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                       |
    |      |                       (5) ...to here
    |......
    | 1052 |     while (current_patch != NULL)
    |      |           ~        
    |      |           |
    |      |           (6) following ‘true’ branch (when ‘current_patch’ is non-NULL)...
    | 1053 |     {
    | 1054 |         status = apply_patch(object, current_patch, false);
    |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                  |
    |      |                  (7) ...to here
    |      |                  (8) calling ‘apply_patch’ from ‘cJSONUtils_ApplyPatches’
    |
    +--> ‘apply_patch’: events 9-10
           |
           |  807 | static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_sensitive)
           |      |            ^~~~~~~~~~~
           |      |            |
           |      |            (9) entry to ‘apply_patch’
           |......
           |  817 |     path = get_object_item(patch, "path", case_sensitive);
           |      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |            |
           |      |            (10) calling ‘get_object_item’ from ‘apply_patch’
           |
           +--> ‘get_object_item’: events 11-13
                  |
                  |  730 | static cJSON *get_object_item(const cJSON * const object, const char* name, const cJSON_bool case_sensitive)
                  |      |               ^~~~~~~~~~~~~~~
                  |      |               |
                  |      |               (11) entry to ‘get_object_item’
                  |  731 | {
                  |  732 |     if (case_sensitive)
                  |      |        ~       
                  |      |        |
                  |      |        (12) following ‘false’ branch (when ‘case_sensitive == 0’)...
                  |......
                  |  737 |     return cJSON_GetObjectItem(object, name);
                  |      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |            |
                  |      |            (13) ...to here
                  |
           <------+
           |
         ‘apply_patch’: events 14-17
           |
           |  817 |     path = get_object_item(patch, "path", case_sensitive);
           |      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |            |
           |      |            (14) returning to ‘apply_patch’ from ‘get_object_item’
           |  818 |     if (!cJSON_IsString(path))
           |      |        ~    
           |      |        |
           |      |        (15) following ‘false’ branch...
           |......
           |  825 |     opcode = decode_patch_operation(patch, case_sensitive);
           |      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |              |
           |      |              (16) ...to here
           |      |              (17) calling ‘decode_patch_operation’ from ‘apply_patch’
           |
           +--> ‘decode_patch_operation’: events 18-19
                  |
                  |  742 | static enum patch_operation decode_patch_operation(const cJSON * const patch, const cJSON_bool case_sensitive)
                  |      |                             ^~~~~~~~~~~~~~~~~~~~~~
                  |      |                             |
                  |      |                             (18) entry to ‘decode_patch_operation’
                  |  743 | {
                  |  744 |     cJSON *operation = get_object_item(patch, "op", case_sensitive);
                  |      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |                        |
                  |      |                        (19) calling ‘get_object_item’ from ‘decode_patch_operation’
                  |
                  +--> ‘get_object_item’: events 20-22
                         |
                         |  730 | static cJSON *get_object_item(const cJSON * const object, const char* name, const cJSON_bool case_sensitive)
                         |      |               ^~~~~~~~~~~~~~~
                         |      |               |
                         |      |               (20) entry to ‘get_object_item’
                         |  731 | {
                         |  732 |     if (case_sensitive)
                         |      |        ~       
                         |      |        |
                         |      |        (21) following ‘false’ branch (when ‘case_sensitive == 0’)...
                         |......
                         |  737 |     return cJSON_GetObjectItem(object, name);
                         |      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                         |      |            |
                         |      |            (22) ...to here
                         |
                  <------+
                  |
                ‘decode_patch_operation’: event 23
                  |
                  |  744 |     cJSON *operation = get_object_item(patch, "op", case_sensitive);
                  |      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |                        |
                  |      |                        (23) returning to ‘decode_patch_operation’ from ‘get_object_item’
                  |
           <------+
           |
         ‘apply_patch’: events 24-35
           |
           |  825 |     opcode = decode_patch_operation(patch, case_sensitive);
           |      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |              |
           |      |              (24) returning to ‘apply_patch’ from ‘decode_patch_operation’
           |......
           |  831 |     else if (opcode == TEST)
           |      |             ~ 
           |      |             |
           |      |             (25) following ‘false’ branch (when ‘opcode != 6’)...
           |......
           |  839 |     if (path->valuestring[0] == '\0')
           |      |         ~~~~~~~~~~~~~~~~~
           |      |             |
           |      |             (26) ...to here
           |......
           |  887 |     if ((opcode == REMOVE) || (opcode == REPLACE))
           |      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |        |                   |
           |      |        |                   (28) ...to here
           |      |        |                   (29) following ‘false’ branch (when ‘opcode != 3’)...
           |      |        (27) following ‘false’ branch (when ‘opcode != 2’)...
           |......
           |  906 |     if ((opcode == MOVE) || (opcode == COPY))
           |      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |        |                 |
           |      |        |                 (32) ...to here
           |      |        |                 (33) following ‘false’ branch (when ‘opcode != 5’)...
           |      |        (30) ...to here
           |      |        (31) following ‘false’ branch (when ‘opcode != 4’)...
           |......
           |  943 |         value = get_object_item(patch, "value", case_sensitive);
           |      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                 |
           |      |                 (34) ...to here
           |      |                 (35) calling ‘get_object_item’ from ‘apply_patch’
           |
           +--> ‘get_object_item’: events 36-38
                  |
                  |  730 | static cJSON *get_object_item(const cJSON * const object, const char* name, const cJSON_bool case_sensitive)
                  |      |               ^~~~~~~~~~~~~~~
                  |      |               |
                  |      |               (36) entry to ‘get_object_item’
                  |  731 | {
                  |  732 |     if (case_sensitive)
                  |      |        ~       
                  |      |        |
                  |      |        (37) following ‘false’ branch (when ‘case_sensitive == 0’)...
                  |......
                  |  737 |     return cJSON_GetObjectItem(object, name);
                  |      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |            |
                  |      |            (38) ...to here
                  |
           <------+
           |
         ‘apply_patch’: events 39-44
           |
           |  943 |         value = get_object_item(patch, "value", case_sensitive);
           |      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                 |
           |      |                 (39) returning to ‘apply_patch’ from ‘get_object_item’
           |  944 |         if (value == NULL)
           |      |            ~     
           |      |            |
           |      |            (40) following ‘false’ branch (when ‘value’ is non-NULL)...
           |......
           |  950 |         value = cJSON_Duplicate(value, 1);
           |      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                 |
           |      |                 (41) ...to here
           |  951 |         if (value == NULL)
           |      |            ~     
           |      |            |
           |      |            (42) following ‘false’ branch (when ‘value’ is non-NULL)...
           |......
           |  962 |     parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring);
           |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                      |                                     |
           |      |                      |                                     (43) ...to here
           |      |                      (44) calling ‘cJSONUtils_strdup’ from ‘apply_patch’
           |
           +--> ‘cJSONUtils_strdup’: events 45-46
                  |
                  |   66 | static unsigned char* cJSONUtils_strdup(const unsigned char* const string)
                  |      |                       ^~~~~~~~~~~~~~~~~
                  |      |                       |
                  |      |                       (45) entry to ‘cJSONUtils_strdup’
                  |......
                  |   73 |     if (copy == NULL)
                  |      |        ~               
                  |      |        |
                  |      |        (46) following ‘true’ branch (when ‘copy’ is NULL)...
                  |
                ‘cJSONUtils_strdup’: event 47
                  |
                  |   75 |         return NULL;
                  |      |                ^~~~
                  |      |                |
                  |      |                (47) ...to here
                  |
                ‘cJSONUtils_strdup’: event 48
                  |
                  |cc1:
                  | (48): ‘<return-value>’ is NULL
                  |
           <------+
           |
         ‘apply_patch’: events 49-50
           |
           |  962 |     parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring);
           |      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                      |
           |      |                      (49) returning to ‘apply_patch’ from ‘cJSONUtils_strdup’
           |  963 |     child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/');
           |      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |                                     |
           |      |                                     (50) argument 1 (‘parent_pointer’) NULL where non-null expected
           |
In file included from cJSON_Utils.c:38:
/usr/include/string.h:253:14: note: argument 1 of ‘strrchr’ must be non-null
  253 | extern char *strrchr (const char *__s, int __c)
      |              ^~~~~~~
cc1: all warnings being treated as errors

I wasn't able to find a json file that can really reproduce the issue.

(Debian Sid, gcc 10)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions