Hello!

This bug duplicates upstream issue #142:
https://github.com/a2o/snoopy/issues/142

It is fixed by PR https://github.com/a2o/snoopy/pull/143

The fix commit (PR merge) is
https://github.com/a2o/snoopy/commit/360bb18e16ceaca16a22b94be9e17fd5f2184c01

I've tried to extract the patch from commit (patch attached), but
compilation started to fail with another warning:

cmdline.c: In function ‘snoopy_datasource_cmdline’:
cmdline.c:71:79: error: comparison between pointer and zero character
constant [-Werror=pointer-compare]
   71 |     for (cmdLineArgCount=0 ;
*(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ;
cmdLineArgCount++);
     
|                                                                              
^~
cmdline.c:71:30: note: did you mean to dereference the pointer?
   71 |     for (cmdLineArgCount=0 ;
*(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ;
cmdLineArgCount++);
      |                              ^
cc1: all warnings being treated as errors

diff -Nur a/lib/inih/dev-update.sh b/lib/inih/dev-update.sh
--- a/lib/inih/dev-update.sh
+++ b/lib/inih/dev-update.sh
@@ -7,17 +7,27 @@
 set -e
 set -u
 GITORIGINURL="https://github.com/benhoyt/inih.git";
-GITORIGINREF="master"
+GITREF="master"
 TMPGITDIR="./_tmp-inih-git"
 DESTDIR="."
 DESTDIRSRC="./src"
 
 
 
+### Parse arguments
+#
+if [ "${1:-}" != "" ]; then
+    GITREF="$1"
+fi
+echo "Using gitref: $GITREF"
+
+
+
 ### Clone the repo
 #
 rm -rf $TMPGITDIR
 git clone   $GITORIGINURL   $TMPGITDIR
+(cd $TMPGITDIR && git checkout $GITREF)
 
 
 
@@ -30,7 +40,7 @@
 
 ### Apply patches
 #
-patch -p3 < ./patches/0001-strip-value-quotes.diff
+patch -p0 < ./patches/0001-strip-value-quotes.diff
 
 
 
diff -Nur a/lib/inih/patches/0001-strip-value-quotes.diff 
b/lib/inih/patches/0001-strip-value-quotes.diff
--- a/lib/inih/patches/0001-strip-value-quotes.diff
+++ b/lib/inih/patches/0001-strip-value-quotes.diff
@@ -1,9 +1,7 @@
-diff --git a/lib/inih/src/ini.c b/lib/inih/src/ini.c
-index 27ca85b..2c015c8 100644
---- a/lib/inih/src/ini.c
-+++ b/lib/inih/src/ini.c
-@@ -149,6 +149,17 @@ int ini_parse_stream(ini_reader reader, void* stream, 
ini_handler handler,
- #endif
+--- src/ini.c.orig     2018-12-26 21:08:15.289767000 +0000
++++ src/ini.c  2018-12-26 21:07:25.707778000 +0000
+@@ -187,6 +187,17 @@
+                 value = lskip(value);
                  rstrip(value);
  
 +                /* Strip surrounding double and single quotes */
@@ -19,4 +17,4 @@
 +
                  /* Valid name[=:]value pair found, call handler */
                  strncpy0(prev_name, name, sizeof(prev_name));
-                 if (!handler(user, section, name, value) && !error)
+                 if (!HANDLER(user, section, name, value) && !error)
diff -Nur a/lib/inih/SOURCE.txt b/lib/inih/SOURCE.txt
--- a/lib/inih/SOURCE.txt
+++ b/lib/inih/SOURCE.txt
@@ -1,3 +1,3 @@
 git-origin-url = 'https://github.com/benhoyt/inih.git'
-git-origin-ref = 'tags/r36-0-g5dbf5cb'
+git-origin-ref = 'tags/r42-0-g9d1af9d'
 patches-dir = 'patches/'
diff -Nur a/lib/inih/src/ini.c b/lib/inih/src/ini.c
--- a/lib/inih/src/ini.c
+++ b/lib/inih/src/ini.c
@@ -24,6 +24,12 @@
 #define MAX_SECTION 50
 #define MAX_NAME 50
 
+/* Used by ini_parse_string() to keep track of string parsing state. */
+typedef struct {
+    const char* ptr;
+    size_t num_left;
+} ini_parse_string_ctx;
+
 /* Strip whitespace chars off end of given string, in place. Return s. */
 static char* rstrip(char* s)
 {
@@ -64,7 +70,7 @@
 /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
 static char* strncpy0(char* dest, const char* src, size_t size)
 {
-    strncpy(dest, src, size);
+    strncpy(dest, src, size - 1);
     dest[size - 1] = '\0';
     return dest;
 }
@@ -76,8 +82,14 @@
     /* Uses a fair bit of stack (use heap instead if you need to) */
 #if INI_USE_STACK
     char line[INI_MAX_LINE];
+    int max_line = INI_MAX_LINE;
 #else
     char* line;
+    int max_line = INI_INITIAL_ALLOC;
+#endif
+#if INI_ALLOW_REALLOC
+    char* new_line;
+    int offset;
 #endif
     char section[MAX_SECTION] = "";
     char prev_name[MAX_NAME] = "";
@@ -90,14 +102,40 @@
     int error = 0;
 
 #if !INI_USE_STACK
-    line = (char*)malloc(INI_MAX_LINE);
+    line = (char*)malloc(INI_INITIAL_ALLOC);
     if (!line) {
         return -2;
     }
 #endif
 
+#if INI_HANDLER_LINENO
+#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
+#else
+#define HANDLER(u, s, n, v) handler(u, s, n, v)
+#endif
+
     /* Scan through stream line by line */
-    while (reader(line, INI_MAX_LINE, stream) != NULL) {
+    while (reader(line, max_line, stream) != NULL) {
+#if INI_ALLOW_REALLOC
+        offset = strlen(line);
+        while (offset == max_line - 1 && line[offset - 1] != '\n') {
+            max_line *= 2;
+            if (max_line > INI_MAX_LINE)
+                max_line = INI_MAX_LINE;
+            new_line = realloc(line, max_line);
+            if (!new_line) {
+                free(line);
+                return -2;
+            }
+            line = new_line;
+            if (reader(line + offset, max_line - offset, stream) == NULL)
+                break;
+            if (max_line >= INI_MAX_LINE)
+                break;
+            offset += strlen(line + offset);
+        }
+#endif
+
         lineno++;
 
         start = line;
@@ -110,15 +148,14 @@
 #endif
         start = lskip(rstrip(start));
 
-        if (*start == ';' || *start == '#') {
-            /* Per Python configparser, allow both ; and # comments at the
-               start of a line */
+        if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
+            /* Start-of-line comment */
         }
 #if INI_ALLOW_MULTILINE
         else if (*prev_name && *start && start > line) {
             /* Non-blank line with leading whitespace, treat as continuation
                of previous name's value (as per Python configparser). */
-            if (!handler(user, section, prev_name, start) && !error)
+            if (!HANDLER(user, section, prev_name, start) && !error)
                 error = lineno;
         }
 #endif
@@ -141,12 +178,13 @@
             if (*end == '=' || *end == ':') {
                 *end = '\0';
                 name = rstrip(start);
-                value = lskip(end + 1);
+                value = end + 1;
 #if INI_ALLOW_INLINE_COMMENTS
                 end = find_chars_or_comment(value, NULL);
                 if (*end)
                     *end = '\0';
 #endif
+                value = lskip(value);
                 rstrip(value);
 
                 /* Strip surrounding double and single quotes */
@@ -154,7 +192,7 @@
                     value[strlen(value) - 1] = '\0';
                     value += 1;
                 } else {
-                    if ((*value == '\'') && (value[strlen(value) - 1] == 
'\'')) {
+                    if ((*value == '"') && (value[strlen(value) - 1] == '"')) {
                         value[strlen(value) - 1] = '\0';
                         value += 1;
                     }
@@ -162,7 +200,7 @@
 
                 /* Valid name[=:]value pair found, call handler */
                 strncpy0(prev_name, name, sizeof(prev_name));
-                if (!handler(user, section, name, value) && !error)
+                if (!HANDLER(user, section, name, value) && !error)
                     error = lineno;
             }
             else if (!error) {
@@ -203,3 +241,40 @@
     fclose(file);
     return error;
 }
+
+/* An ini_reader function to read the next line from a string buffer. This
+   is the fgets() equivalent used by ini_parse_string(). */
+static char* ini_reader_string(char* str, int num, void* stream) {
+    ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
+    const char* ctx_ptr = ctx->ptr;
+    size_t ctx_num_left = ctx->num_left;
+    char* strp = str;
+    char c;
+
+    if (ctx_num_left == 0 || num < 2)
+        return NULL;
+
+    while (num > 1 && ctx_num_left != 0) {
+        c = *ctx_ptr++;
+        ctx_num_left--;
+        *strp++ = c;
+        if (c == '\n')
+            break;
+        num--;
+    }
+
+    *strp = '\0';
+    ctx->ptr = ctx_ptr;
+    ctx->num_left = ctx_num_left;
+    return str;
+}
+
+/* See documentation in header file. */
+int ini_parse_string(const char* string, ini_handler handler, void* user) {
+    ini_parse_string_ctx ctx;
+
+    ctx.ptr = string;
+    ctx.num_left = strlen(string);
+    return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
+                            user);
+}
diff -Nur a/lib/inih/src/ini.h b/lib/inih/src/ini.h
--- a/lib/inih/src/ini.h
+++ b/lib/inih/src/ini.h
@@ -17,9 +17,20 @@
 
 #include <stdio.h>
 
+/* Nonzero if ini_handler callback should accept lineno parameter. */
+#ifndef INI_HANDLER_LINENO
+#define INI_HANDLER_LINENO 0
+#endif
+
 /* Typedef for prototype of handler function. */
+#if INI_HANDLER_LINENO
+typedef int (*ini_handler)(void* user, const char* section,
+                           const char* name, const char* value,
+                           int lineno);
+#else
 typedef int (*ini_handler)(void* user, const char* section,
                            const char* name, const char* value);
+#endif
 
 /* Typedef for prototype of fgets-style reader function. */
 typedef char* (*ini_reader)(char* str, int num, void* stream);
@@ -44,10 +55,16 @@
 int ini_parse_file(FILE* file, ini_handler handler, void* user);
 
 /* Same as ini_parse(), but takes an ini_reader function pointer instead of
-   filename. Used for implementing custom or string-based I/O. */
+   filename. Used for implementing custom or string-based I/O (see also
+   ini_parse_string). */
 int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
                      void* user);
 
+/* Same as ini_parse(), but takes a zero-terminated string with the INI data
+instead of a file. Useful for parsing INI data from a network socket or
+already in memory. */
+int ini_parse_string(const char* string, ini_handler handler, void* user);
+
 /* Nonzero to allow multi-line value parsing, in the style of Python's
    configparser. If allowed, ini_parse() will call the handler with the same
    name for each subsequent line parsed. */
@@ -61,6 +78,12 @@
 #define INI_ALLOW_BOM 1
 #endif
 
+/* Chars that begin a start-of-line comment. Per Python configparser, allow
+   both ; and # comments at the start of a line by default. */
+#ifndef INI_START_COMMENT_PREFIXES
+#define INI_START_COMMENT_PREFIXES ";#"
+#endif
+
 /* Nonzero to allow inline comments (with valid inline comment characters
    specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
    Python 3.2+ configparser behaviour. */
@@ -71,21 +94,35 @@
 #define INI_INLINE_COMMENT_PREFIXES ";"
 #endif
 
-/* Nonzero to use stack, zero to use heap (malloc/free). */
+/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
 #ifndef INI_USE_STACK
 #define INI_USE_STACK 1
 #endif
 
+/* Maximum line length for any line in INI file (stack or heap). Note that
+   this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
+#ifndef INI_MAX_LINE
+#define INI_MAX_LINE 200
+#endif
+
+/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
+   fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
+   zero. */
+#ifndef INI_ALLOW_REALLOC
+#define INI_ALLOW_REALLOC 0
+#endif
+
+/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
+   is zero. */
+#ifndef INI_INITIAL_ALLOC
+#define INI_INITIAL_ALLOC 200
+#endif
+
 /* Stop parsing on first error (default is to keep parsing). */
 #ifndef INI_STOP_ON_FIRST_ERROR
 #define INI_STOP_ON_FIRST_ERROR 0
 #endif
 
-/* Maximum line length for any line in INI file. */
-#ifndef INI_MAX_LINE
-#define INI_MAX_LINE 200
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff -Nur a/src/datasource/rpname.c b/src/datasource/rpname.c
--- a/src/datasource/rpname.c
+++ b/src/datasource/rpname.c
@@ -154,7 +154,7 @@
                 strncpy(returnValue, v, PROC_PID_STATUS_VAL_MAX_LENGTH);
                 returnValue[PROC_PID_STATUS_VAL_MAX_LENGTH_STR-1] = 0; // 
Change newline into null character
             } else {
-                strncpy(returnValue, v, PROC_PID_STATUS_VAL_MAX_LENGTH_STR);
+                strncpy(returnValue, v, PROC_PID_STATUS_VAL_MAX_LENGTH_STR-1);
             }
 
             // Do a cleanup and return a string duplicate, which should be 
freed by the caller
diff -Nur a/src/filtering.c b/src/filtering.c
--- a/src/filtering.c
+++ b/src/filtering.c
@@ -59,7 +59,6 @@
     char *filterChain
 ) {
     char  filterChainCopy[SNOOPY_FILTER_CHAIN_MAX_SIZE];   // Must be here, or 
strtok_r segfaults
-    int   filterChainCopySize;
     int   j;
     char *str;
     char *rest;
@@ -67,12 +66,8 @@
     char *fcPos_filterSpecArg;   // Pointer to argument part of single filter 
specification in a filter chain
 
     // Copy the filter chain specification to separate string, to be used in 
strtok_r
-    filterChainCopySize = strlen(filterChain);
-    if (filterChainCopySize > SNOOPY_FILTER_CHAIN_MAX_SIZE - 1) {
-        filterChainCopySize = SNOOPY_FILTER_CHAIN_MAX_SIZE - 1;
-    }
-    strncpy(filterChainCopy, filterChain, filterChainCopySize);
-    filterChainCopy[filterChainCopySize] = '\0';
+    strncpy(filterChainCopy, filterChain, SNOOPY_FILTER_CHAIN_MAX_SIZE - 1);
+    filterChainCopy[SNOOPY_FILTER_CHAIN_MAX_SIZE-1] = '\0';
 
     // Loop through all filters
     for (j=1, str=filterChainCopy;  ; j++, str=NULL) {

Reply via email to