Skip to content

frogfs fails to build with CONFIG_COMPILER_STATIC_ANALYZER=y #77

@hyrsky

Description

@hyrsky

Enabling CONFIG_COMPILER_STATIC_ANALYZER=y in an ESP-IDF project that depends on jkent/frogfs makes the build fail.

Reproduce

In any ESP-IDF v6 project that depends on jkent/frogfs:

  1. idf.py menuconfig: Compiler options --> Enable compiler static analyzer.
  2. idf.py build.
In file included from /var/home/user/test/components/jkent__frogfs/src/decomp_miniz.c:15:
/var/home/user/test/components/jkent__frogfs/src/decomp_miniz.c: In function 'open_miniz':
/var/home/user/test/components/jkent__frogfs/src/log.h:51:63: error: leak of 'priv' [CWE-401] [-Werror=analyzer-malloc-leak]
   51 | # define LOGE( format, ... )  if (LOG_LEVEL >= LOG_ERROR)   { fprintf(stderr, LOG_FORMAT(E, format), __func__, ##__VA_ARGS__); }
      |                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/var/home/user/test/components/jkent__frogfs/src/decomp_miniz.c:48:13: note: in expansion of macro 'LOGE'
   48 |             LOGE("unsupported gzip compression method");
      |             ^~~~
  'open_miniz': events 1-6
   33 |     priv_data_t *priv = malloc(sizeof(priv_data_t));
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                         |
      |                         (1) allocated here
   34 |     if (priv == NULL) {
      |        ~                 
      |        |
      |        (2) assuming 'priv' is non-NULL
      |        (3) following 'false' branch (when 'priv' is non-NULL)... ─>─┐
      |                                                                     │
......
      |                                                                     │
      |┌────────────────────────────────────────────────────────────────────┘
   39 |│    const char *p = f->data_start;
      |│                ~        
      |│                |
      |└───────────────>(4) ...to here
......
   45 |     } else if (*p == 0x1f && *(p + 1) == 0x8b) {
      |               ~          
      |               |
      |               (5) following 'true' branch... ─>─┐
      |                                                 │
      |                                                 │
      |┌────────────────────────────────────────────────┘
   46 |│        /* gzip */
   47 |│        if (*(p + 2) != 8) {
      |│            ~~~~~~~~     
      |│            |
      |└───────────>(6) ...to here
  'open_miniz': event 7
   47 |         if (*(p + 2) != 8) {
      |            ^
      |            |
      |            (7) following 'true' branch... ─>─┐
      |                                              │
  'open_miniz': event 8
/var/home/user/test/components/jkent__frogfs/src/log.h:51:63:
      |                                              │
      |┌─────────────────────────────────────────────┘
   51 |│# define LOGE( format, ... )  if (LOG_LEVEL >= LOG_ERROR)   { fprintf(stderr, LOG_FORMAT(E, format), __func__, ##__VA_ARGS__); }
      |│                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |│                                                              |
      |└─────────────────────────────────────────────────────────────>(8) ...to here
/var/home/user/test/components/jkent__frogfs/src/decomp_miniz.c:48:13: note: in expansion of macro 'LOGE'
   48 |             LOGE("unsupported gzip compression method");
      |             ^~~~
  'open_miniz': event 9
/var/home/user/test/components/jkent__frogfs/src/log.h:51:63:
   51 | # define LOGE( format, ... )  if (LOG_LEVEL >= LOG_ERROR)   { fprintf(stderr, LOG_FORMAT(E, format), __func__, ##__VA_ARGS__); }
      |                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                               |
      |                                                               (9) ⚠️  'priv' leaks here; was allocated at (1)
/var/home/user/test/components/jkent__frogfs/src/decomp_miniz.c:48:13: note: in expansion of macro 'LOGE'
   48 |             LOGE("unsupported gzip compression method");
      |             ^~~~
/var/home/user/test/components/jkent__frogfs/src/vfs.c: In function 'frogfs_vfs_opendir':
/var/home/user/test/components/jkent__frogfs/src/vfs.c:192:8: error: leak of 'dh' [CWE-401] [-Werror=analyzer-malloc-leak]
  192 |     if (entry == NULL) {
      |        ^
  'frogfs_vfs_opendir': events 1-2
  189 |     frogfs_vfs_dh_t *dh = malloc(sizeof(*dh));
      |                           ^~~~~~~~~~~~~~~~~~~
      |                           |
      |                           (1) allocated here
......
  192 |     if (entry == NULL) {
      |        ~                   
      |        |
      |        (2) following 'true' branch (when 'entry' is NULL)... ─>─┐
      |                                                                 │
  'frogfs_vfs_opendir': event 3
cc1:
 (3): ...to here
  'frogfs_vfs_opendir': event 4
  192 |     if (entry == NULL) {
      |        ^
      |        |
      |        (4) ⚠️  'dh' leaks here; was allocated at (1)
/var/home/user/test/components/jkent__frogfs/src/vfs.c:196:12: error: dereference of possibly-NULL 'dh' [CWE-690] [-Werror=analyzer-possible-null-dereference]
  196 |     dh->dh = frogfs_opendir(vfs->fs, entry);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  'frogfs_vfs_opendir': events 1-3
  189 |     frogfs_vfs_dh_t *dh = malloc(sizeof(*dh));
      |                           ^~~~~~~~~~~~~~~~~~~
      |                           |
      |                           (1) this call could return NULL
......
  192 |     if (entry == NULL) {
      |        ~                   
      |        |
      |        (2) following 'false' branch (when 'entry' is non-NULL)... ─>─┐
      |                                                                      │
......
      |                                                                      │
      |┌─────────────────────────────────────────────────────────────────────┘
  196 |│    dh->dh = frogfs_opendir(vfs->fs, entry);
      |│             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |│             |
      |└────────────>(3) ...to here
  'frogfs_vfs_opendir': event 4
  196 |     dh->dh = frogfs_opendir(vfs->fs, entry);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |            |
      |            (4) ⚠️  'dh' could be NULL: unchecked value from (1)
/var/home/user/test/components/jkent__frogfs/src/frogfs.c: In function 'frogfs_get_entry':
/var/home/user/test/components/jkent__frogfs/src/frogfs.c:194:13: error: use of NULL 'match' where non-null expected [CWE-476] [-Werror=analyzer-null-argument]
  194 |         if (strcmp(path, match) == 0) {
      |             ^~~~~~~~~~~~~~~~~~~
  'frogfs_get_entry': event 1
    │
    │  145 | const frogfs_entry_t *frogfs_get_entry(const frogfs_fs_t *fs, const char *path)
    │      |                       ^~~~~~~~~~~~~~~~
    │      |                       |
    │      |                       (1) entry to 'frogfs_get_entry'
    │
  'frogfs_get_entry': event 2
    │
    │/var/home/user/Documents/esp-idf/components/esp_libc/platform_include/assert.h:45:61:
    │   45 | #define assert(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func (__FILENAME__, __LINE__, \
    │      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │      |                                                             |
    │      |                                                             (2) following 'false' branch... ─>─┐
    │      |                                                                                                │
    │      |                                                                                                │
    │      |┌───────────────────────────────────────────────────────────────────────────────────────────────┘
    │   46 |│                                                                             __ASSERT_FUNC, #__e))
    │      |│                                                                             ~~~~~~~~~~~~~~~~~~~~~
/var/home/user/test/components/jkent__frogfs/src/frogfs.c:147:5: note: in expansion of macro 'assert'
    │  147 |     assert(fs != NULL);
    │      |     ^~~~~~
    │
  'frogfs_get_entry': event 3
    │
    │/var/home/user/Documents/esp-idf/components/esp_libc/platform_include/assert.h:45:22:
    │   45 | #define assert(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func (__FILENAME__, __LINE__, \
    │      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │      |                      |
    │      |└────────────────────>(3) ...to here
/var/home/user/test/components/jkent__frogfs/src/frogfs.c:148:5: note: in expansion of macro 'assert'
    │  148 |     assert(path != NULL);
    │      |     ^~~~~~
    │
  'frogfs_get_entry': event 4
    │
    │/var/home/user/Documents/esp-idf/components/esp_libc/platform_include/assert.h:45:61:
    │   45 | #define assert(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func (__FILENAME__, __LINE__, \
    │      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │      |                                                             |
    │      |                                                             (4) following 'false' branch... ─>─┐
    │      |                                                                                                │
    │      |                                                                                                │
    │      |┌───────────────────────────────────────────────────────────────────────────────────────────────┘
    │   46 |│                                                                             __ASSERT_FUNC, #__e))
    │      |│                                                                             ~~~~~~~~~~~~~~~~~~~~~
/var/home/user/test/components/jkent__frogfs/src/frogfs.c:148:5: note: in expansion of macro 'assert'
    │  148 |     assert(path != NULL);
    │      |     ^~~~~~
    │
  'frogfs_get_entry': event 5
    │
    │cc1:
    │ (5): ...to here
    │
  'frogfs_get_entry': events 6-8
    │
    │  163 |     while (first <= last) {
    │      |            ~~~~~~^~~~~~~
    │      |                  |
    │      |                  (6) following 'true' branch (when 'last >= first')... ─>─┐
    │      |                                                                           │
    │      |                                                                           │
    │      |┌──────────────────────────────────────────────────────────────────────────┘
    │  164 |│        middle = first + (last - first) / 2;
    │      |│                         ~~~~~~~~~~~~~~
    │      |│                               |
    │      |└──────────────────────────────>(7) ...to here
    │......
    │  175 |     if (first > last) {
    │      |        ~          
    │      |        |
    │      |        (8) following 'false' branch (when 'last >= first')... ─>─┐
    │      |                                                                  │
    │
  'frogfs_get_entry': event 9
    │
    │cc1:
    │ (9): ...to here
    │
  'frogfs_get_entry': event 10
    │
    │  193 |         char *match = frogfs_get_path(fs, entry);
    │      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
    │      |                       |
    │      |                       (10) calling 'frogfs_get_path' from 'frogfs_get_entry'
    │
    └──> 'frogfs_get_path': event 11
           │
           │  216 | char *frogfs_get_path(const frogfs_fs_t *fs, const frogfs_entry_t *entry)
           │      |       ^~~~~~~~~~~~~~~
           │      |       |
           │      |       (11) entry to 'frogfs_get_path'
           │
         'frogfs_get_path': event 12
           │
           │/var/home/user/Documents/esp-idf/components/esp_libc/platform_include/assert.h:45:61:
           │   45 | #define assert(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func (__FILENAME__, __LINE__, \
           │      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           │      |                                                             |
           │      |                                                             (12) following 'false' branch... ─>─┐
           │      |                                                                                                 │
           │      |                                                                                                 │
           │      |┌────────────────────────────────────────────────────────────────────────────────────────────────┘
           │   46 |│                                                                             __ASSERT_FUNC, #__e))
           │      |│                                                                             ~~~~~~~~~~~~~~~~~~~~~
/var/home/user/test/components/jkent__frogfs/src/frogfs.c:218:5: note: in expansion of macro 'assert'
           │  218 |     assert(entry != NULL);
           │      |     ^~~~~~
           │
         'frogfs_get_path': events 13-16
           │
           │  220 |     char *path = calloc(PATH_MAX, 1);
           │      |                  ^~~~~~~~~~~~~~~~~~~
           │      |                  |
           │      |└────────────────>(13) ...to here
           │      |                  (14) allocated here
           │  221 |     size_t len = 0;
           │  222 |     if (!path) {
           │      |        ~          
           │      |        |
           │      |        (15) assuming 'path' is NULL
           │      |        (16) following 'true' branch (when 'path' is NULL)... ─>─┐
           │      |                                                                 │
           │
         'frogfs_get_path': event 17
           │
           │cc1:
           │ (17): ...to here
           │
    <──────┘
    │
  'frogfs_get_entry': events 18-19
    │
    │  193 |         char *match = frogfs_get_path(fs, entry);
    │      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
    │      |                       |
    │      |                       (18) returning to 'frogfs_get_entry' from 'frogfs_get_path'
    │  194 |         if (strcmp(path, match) == 0) {
    │      |             ~~~~~~~~~~~~~~~~~~~
    │      |             |
    │      |             (19) ⚠️  argument 2 ('match') NULL where non-null expected
    │
In file included from /var/home/user/test/components/jkent__frogfs/src/frogfs.c:18:
/var/home/user/.espressif/tools/xtensa-esp-elf/esp-15.2.0_20251204/xtensa-esp-elf/picolibc/include/string.h:113:10: note: argument 2 of 'strcmp' must be non-null
  113 | int      strcmp (const char *, const char *);
      |          ^~~~~~

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