/ Check-in [f3ae4ac5]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change sqlite3_snprintf() so that it does not write a zero-terminator if the buffer size argument is less than 1. Ticket #2341. Added documentation about the sqlite3_snprintf() function. (CVS 3935)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f3ae4ac5fe0bfa2f91e76a6def86c444e51fe80b
User & Date: drh 2007-05-07 11:24:30
Context
2007-05-07
11:53
Add interface to configure SQLite to use ICU collation functions. (CVS 3936) check-in: b29a81b4 user: danielk1977 tags: trunk
11:24
Change sqlite3_snprintf() so that it does not write a zero-terminator if the buffer size argument is less than 1. Ticket #2341. Added documentation about the sqlite3_snprintf() function. (CVS 3935) check-in: f3ae4ac5 user: drh tags: trunk
09:32
Add the experimental create_collation_x() api. (CVS 3934) check-in: ff49d48f user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to main.mk.

    61     61            main.o malloc.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
    62     62            pager.o parse.o pragma.o prepare.o printf.o random.o \
    63     63            select.o table.o tclsqlite.o tokenize.o trigger.o \
    64     64            update.o util.o vacuum.o \
    65     65            vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \
    66     66            where.o utf.o legacy.o vtab.o
    67     67   
    68         -LIBOBJ += icu.o
    69         -
    70     68   # All of the source code files.
    71     69   #
    72     70   SRC = \
    73     71     $(TOP)/src/alter.c \
    74     72     $(TOP)/src/analyze.c \
    75     73     $(TOP)/src/attach.c \
    76     74     $(TOP)/src/auth.c \
................................................................................
   139    137     $(TOP)/ext/fts2/fts2.c \
   140    138     $(TOP)/ext/fts2/fts2.h \
   141    139     $(TOP)/ext/fts2/fts2_hash.c \
   142    140     $(TOP)/ext/fts2/fts2_hash.h \
   143    141     $(TOP)/ext/fts2/fts2_porter.c \
   144    142     $(TOP)/ext/fts2/fts2_tokenizer.h \
   145    143     $(TOP)/ext/fts2/fts2_tokenizer1.c
   146         -SRC += \
   147         -  $(TOP)/ext/icu/icu.c
   148    144   
   149    145   # Generated source code files
   150    146   #
   151    147   SRC += \
   152    148     keywordhash.h \
   153    149     opcodes.c \
   154    150     opcodes.h \

Changes to src/printf.c.

   833    833   ** are not able to use a "," as the decimal point in place of "." as
   834    834   ** specified by some locales.
   835    835   */
   836    836   char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
   837    837     char *z;
   838    838     va_list ap;
   839    839   
          840  +  if( n<=0 ){
          841  +    return zBuf;
          842  +  }
          843  +  zBuf[0] = 0;
   840    844     va_start(ap,zFormat);
   841    845     z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
   842    846     va_end(ap);
   843    847     return z;
   844    848   }
   845    849   
   846    850   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.248 2007/05/07 09:32:45 danielk1977 Exp $
           16  +** $Id: test1.c,v 1.249 2007/05/07 11:24:30 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include "os.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
   421    421     char *zStr;
   422    422     int n = 0;
   423    423     zStr = sqlite3MPrintf("%s%n", argv[1], &n);
   424    424     sqliteFree(zStr);
   425    425     Tcl_SetObjResult(interp, Tcl_NewIntObj(n));
   426    426     return TCL_OK;
   427    427   }
          428  +
          429  +/*
          430  +** Usage:  sqlite3_snprintf_int  SIZE FORMAT  INT
          431  +**
          432  +** Test the of sqlite3_snprintf() routine.  SIZE is the size of the
          433  +** output buffer in bytes.  The maximum size is 100.  FORMAT is the
          434  +** format string.  INT is a single integer argument.  The FORMAT
          435  +** string must require no more than this one integer argument.  If
          436  +** You pass in a format string that requires more than one argument,
          437  +** bad things will happen.
          438  +*/
          439  +static int test_snprintf_int(
          440  +  void *NotUsed,
          441  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
          442  +  int argc,              /* Number of arguments */
          443  +  char **argv            /* Text of each argument */
          444  +){
          445  +  char zStr[100];
          446  +  int n = atoi(argv[1]);
          447  +  if( n>sizeof(zStr) ) n = sizeof(zStr);
          448  +  const char *zFormat = argv[2];
          449  +  int a1 = atoi(argv[3]);
          450  +  strcpy(zStr, "abcdefghijklmnopqrstuvwxyz");
          451  +  sqlite3_snprintf(n, zStr, zFormat, a1);
          452  +  Tcl_AppendResult(interp, zStr, 0);
          453  +  return TCL_OK;
          454  +}
   428    455   
   429    456   /*
   430    457   ** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING
   431    458   **
   432    459   ** Invoke the sqlite3_get_table_printf() interface using the open database
   433    460   ** DB.  The SQL is the string FORMAT.  The format string should contain
   434    461   ** one %s or %q.  STRING is the value inserted into %s or %q.
................................................................................
  4605   4632        { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
  4606   4633        { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
  4607   4634        { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
  4608   4635        { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
  4609   4636        { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
  4610   4637        { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
  4611   4638        { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
         4639  +     { "sqlite3_snprintf_int",          (Tcl_CmdProc*)test_snprintf_int     },
  4612   4640        { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
  4613   4641        { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
  4614   4642        { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
  4615   4643        { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
  4616   4644        { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
  4617   4645        { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
  4618   4646        { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },

Changes to test/printf.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the sqlite_*_printf() interface.
    13     13   #
    14         -# $Id: printf.test,v 1.22 2007/03/31 15:02:50 drh Exp $
           14  +# $Id: printf.test,v 1.23 2007/05/07 11:24:31 drh Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   set n 1
    20     20   foreach v {1 2 5 10 99 100 1000000 999999999 0 -1 -2 -5 -10 -99 -100 -9999999} {
    21     21     set v32 [expr {$v&0xffffffff}]
................................................................................
   264    264   do_test printf-14.2 {
   265    265     sqlite3_mprintf_n_test {xyzzy}
   266    266   } 5
   267    267   do_test printf-14.3 {
   268    268     sqlite3_mprintf_str {abc-%T-123} 0 0 {not used}
   269    269   } {abc-}
   270    270   
          271  +do_test printf-15.1 {
          272  +  sqlite3_snprintf_int 5 {12345} 0
          273  +} {1234}
          274  +do_test printf-15.2 {
          275  +  sqlite3_snprintf_int 5 {} 0
          276  +} {}
          277  +do_test printf-15.3 {
          278  +  sqlite3_snprintf_int 0 {} 0
          279  +} {abcdefghijklmnopqrstuvwxyz}
   271    280   
   272    281   finish_test

Changes to www/capi3ref.tcl.

     1         -set rcsid {$Id: capi3ref.tcl,v 1.56 2007/04/27 17:16:22 drh Exp $}
            1  +set rcsid {$Id: capi3ref.tcl,v 1.57 2007/05/07 11:24:31 drh Exp $}
     2      2   source common.tcl
     3      3   header {C/C++ Interface For SQLite Version 3}
     4      4   puts {
     5      5   <h2 class=pdf_section>C/C++ Interface For SQLite Version 3</h2>
     6      6   }
     7      7   
     8      8   proc api {name prototype desc {notused x}} {
................................................................................
  1129   1129     INSERT INTO table1 VALUES('It's a happy day!');
  1130   1130     </pre></blockquote>
  1131   1131   
  1132   1132    This second example is an SQL syntax error.  As a general rule you
  1133   1133    should always use %q instead of %s when inserting text into a string 
  1134   1134    literal.
  1135   1135   } {}
         1136  +
         1137  +api {} {
         1138  +char *sqlite3_snprintf(int bufSize, char *buf, const char *zFormat, ...);
         1139  +} {
         1140  +  This routine works like "sprintf()", writing a formatted string into
         1141  +  the buf[].  However, no more than bufSize characters will be written
         1142  +  into buf[].  This routine returns a pointer to buf[].  If bufSize is
         1143  +  greater than zero, then buf[] is guaranteed to be zero-terminated.
         1144  +
         1145  +  This routine uses the same extended formatting options as
         1146  +  sqlite3_mprintf() and sqlite3_vmprintf().
         1147  +
         1148  +  Note these differences with the snprintf() function found in many
         1149  +  standard libraries:  (1)  sqlite3_snprintf() returns a pointer to the
         1150  +  buffer rather than the number of characters written.  (It would,
         1151  +  arguably, be more useful to return the number of characters written,
         1152  +  but we discovered that after the interface had been published and
         1153  +  are unwilling to break backwards compatibility.)  (2)  The order
         1154  +  of the bufSize and buf parameter is reversed from snprintf().  
         1155  +  And (3) sqlite3_snprintf() always writes a zero-terminator if bufSize
         1156  +  is positive.  
         1157  +
         1158  +  Please do not use the return value of this routine.  We may
         1159  +  decide to make the minor compatibility break and change this routine
         1160  +  to return the number of characters written rather than a pointer to
         1161  +  the buffer in a future minor version increment.
         1162  +}
  1136   1163   
  1137   1164   api {} {
  1138   1165   int sqlite3_open(
  1139   1166     const char *filename,   /* Database filename (UTF-8) */
  1140   1167     sqlite3 **ppDb          /* OUT: SQLite db handle */
  1141   1168   );
  1142   1169   int sqlite3_open16(