GNS3 / ubridge

Bridge for UDP tunnels, Ethernet, TAP and VMnet interfaces.
GNU General Public License v3.0
115 stars 46 forks source link

SYSTEM_INIPARSER option support #60

Closed linxon closed 5 years ago

linxon commented 5 years ago

do I have to use the SYSTEM_INIPARSER option in the latest version? https://github.com/GNS3/ubridge/blob/8d4e39470ae111827341281e84ac2a3f591df815/Makefile#L68

because when I enable it I get these errors while compiling: Selection_005

diff output btw initparser.c and your src/iniparser/iniparser.c:

diff -ur a/iniparser.c b/iniparser.c
--- a/iniparser.c   2019-05-17 12:06:17.204073297 +0300
+++ b/iniparser.c   2019-05-17 12:06:39.879468506 +0300
@@ -8,7 +8,6 @@
 /*--------------------------------------------------------------------------*/
 /*---------------------------- Includes ------------------------------------*/
 #include <ctype.h>
-#include <stdarg.h>
 #include "iniparser.h"

 /*---------------------------- Defines -------------------------------------*/
@@ -58,27 +57,18 @@

 /*-------------------------------------------------------------------------*/
 /**
-  @brief    Duplicate a string
-  @param    s String to duplicate
-  @return   Pointer to a newly allocated string, to be freed with free()
+  @brief    Copy string in a newly mallocced area
+  @param    str  String to copy.
+  @return   str  Copied version of the given string allocated with malloc

-  This is a replacement for strdup(). This implementation is provided
-  for systems that do not have it.
+  Original strdup is not portable, need to implement our own
  */
 /*--------------------------------------------------------------------------*/
-static char * xstrdup(const char * s)
+static char * _strdup(const char *s)
 {
-    char * t ;
-    size_t len ;
-    if (!s)
-        return NULL ;
-
-    len = strlen(s) + 1 ;
-    t = (char*) malloc(len) ;
-    if (t) {
-        memcpy(t, s, len) ;
-    }
-    return t ;
+    char * copy = (char*) malloc(strlen(s));
+    strcpy(copy, s);
+    return copy ;
 }

 /*-------------------------------------------------------------------------*/
@@ -88,7 +78,7 @@
   @return   unsigned New size of the string.
  */
 /*--------------------------------------------------------------------------*/
-static unsigned strstrip(char * s)
+unsigned strstrip(char * s)
 {
     char *last = NULL ;
     char *dest = s;
@@ -110,41 +100,6 @@

 /*-------------------------------------------------------------------------*/
 /**
-  @brief    Default error callback for iniparser: wraps `fprintf(stderr, ...)`.
- */
-/*--------------------------------------------------------------------------*/
-static int default_error_callback(const char *format, ...)
-{
-  int ret;
-  va_list argptr;
-  va_start(argptr, format);
-  ret = vfprintf(stderr, format, argptr);
-  va_end(argptr);
-  return ret;
-}
-
-static int (*iniparser_error_callback)(const char*, ...) = default_error_callback;
-
-/*-------------------------------------------------------------------------*/
-/**
-  @brief    Configure a function to receive the error messages.
-  @param    errback  Function to call.
-
-  By default, the error will be printed on stderr. If a null pointer is passed
-  as errback the error callback will be switched back to default.
- */
-/*--------------------------------------------------------------------------*/
-void iniparser_set_error_callback(int (*errback)(const char *, ...))
-{
-  if (errback) {
-    iniparser_error_callback = errback;
-  } else {
-    iniparser_error_callback = default_error_callback;
-  }
-}
-
-/*-------------------------------------------------------------------------*/
-/**
   @brief    Get number of sections in a dictionary
   @param    d   Dictionary to examine
   @return   int Number of sections found in dictionary
@@ -339,8 +294,7 @@
     if (! iniparser_find_entry(d, s)) return nkeys;

     seclen  = (int)strlen(s);
-    strlwc(s, keym, sizeof(keym));
-    keym[seclen] = ':';
+    sprintf(keym, "%s:", s);

     for (j=0 ; j<d->size ; j++) {
         if (d->key[j]==NULL)
@@ -378,8 +332,7 @@
     if (! iniparser_find_entry(d, s)) return NULL;

     seclen  = (int)strlen(s);
-    strlwc(s, keym, sizeof(keym));
-    keym[seclen] = ':';
+    sprintf(keym, "%s:", s);

     i = 0;

@@ -426,11 +379,11 @@

 /*-------------------------------------------------------------------------*/
 /**
-  @brief    Get the string associated to a key, convert to an long int
+  @brief    Get the string associated to a key, convert to an int
   @param    d Dictionary to search
   @param    key Key string to look for
   @param    notfound Value to return in case of error
-  @return   long integer
+  @return   integer

   This function queries a dictionary for a key. A key as read from an
   ini file is given as "section:key". If the key cannot be found,
@@ -451,46 +404,13 @@
   Credits: Thanks to A. Becker for suggesting strtol()
  */
 /*--------------------------------------------------------------------------*/
-long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound)
+int iniparser_getint(const dictionary * d, const char * key, int notfound)
 {
     const char * str ;

     str = iniparser_getstring(d, key, INI_INVALID_KEY);
     if (str==INI_INVALID_KEY) return notfound ;
-    return strtol(str, NULL, 0);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/**
-  @brief    Get the string associated to a key, convert to an int
-  @param    d Dictionary to search
-  @param    key Key string to look for
-  @param    notfound Value to return in case of error
-  @return   integer
-
-  This function queries a dictionary for a key. A key as read from an
-  ini file is given as "section:key". If the key cannot be found,
-  the notfound value is returned.
-
-  Supported values for integers include the usual C notation
-  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
-  are supported. Examples:
-
-  "42"      ->  42
-  "042"     ->  34 (octal -> decimal)
-  "0x42"    ->  66 (hexa  -> decimal)
-
-  Warning: the conversion may overflow in various ways. Conversion is
-  totally outsourced to strtol(), see the associated man page for overflow
-  handling.
-
-  Credits: Thanks to A. Becker for suggesting strtol()
- */
-/*--------------------------------------------------------------------------*/
-int iniparser_getint(const dictionary * d, const char * key, int notfound)
-{
-    return (int)iniparser_getlongint(d, key, notfound);
+    return (int)strtol(str, NULL, 0);
 }

 /*-------------------------------------------------------------------------*/
@@ -640,7 +560,7 @@
     char * line = NULL;
     size_t      len ;

-    line = xstrdup(input_line);
+    line = _strdup(input_line);
     len = strstrip(line);

     sta = LINE_UNPROCESSED ;
@@ -657,14 +577,9 @@
         strlwc(section, section, len);
         sta = LINE_SECTION ;
     } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
-           ||  sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2) {
-        /* Usual key=value with quotes, with or without comments */
-        strstrip(key);
-        strlwc(key, key, len);
-        /* Don't strip spaces from values surrounded with quotes */
-        sta = LINE_VALUE ;
-    } else if (sscanf (line, "%[^=] = %[^;#]", key, value) == 2) {
-        /* Usual key=value without quotes, with or without comments */
+           ||  sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2
+           ||  sscanf (line, "%[^=] = %[^;#]",     key, value) == 2) {
+        /* Usual key=value, with or without comments */
         strstrip(key);
         strlwc(key, key, len);
         strstrip(value);
@@ -711,7 +626,7 @@
   The returned dictionary must be freed using iniparser_freedict().
  */
 /*--------------------------------------------------------------------------*/
-dictionary * iniparser_load(const char * ininame)
+dictionary * iniparser_load(const char * ininame, load_options options)
 {
     FILE * in ;

@@ -725,12 +640,11 @@
     int  len ;
     int  lineno=0 ;
     int  errs=0;
-    int  mem_err=0;

     dictionary * dict ;

     if ((in=fopen(ininame, "r"))==NULL) {
-        iniparser_error_callback("iniparser: cannot open %s\n", ininame);
+        fprintf(stderr, "iniparser: cannot open %s\n", ininame);
         return NULL ;
     }

@@ -749,14 +663,14 @@
     while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
         lineno++ ;
         len = (int)strlen(line)-1;
-        if (len<=0)
+        if (len==0)
             continue;
         /* Safety check against buffer overflows */
         if (line[len]!='\n' && !feof(in)) {
-            iniparser_error_callback(
-              "iniparser: input line too long in %s (%d)\n",
-              ininame,
-              lineno);
+            fprintf(stderr,
+                    "iniparser: input line too long in %s (%d)\n",
+                    ininame,
+                    lineno);
             dictionary_del(dict);
             fclose(in);
             return NULL ;
@@ -784,20 +698,27 @@
             break ;

             case LINE_SECTION:
-            mem_err = dictionary_set(dict, section, NULL);
+            errs = dictionary_set(dict, section, NULL);
             break ;

             case LINE_VALUE:
             sprintf(tmp, "%s:%s", section, key);
-            mem_err = dictionary_set(dict, tmp, val);
+            errs = dictionary_set(dict, tmp, val) ;
             break ;

             case LINE_ERROR:
-            iniparser_error_callback(
-              "iniparser: syntax error in %s (%d):\n-> %s\n",
-              ininame,
-              lineno,
-              line);
+
+            if(options & HIDE_ERRORED_LINE_CONTENT) {
+              fprintf(stderr, "iniparser: syntax error in %s (%d)\n",
+                      ininame,
+                      lineno);
+            }
+            else {
+              fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
+                      ininame,
+                      lineno);
+              fprintf(stderr, "-> %s\n", line);
+            }
             errs++ ;
             break;

@@ -806,8 +727,8 @@
         }
         memset(line, 0, ASCIILINESZ);
         last=0;
-        if (mem_err<0) {
-            iniparser_error_callback("iniparser: memory allocation failure\n");
+        if (errs<0) {
+            fprintf(stderr, "iniparser: memory allocation failure\n");
             break ;
         }
     }
ziajka commented 5 years ago

Thank you @linxon for reporting this. It is an issue, workaround is to use our copy of iniparser.

linxon commented 5 years ago

what do you think about these warnings and it can be critical in the future?

...
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/hypervisor_bridge.o src/hypervisor_bridge.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/nio_linux_raw.o src/nio_linux_raw.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/hypervisor_docker.o src/hypervisor_docker.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/hypervisor_iol_bridge.o src/hypervisor_iol_bridge.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/hypervisor_brctl.o src/hypervisor_brctl.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/netlink/nl.o src/netlink/nl.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/iniparser/iniparser.o src/iniparser/iniparser.c
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW   -c -o src/iniparser/dictionary.o src/iniparser/dictionary.c
src/iniparser/iniparser.c: In function ‘iniparser_load’:
src/iniparser/iniparser.c:705:32: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=]
             sprintf(tmp, "%s:%s", section, key);
                                ^
In file included from /usr/include/stdio.h:867,
                 from src/iniparser/iniparser.h:17,
                 from src/iniparser/iniparser.c:11:
/usr/include/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 2050 bytes into a destination of size 2049
   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       __bos (__s), __fmt, __va_arg_pack ());
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x86_64-pc-linux-gnu-gcc -O2 -pipe -Wall -DLINUX_RAW -Wl,-O1 -Wl,--as-needed -o ubridge src/ubridge.o src/nio.o src/nio_udp.o src/nio_unix.o src/nio_ethernet.o src/nio_tap.o src/parse.o src/packet_filter.o src/pcap_capture.o src/pcap_filter.o src/hypervisor.o src/hypervisor_parser.o src/hypervisor_bridge.o src/nio_linux_raw.o src/hypervisor_docker.o src/hypervisor_iol_bridge.o src/hypervisor_brctl.o src/netlink/nl.o src/iniparser/iniparser.o src/iniparser/dictionary.o -lpthread -lpcap
>>> Source compiled.

P.S. gcc-8.3.0

ziajka commented 5 years ago

@linxon Indeed, updated iniparser and fixed issue in the latest release: https://github.com/GNS3/ubridge/releases/tag/v0.9.16

linxon commented 5 years ago

@ziajka thank you! :)