apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject cvs commit: apr/test teststr.c
Date Sun, 25 Aug 2002 04:10:40 GMT
rbb         2002/08/24 21:10:40

  Modified:    .        CHANGES
               strings  apr_snprintf.c
               test     teststr.c
  Log:
  Printing a string with apr_snprintf can seg fault, if a precision is
  specified for the string, and the string being printed doesn't have a
  trailing '\0'.  Fix that seg fault by not calling strlen if a precision
  is specified when printing a string.  Also add a test to the test suite
  for this case.
  
  PR:	8554
  Submitted by:	R Samuel Klatchko <rsk@brightmail.com>
  
  Revision  Changes    Path
  1.325     +8 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.324
  retrieving revision 1.325
  diff -u -r1.324 -r1.325
  --- CHANGES	22 Aug 2002 23:29:01 -0000	1.324
  +++ CHANGES	25 Aug 2002 04:10:39 -0000	1.325
  @@ -1,4 +1,12 @@
   Changes with APR 0.9.0
  +
  +  *) Printing a string with apr_snprintf can seg fault, if a precision is
  +     specified for the string, and the string being printed doesn't have a
  +     trailing '\0'.  Fix that seg fault by not calling strlen if a precision
  +     is specified when printing a string.  Also add a test to the test suite
  +     for this case.
  +     [R Samuel Klatchko <rsk@brightmail.com>]
  +
     *) handle leak related to threads on Windows2000/XP 
        [INOUE Seiichiro <inoue@ariel-networks.com>]
   
  
  
  
  1.26      +32 -3     apr/strings/apr_snprintf.c
  
  Index: apr_snprintf.c
  ===================================================================
  RCS file: /home/cvs/apr/strings/apr_snprintf.c,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- apr_snprintf.c	13 Jul 2002 21:34:36 -0000	1.25
  +++ apr_snprintf.c	25 Aug 2002 04:10:40 -0000	1.26
  @@ -952,9 +952,38 @@
               case 's':
                   s = va_arg(ap, char *);
                   if (s != NULL) {
  -                    s_len = strlen(s);
  -                    if (adjust_precision && precision < s_len)
  -                        s_len = precision;
  +                    if (!adjust_precision) {
  +                        s_len = strlen(s);
  +                    }
  +                    else {
  +                        /* From the C library standard in section 7.9.6.1:
  +                         * ...if the precision is specified, no more then
  +                         * that many characters are written.  If the
  +                         * precision is not specified or is greater
  +                         * than the size of the array, the array shall
  +                         * contain a null character.
  +                         *
  +                         * My reading is is precision is specified and
  +                         * is less then or equal to the size of the
  +                         * array, no null character is required.  So
  +                         * we can't do a strlen.
  +                         *
  +                         * This figures out the length of the string
  +                         * up to the precision.  Once it's long enough
  +                         * for the specified precision, we don't care
  +                         * anymore.
  +                         *
  +                         * NOTE: you must do the length comparison
  +                         * before the check for the null character.
  +                         * Otherwise, you'll check one beyond the
  +                         * last valid character.
  +                         */
  +                        const char *walk;
  +
  +                        for (walk = s, s_len = 0;
  +                             (s_len < precision) && (*walk != '\0');
  +                             ++walk, ++s_len);
  +                    }
                   }
                   else {
                       s = S_NULL;
  
  
  
  1.4       +23 -0     apr/test/teststr.c
  
  Index: teststr.c
  ===================================================================
  RCS file: /home/cvs/apr/test/teststr.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- teststr.c	13 Mar 2002 20:39:27 -0000	1.3
  +++ teststr.c	25 Aug 2002 04:10:40 -0000	1.4
  @@ -54,6 +54,7 @@
   
   #include <assert.h>
   #include <stdlib.h>
  +#include <stdio.h>
   #include <string.h>
   
   #include "apr_general.h"
  @@ -119,6 +120,27 @@
       }
   }
   
  +void test_snprintf(apr_pool_t *p)
  +{
  +    char buff[100];
  +    char *testing = apr_palloc(p, 10);
  +
  +    testing[0] = 't';
  +    testing[1] = 'e';
  +    testing[2] = 's';
  +    testing[3] = 't';
  +    testing[4] = 'i';
  +    testing[5] = 'n';
  +    testing[6] = 'g';
  +    
  +    fprintf(stderr, "Testing precision  ........  ");
  +    apr_snprintf(buff, sizeof(buff), "%.*s", 7, testing);
  +    if (!strncmp(buff, testing, 7)) {
  +        fprintf(stderr, "OK\n");
  +    }
  +
  +}
  +
   int main(int argc, const char * const argv[])
   {
       apr_pool_t *p;
  @@ -128,6 +150,7 @@
       apr_pool_create(&p, NULL);
   
       test_strtok(p);
  +    test_snprintf(p);
   
       return 0;
   }
  
  
  

Mime
View raw message