| | @@ -525,10 +525,11 @@ |
| 525 | 525 | sqlite3 *db; /* The database */ |
| 526 | 526 | int echoOn; /* True to echo input commands */ |
| 527 | 527 | int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ |
| 528 | 528 | int statsOn; /* True to display memory stats before each finalize */ |
| 529 | 529 | int scanstatsOn; /* True to display scan stats before each finalize */ |
| 530 | + int backslashOn; /* Resolve C-style \x escapes in SQL input text */ |
| 530 | 531 | int outCount; /* Revert to stdout when reaching zero */ |
| 531 | 532 | int cnt; /* Number of records displayed so far */ |
| 532 | 533 | FILE *out; /* Write results here */ |
| 533 | 534 | FILE *traceOut; /* Output for sqlite3_trace() */ |
| 534 | 535 | int nErr; /* Number of errors seen */ |
| | @@ -1942,11 +1943,11 @@ |
| 1942 | 1943 | static void resolve_backslashes(char *z){ |
| 1943 | 1944 | int i, j; |
| 1944 | 1945 | char c; |
| 1945 | 1946 | while( *z && *z!='\\' ) z++; |
| 1946 | 1947 | for(i=j=0; (c = z[i])!=0; i++, j++){ |
| 1947 | | - if( c=='\\' ){ |
| 1948 | + if( c=='\\' && z[i+1]!=0 ){ |
| 1948 | 1949 | c = z[++i]; |
| 1949 | 1950 | if( c=='n' ){ |
| 1950 | 1951 | c = '\n'; |
| 1951 | 1952 | }else if( c=='t' ){ |
| 1952 | 1953 | c = '\t'; |
| | @@ -4109,10 +4110,11 @@ |
| 4109 | 4110 | } |
| 4110 | 4111 | if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) |
| 4111 | 4112 | && sqlite3_complete(zSql) ){ |
| 4112 | 4113 | p->cnt = 0; |
| 4113 | 4114 | open_db(p, 0); |
| 4115 | + if( p->backslashOn ) resolve_backslashes(zSql); |
| 4114 | 4116 | BEGIN_TIMER; |
| 4115 | 4117 | rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); |
| 4116 | 4118 | END_TIMER; |
| 4117 | 4119 | if( rc || zErrMsg ){ |
| 4118 | 4120 | char zPrefix[100]; |
| | @@ -4575,10 +4577,17 @@ |
| 4575 | 4577 | data.autoEQP = 1; |
| 4576 | 4578 | }else if( strcmp(z,"-stats")==0 ){ |
| 4577 | 4579 | data.statsOn = 1; |
| 4578 | 4580 | }else if( strcmp(z,"-scanstats")==0 ){ |
| 4579 | 4581 | data.scanstatsOn = 1; |
| 4582 | + }else if( strcmp(z,"-backslash")==0 ){ |
| 4583 | + /* Undocumented command-line option: -backslash |
| 4584 | + ** Causes C-style backslash escapes to be evaluated in SQL statements |
| 4585 | + ** prior to sending the SQL into SQLite. Useful for injecting |
| 4586 | + ** crazy bytes in the middle of SQL statements for testing and debugging. |
| 4587 | + */ |
| 4588 | + data.backslashOn = 1; |
| 4580 | 4589 | }else if( strcmp(z,"-bail")==0 ){ |
| 4581 | 4590 | bail_on_error = 1; |
| 4582 | 4591 | }else if( strcmp(z,"-version")==0 ){ |
| 4583 | 4592 | printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); |
| 4584 | 4593 | return 0; |
| 4585 | 4594 | |