Loading ...
Sorry, an error occurred while loading the content.

5602Re: sscanf bugs (nuttx-6.30)

Expand Messages
  • spudarnia
    Mar 30, 2014
    • 0 Attachment
      Thanks.  Yes, I now see the problem.  The root cause of the counting problem is this conditional logic:
       
        /* Note %n does not count as a conversion */

        if (!noassign && *fmt != 'n')
          {
            count++;
          }

      The cause of the problem is that the conditions for incrementing the count are insufficient.  The best solution, I believe, is simply to remove the above conditional logic altogether and simply increment the count when a value is written back in all cases (except %n).  I made the change at the end of this email. Now I see:

      $ ./sscanf.exe ""
      retval=-1, n=0, m=0

      $ ./sscanf.exe "1"
      retval=1, n=1, m=0

      patacongo@Sharmanto ~/projects/nuttx/tmp/sscanf
      $ ./sscanf.exe "1 2"
      retval=2, n=1, m=2

      patacongo@Sharmanto ~/projects/nuttx/tmp/sscanf
      $ ./sscanf.exe "1 2 3"
      retval=2, n=1, m=2

      [Note it also now returns EOF if no values were converted.]

      I believe that this change is safer because it is simple, straight forward, and not likely to have side-effects.  I will check it in.  The only risk is that I might have missed a place count 'count' needs to be incremented.  If you see any problem let me know.

      Greg


      @@ -307,6 +307,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
                           {
                             strncpy(tv, buf, width);
                             tv[width] = '\0';
      +                      count++;
                           }

                         /* Update the buffer pointer past the string in the input */
      @@ -354,6 +355,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
                           {
                             strncpy(tv, buf, width);
                             tv[width] = '\0';
      +                      count++;
                           }

                         /* Update the buffer pointer past the character(s) in the
      @@ -489,6 +491,8 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
                                       tmplong, pint);
                                 *pint = (int)tmplong;
                               }
      +
      +                      count++;
                           }
                       }
                   }
      @@ -601,6 +605,8 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
                                 lvdbg("vsscanf: Return %f to %p\n", dvalue, pf);
                                 *pf = (float)dvalue;
                               }
      +
      +                      count++;
                           }
                       }
       #endif
      @@ -629,13 +637,6 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
                       }
                   }

      -          /* Note %n does not count as a conversion */
      -
      -          if (!noassign && *fmt != 'n')
      -            {
      -              count++;
      -            }
      -
                 width    = 0;
                 noassign = false;
                 lflag    = false;
                                                                                                                
      @@ -674,5 +675,9 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
               }
           }
       
      -  return count;
      +  /* sscanf is required to return EOF if the input ends before the first
      +   * matching failure or conversion.
      +   */
      +
      +  return count ? count : EOF;
       }
    • Show all 12 messages in this topic