]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The %#Q conversion now adds unistr('...') around the converted string if
authordrh <>
Sun, 23 Feb 2025 11:48:07 +0000 (11:48 +0000)
committerdrh <>
Sun, 23 Feb 2025 11:48:07 +0000 (11:48 +0000)
escape characters were inserted.  %#w now works just like %w as escape
sequences inside of identifiers are not recognized.

FossilOrigin-Name: 997391d42079783e294836f714ccd9526ecc442c8dbf8212d72cd17c67e7158a

manifest
manifest.uuid
src/printf.c

index 73208a8d34cab64c7b74f78c49c8afa2a949fd03..82f49876ada3b8a8b903c10da55b203cdbe70481 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\s%Q,\s%q,\sand\s%w\sprintf\sconversions\sso\sthat\sif\sthe\salternate-form\nflag\s#\sis\spresent,\sthey\stransform\sbackslash\sand\scontrol\scharacters\sinto\nunistr()-style\sbackslash\sescape\scodes.
-D 2025-02-23T00:09:24.456
+C The\s%#Q\sconversion\snow\sadds\sunistr('...')\saround\sthe\sconverted\sstring\sif\nescape\scharacters\swere\sinserted.\s\s%#w\snow\sworks\sjust\slike\s%w\sas\sescape\nsequences\sinside\sof\sidentifiers\sare\snot\srecognized.
+D 2025-02-23T11:48:07.678
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -777,7 +777,7 @@ F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 F src/pcache1.c 78d4935e510f7bed0fdd1a3f742c0e663b36a795f9dc7411161dc22bdae1245e
 F src/pragma.c c7ada272232e1182c4536d9637fa7b955a10bc1bd8d5a87d4dc9309dab827791
 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126
-F src/printf.c 41f5ccdec1d9db821903e37181b9bf5ecc07748e4b48d99f830edb6433971187
+F src/printf.c 743e31d168ad01ecc93a7303c07ef5ac741c4b8342b88e7cda428dbd2b4d9844
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 626c24b258b111f75c22107aa5614ad89810df3026f5ca071116d3fe75925c75
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
@@ -2210,8 +2210,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7cc302de05ed2a973372c05f55b048bf99af3d2590dd29f6fd0f379fb451aa0e
-R 4bc2cfded966113e2805f8612a2c2a29
+P ffbfcc2bbb57f02aa5ee813e7a25a2a014e3353a10f6bccb609075a5b63545d7
+R b7621246db8a84c2bec12427fadf6f60
 U drh
-Z 4e1c6c3e8807d851d73b039b2ed1c034
+Z bdb58a5a11dd9515f24e08ce18cb765e
 # Remove this line to create a well-formed Fossil manifest.
index 6d9422e694c3c59b50db011a1a14a44eb5fefea9..24c7fa98d02ae2d1c30e76a86eb0352fb23941fd 100644 (file)
@@ -1 +1 @@
-ffbfcc2bbb57f02aa5ee813e7a25a2a014e3353a10f6bccb609075a5b63545d7
+997391d42079783e294836f714ccd9526ecc442c8dbf8212d72cd17c67e7158a
index 4f4072243dac5ee3f09b562428673b8018fce44f..2b4ccf259dcce13599fe056611dcc4f11b691eaf 100644 (file)
 #define etPERCENT     7 /* Percent symbol. %% */
 #define etCHARX       8 /* Characters. %c */
 /* The rest are extensions, not normally found in printf() */
-#define etSQLESCAPE   9 /* Strings with '\'' doubled.  %q */
-#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '',
-                          NULL pointers replaced by SQL NULL.  %Q */
-#define etTOKEN      11 /* a pointer to a Token structure */
-#define etSRCITEM    12 /* a pointer to a SrcItem */
-#define etPOINTER    13 /* The %p conversion */
-#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
-#define etORDINAL    15 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
-#define etDECIMAL    16 /* %d or %u, but not %x, %o */
+#define etESCAPE_q    9  /* Strings with '\'' doubled.  %q */
+#define etESCAPE_Q    10 /* Strings with '\'' doubled and enclosed in '',
+                            NULL pointers replaced by SQL NULL.  %Q */
+#define etTOKEN       11 /* a pointer to a Token structure */
+#define etSRCITEM     12 /* a pointer to a SrcItem */
+#define etPOINTER     13 /* The %p conversion */
+#define etESCAPE_w    14 /* %w -> Strings with '\"' doubled */
+#define etORDINAL     15 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
+#define etDECIMAL     16 /* %d or %u, but not %x, %o */
 
-#define etINVALID    17 /* Any unrecognized conversion type */
+#define etINVALID     17 /* Any unrecognized conversion type */
 
 
 /*
@@ -74,9 +74,9 @@ static const et_info fmtinfo[] = {
   {  's',  0, 4, etSTRING,     0,  0 },
   {  'g',  0, 1, etGENERIC,    30, 0 },
   {  'z',  0, 4, etDYNSTRING,  0,  0 },
-  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
-  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
-  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
+  {  'q',  0, 4, etESCAPE_q,   0,  0 },
+  {  'Q',  0, 4, etESCAPE_Q,   0,  0 },
+  {  'w',  0, 4, etESCAPE_w,   0,  0 },
   {  'c',  0, 0, etCHARX,      0,  0 },
   {  'o',  8, 0, etRADIX,      0,  2 },
   {  'u', 10, 0, etDECIMAL,    0,  0 },
@@ -771,14 +771,14 @@ void sqlite3_str_vappendf(
           while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
         }
         break;
-      case etSQLESCAPE:           /* %q: Escape ' characters */
-      case etSQLESCAPE2:          /* %Q: Escape ' and enclose in '...' */
-      case etSQLESCAPE3: {        /* %w: Escape " characters */
+      case etESCAPE_q:          /* %q: Escape ' characters */
+      case etESCAPE_Q:          /* %Q: Escape ' and enclose in '...' */
+      case etESCAPE_w: {        /* %w: Escape " characters */
         i64 i, j, k, n;
-        int needQuote, isnull;
+        int isnull, needQuote = 0;
         char ch;
-        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
         char *escarg;
+        char q;
 
         if( bArgList ){
           escarg = getTextArg(pArgList);
@@ -786,7 +786,17 @@ void sqlite3_str_vappendf(
           escarg = va_arg(ap,char*);
         }
         isnull = escarg==0;
-        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
+        if( xtype==etESCAPE_w ){
+          q = '"';
+          flag_alternateform = 0;
+        }else{
+          q = '\'';
+        }
+        if( isnull ){
+          escarg = (xtype==etESCAPE_Q ? "NULL" : "(NULL)");
+        }else if( xtype==etESCAPE_Q ){
+          needQuote = 1;
+        }
         /* For %q, %Q, and %w, the precision is the number of bytes (or
         ** characters if the ! flags is present) to use from the input.
         ** Because of the extra quoting characters inserted, the number
@@ -800,17 +810,29 @@ void sqlite3_str_vappendf(
           }
         }
         if( flag_alternateform ){
-          /* for %#q, %#Q, and %#w, do unistr()-style backslash escapes for
-          ** all control characters, and for backslash itself */
+          /* For %#q, do unistr()-style backslash escapes for
+          ** all control characters, and for backslash itself.
+          ** For %#Q, do the same but only if there is at least
+          ** one control character. */
+          u32 nBack = 0;
+          u32 nCtrl = 0;
           for(k=0; k<i; k++){
             if( escarg[k]=='\\' ){
-              n++;
+              nBack++;
             }else if( escarg[k]<=0x1f ){
-              n += 4;
+              nCtrl++;
+            }
+          }
+          if( nCtrl || xtype==etESCAPE_q ){
+            n += nBack + 5*nCtrl;
+            if( xtype==etESCAPE_Q ){
+              n += 10;
+              needQuote = 2;
             }
+          }else{
+            flag_alternateform = 0;
           }
         }
-        needQuote = !isnull && xtype==etSQLESCAPE2;
         n += i + 3;
         if( n>etBUFSIZE ){
           bufpt = zExtra = printfTempBuf(pAccum, n);
@@ -819,7 +841,14 @@ void sqlite3_str_vappendf(
           bufpt = buf;
         }
         j = 0;
-        if( needQuote ) bufpt[j++] = q;
+        if( needQuote ){
+          if( needQuote==2 ){
+            memcpy(&bufpt[j], "unistr('", 8);
+            j += 8;
+          }else{
+            bufpt[j++] = '\'';
+          }
+        }
         k = i;
         for(i=0; i<k; i++){
           bufpt[j++] = ch = escarg[i];
@@ -830,6 +859,7 @@ void sqlite3_str_vappendf(
               bufpt[j++] = '\\';
             }else if( ch<=0x1f ){
               bufpt[j-1] = '\\';
+              bufpt[j++] = 'u';
               bufpt[j++] = '0';
               bufpt[j++] = '0';
               bufpt[j++] = ch>=0x10 ? '1' : '0';
@@ -837,7 +867,10 @@ void sqlite3_str_vappendf(
             }
           }
         }
-        if( needQuote ) bufpt[j++] = q;
+        if( needQuote ){
+          bufpt[j++] = '\'';
+          if( needQuote==2 ) bufpt[j++] = ')';
+        }
         bufpt[j] = 0;
         length = j;
         goto adjust_width_for_utf8;