Fossil SCM

Enhance the blob_append_escaped_args() routine with a new parameter to indicate if the argument is a filename. Only prepend "./" to filename arguments that begin with "-". The "%$" printf conversion assumes a filename, but the "%!$" conversion does not.

drh 2021-06-30 13:52 trunk
Commit 4f83d06275804a8320e79fd90df1cc990fb4fd23a2b54b85927609f5f9c4efbc
--- src/backoffice.c
+++ src/backoffice.c
@@ -754,11 +754,11 @@
754754
&& (nMin<=0 || aLastRun[i]+nMin>iNow)
755755
){
756756
continue; /* Not yet time to run this one */
757757
}
758758
blob_init(&cmd, 0, 0);
759
- blob_append_escaped_arg(&cmd, g.nameOfExe);
759
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
760760
blob_append(&cmd, " backoffice --nodelay", -1);
761761
if( g.fAnyTrace ){
762762
blob_append(&cmd, " --trace", -1);
763763
}
764764
if( bDebug ){
@@ -767,13 +767,13 @@
767767
if( nPoll>0 ){
768768
blob_append(&cmd, " --nolease", -1);
769769
}
770770
if( backofficeLogfile ){
771771
blob_append(&cmd, " --logfile", -1);
772
- blob_append_escaped_arg(&cmd, backofficeLogfile);
772
+ blob_append_escaped_arg(&cmd, backofficeLogfile, 1);
773773
}
774
- blob_append_escaped_arg(&cmd, g.argv[i]);
774
+ blob_append_escaped_arg(&cmd, g.argv[i], 1);
775775
nCmd++;
776776
if( bDebug ){
777777
fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
778778
}
779779
fossil_system(blob_str(&cmd));
780780
--- src/backoffice.c
+++ src/backoffice.c
@@ -754,11 +754,11 @@
754 && (nMin<=0 || aLastRun[i]+nMin>iNow)
755 ){
756 continue; /* Not yet time to run this one */
757 }
758 blob_init(&cmd, 0, 0);
759 blob_append_escaped_arg(&cmd, g.nameOfExe);
760 blob_append(&cmd, " backoffice --nodelay", -1);
761 if( g.fAnyTrace ){
762 blob_append(&cmd, " --trace", -1);
763 }
764 if( bDebug ){
@@ -767,13 +767,13 @@
767 if( nPoll>0 ){
768 blob_append(&cmd, " --nolease", -1);
769 }
770 if( backofficeLogfile ){
771 blob_append(&cmd, " --logfile", -1);
772 blob_append_escaped_arg(&cmd, backofficeLogfile);
773 }
774 blob_append_escaped_arg(&cmd, g.argv[i]);
775 nCmd++;
776 if( bDebug ){
777 fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
778 }
779 fossil_system(blob_str(&cmd));
780
--- src/backoffice.c
+++ src/backoffice.c
@@ -754,11 +754,11 @@
754 && (nMin<=0 || aLastRun[i]+nMin>iNow)
755 ){
756 continue; /* Not yet time to run this one */
757 }
758 blob_init(&cmd, 0, 0);
759 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
760 blob_append(&cmd, " backoffice --nodelay", -1);
761 if( g.fAnyTrace ){
762 blob_append(&cmd, " --trace", -1);
763 }
764 if( bDebug ){
@@ -767,13 +767,13 @@
767 if( nPoll>0 ){
768 blob_append(&cmd, " --nolease", -1);
769 }
770 if( backofficeLogfile ){
771 blob_append(&cmd, " --logfile", -1);
772 blob_append_escaped_arg(&cmd, backofficeLogfile, 1);
773 }
774 blob_append_escaped_arg(&cmd, g.argv[i], 1);
775 nCmd++;
776 if( bDebug ){
777 fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
778 }
779 fossil_system(blob_str(&cmd));
780
+1 -1
--- src/bisect.c
+++ src/bisect.c
@@ -411,11 +411,11 @@
411411
}
412412
while( db_lget_int("bisect-complete",0)==0 ){
413413
int rc;
414414
Blob cmd;
415415
blob_init(&cmd, 0, 0);
416
- blob_append_escaped_arg(&cmd, g.nameOfExe);
416
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
417417
rc = fossil_unsafe_system(zCmd);
418418
if( isInteractive ){
419419
Blob in;
420420
fossil_print("test-command result: %d\n", rc);
421421
while(1){
422422
--- src/bisect.c
+++ src/bisect.c
@@ -411,11 +411,11 @@
411 }
412 while( db_lget_int("bisect-complete",0)==0 ){
413 int rc;
414 Blob cmd;
415 blob_init(&cmd, 0, 0);
416 blob_append_escaped_arg(&cmd, g.nameOfExe);
417 rc = fossil_unsafe_system(zCmd);
418 if( isInteractive ){
419 Blob in;
420 fossil_print("test-command result: %d\n", rc);
421 while(1){
422
--- src/bisect.c
+++ src/bisect.c
@@ -411,11 +411,11 @@
411 }
412 while( db_lget_int("bisect-complete",0)==0 ){
413 int rc;
414 Blob cmd;
415 blob_init(&cmd, 0, 0);
416 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
417 rc = fossil_unsafe_system(zCmd);
418 if( isInteractive ){
419 Blob in;
420 fossil_print("test-command result: %d\n", rc);
421 while(1){
422
+27 -11
--- src/blob.c
+++ src/blob.c
@@ -1367,17 +1367,18 @@
13671367
**
13681368
** The argument is escaped if it contains white space or other characters
13691369
** that need to be escaped for the shell. If zIn contains characters
13701370
** that cannot be safely escaped, then throw a fatal error.
13711371
**
1372
-** The argument is expected to be a filename. As shell commands
1373
-** commonly have command-line options that begin with "-" and since we
1374
-** do not want an attacker to be able to invoke these switches using
1375
-** filenames that begin with "-", if zIn begins with "-", prepend
1376
-** an additional "./" (or ".\\" on Windows).
1372
+** If the isFilename argument is true, then the argument is expected
1373
+** to be a filename. As shell commands commonly have command-line
1374
+** options that begin with "-" and since we do not want an attacker
1375
+** to be able to invoke these switches using filenames that begin
1376
+** with "-", if zIn begins with "-", prepend an additional "./"
1377
+** (or ".\\" on Windows).
13771378
*/
1378
-void blob_append_escaped_arg(Blob *pBlob, const char *zIn){
1379
+void blob_append_escaped_arg(Blob *pBlob, const char *zIn, int isFilename){
13791380
int i;
13801381
unsigned char c;
13811382
int needEscape = 0;
13821383
int n = blob_size(pBlob);
13831384
char *z = blob_buffer(pBlob);
@@ -1418,11 +1419,11 @@
14181419
blob_append_char(pBlob, ' ');
14191420
}
14201421
14211422
/* Check for characters that need quoting */
14221423
if( !needEscape ){
1423
- if( zIn[0]=='-' ){
1424
+ if( isFilename && zIn[0]=='-' ){
14241425
blob_append_char(pBlob, '.');
14251426
#if defined(_WIN32)
14261427
blob_append_char(pBlob, '\\');
14271428
#else
14281429
blob_append_char(pBlob, '/');
@@ -1434,11 +1435,11 @@
14341435
/* Quoting strategy for windows:
14351436
** Put the entire name inside of "...". Any " characters within
14361437
** the name get doubled.
14371438
*/
14381439
blob_append_char(pBlob, '"');
1439
- if( zIn[0]=='-' ){
1440
+ if( isFilename && zIn[0]=='-' ){
14401441
blob_append_char(pBlob, '.');
14411442
blob_append_char(pBlob, '\\');
14421443
}else if( zIn[0]=='/' ){
14431444
blob_append_char(pBlob, '.');
14441445
}
@@ -1452,21 +1453,21 @@
14521453
** If the name does not contain ', then surround the whole thing
14531454
** with '...'. If there is one or more ' characters within the
14541455
** name, then put \ before each special character.
14551456
*/
14561457
if( strchr(zIn,'\'') ){
1457
- if( zIn[0]=='-' ){
1458
+ if( isFilename && zIn[0]=='-' ){
14581459
blob_append_char(pBlob, '.');
14591460
blob_append_char(pBlob, '/');
14601461
}
14611462
for(i=0; (c = (unsigned char)zIn[i])!=0; i++){
14621463
if( aSafeChar[c] && aSafeChar[c]!=2 ) blob_append_char(pBlob, '\\');
14631464
blob_append_char(pBlob, (char)c);
14641465
}
14651466
}else{
14661467
blob_append_char(pBlob, '\'');
1467
- if( zIn[0]=='-' ){
1468
+ if( isFilename && zIn[0]=='-' ){
14681469
blob_append_char(pBlob, '.');
14691470
blob_append_char(pBlob, '/');
14701471
}
14711472
blob_append(pBlob, zIn, -1);
14721473
blob_append_char(pBlob, '\'');
@@ -1484,10 +1485,14 @@
14841485
** result. Append each argument to "fossil test-echo" and run that
14851486
** using fossil_system() to verify that it really does get escaped
14861487
** correctly.
14871488
**
14881489
** Other options:
1490
+**
1491
+** --filename-args BOOL Subsequent arguments are assumed to be
1492
+** filenames if BOOL is true, or not if BOOL
1493
+** is false. Defaults on.
14891494
**
14901495
** --hex HEX Skip the --hex flag and instead decode HEX
14911496
** into ascii. This provides a way to insert
14921497
** unusual characters as an argument for testing.
14931498
**
@@ -1501,10 +1506,11 @@
15011506
*/
15021507
void test_escaped_arg_command(void){
15031508
int i;
15041509
Blob x;
15051510
const char *zArg;
1511
+ int isFilename = 1;
15061512
char zBuf[100];
15071513
blob_init(&x, 0, 0);
15081514
for(i=2; i<g.argc; i++){
15091515
zArg = g.argv[i];
15101516
if( fossil_strcmp(zArg, "--hex")==0 && i+1<g.argc ){
@@ -1586,13 +1592,23 @@
15861592
rc = fossil_system(blob_str(&x));
15871593
if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x));
15881594
blob_reset(&x);
15891595
}
15901596
continue;
1597
+ }else if( fossil_strcmp(zArg, "--filename-args")==0 ){
1598
+ if( i+1<g.argc ){
1599
+ i++;
1600
+ isFilename = is_truth(g.argv[i]);
1601
+ }
1602
+ continue;
15911603
}
15921604
fossil_print("%3d [%s]: ", i, zArg);
1593
- blob_appendf(&x, "%$ test-echo %$", g.nameOfExe, zArg);
1605
+ if( isFilename ){
1606
+ blob_appendf(&x, "%$ test-echo %$", g.nameOfExe, zArg);
1607
+ }else{
1608
+ blob_appendf(&x, "%$ test-echo %!$", g.nameOfExe, zArg);
1609
+ }
15941610
fossil_print("%s\n", blob_str(&x));
15951611
fossil_system(blob_str(&x));
15961612
blob_reset(&x);
15971613
}
15981614
}
15991615
--- src/blob.c
+++ src/blob.c
@@ -1367,17 +1367,18 @@
1367 **
1368 ** The argument is escaped if it contains white space or other characters
1369 ** that need to be escaped for the shell. If zIn contains characters
1370 ** that cannot be safely escaped, then throw a fatal error.
1371 **
1372 ** The argument is expected to be a filename. As shell commands
1373 ** commonly have command-line options that begin with "-" and since we
1374 ** do not want an attacker to be able to invoke these switches using
1375 ** filenames that begin with "-", if zIn begins with "-", prepend
1376 ** an additional "./" (or ".\\" on Windows).
 
1377 */
1378 void blob_append_escaped_arg(Blob *pBlob, const char *zIn){
1379 int i;
1380 unsigned char c;
1381 int needEscape = 0;
1382 int n = blob_size(pBlob);
1383 char *z = blob_buffer(pBlob);
@@ -1418,11 +1419,11 @@
1418 blob_append_char(pBlob, ' ');
1419 }
1420
1421 /* Check for characters that need quoting */
1422 if( !needEscape ){
1423 if( zIn[0]=='-' ){
1424 blob_append_char(pBlob, '.');
1425 #if defined(_WIN32)
1426 blob_append_char(pBlob, '\\');
1427 #else
1428 blob_append_char(pBlob, '/');
@@ -1434,11 +1435,11 @@
1434 /* Quoting strategy for windows:
1435 ** Put the entire name inside of "...". Any " characters within
1436 ** the name get doubled.
1437 */
1438 blob_append_char(pBlob, '"');
1439 if( zIn[0]=='-' ){
1440 blob_append_char(pBlob, '.');
1441 blob_append_char(pBlob, '\\');
1442 }else if( zIn[0]=='/' ){
1443 blob_append_char(pBlob, '.');
1444 }
@@ -1452,21 +1453,21 @@
1452 ** If the name does not contain ', then surround the whole thing
1453 ** with '...'. If there is one or more ' characters within the
1454 ** name, then put \ before each special character.
1455 */
1456 if( strchr(zIn,'\'') ){
1457 if( zIn[0]=='-' ){
1458 blob_append_char(pBlob, '.');
1459 blob_append_char(pBlob, '/');
1460 }
1461 for(i=0; (c = (unsigned char)zIn[i])!=0; i++){
1462 if( aSafeChar[c] && aSafeChar[c]!=2 ) blob_append_char(pBlob, '\\');
1463 blob_append_char(pBlob, (char)c);
1464 }
1465 }else{
1466 blob_append_char(pBlob, '\'');
1467 if( zIn[0]=='-' ){
1468 blob_append_char(pBlob, '.');
1469 blob_append_char(pBlob, '/');
1470 }
1471 blob_append(pBlob, zIn, -1);
1472 blob_append_char(pBlob, '\'');
@@ -1484,10 +1485,14 @@
1484 ** result. Append each argument to "fossil test-echo" and run that
1485 ** using fossil_system() to verify that it really does get escaped
1486 ** correctly.
1487 **
1488 ** Other options:
 
 
 
 
1489 **
1490 ** --hex HEX Skip the --hex flag and instead decode HEX
1491 ** into ascii. This provides a way to insert
1492 ** unusual characters as an argument for testing.
1493 **
@@ -1501,10 +1506,11 @@
1501 */
1502 void test_escaped_arg_command(void){
1503 int i;
1504 Blob x;
1505 const char *zArg;
 
1506 char zBuf[100];
1507 blob_init(&x, 0, 0);
1508 for(i=2; i<g.argc; i++){
1509 zArg = g.argv[i];
1510 if( fossil_strcmp(zArg, "--hex")==0 && i+1<g.argc ){
@@ -1586,13 +1592,23 @@
1586 rc = fossil_system(blob_str(&x));
1587 if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x));
1588 blob_reset(&x);
1589 }
1590 continue;
 
 
 
 
 
 
1591 }
1592 fossil_print("%3d [%s]: ", i, zArg);
1593 blob_appendf(&x, "%$ test-echo %$", g.nameOfExe, zArg);
 
 
 
 
1594 fossil_print("%s\n", blob_str(&x));
1595 fossil_system(blob_str(&x));
1596 blob_reset(&x);
1597 }
1598 }
1599
--- src/blob.c
+++ src/blob.c
@@ -1367,17 +1367,18 @@
1367 **
1368 ** The argument is escaped if it contains white space or other characters
1369 ** that need to be escaped for the shell. If zIn contains characters
1370 ** that cannot be safely escaped, then throw a fatal error.
1371 **
1372 ** If the isFilename argument is true, then the argument is expected
1373 ** to be a filename. As shell commands commonly have command-line
1374 ** options that begin with "-" and since we do not want an attacker
1375 ** to be able to invoke these switches using filenames that begin
1376 ** with "-", if zIn begins with "-", prepend an additional "./"
1377 ** (or ".\\" on Windows).
1378 */
1379 void blob_append_escaped_arg(Blob *pBlob, const char *zIn, int isFilename){
1380 int i;
1381 unsigned char c;
1382 int needEscape = 0;
1383 int n = blob_size(pBlob);
1384 char *z = blob_buffer(pBlob);
@@ -1418,11 +1419,11 @@
1419 blob_append_char(pBlob, ' ');
1420 }
1421
1422 /* Check for characters that need quoting */
1423 if( !needEscape ){
1424 if( isFilename && zIn[0]=='-' ){
1425 blob_append_char(pBlob, '.');
1426 #if defined(_WIN32)
1427 blob_append_char(pBlob, '\\');
1428 #else
1429 blob_append_char(pBlob, '/');
@@ -1434,11 +1435,11 @@
1435 /* Quoting strategy for windows:
1436 ** Put the entire name inside of "...". Any " characters within
1437 ** the name get doubled.
1438 */
1439 blob_append_char(pBlob, '"');
1440 if( isFilename && zIn[0]=='-' ){
1441 blob_append_char(pBlob, '.');
1442 blob_append_char(pBlob, '\\');
1443 }else if( zIn[0]=='/' ){
1444 blob_append_char(pBlob, '.');
1445 }
@@ -1452,21 +1453,21 @@
1453 ** If the name does not contain ', then surround the whole thing
1454 ** with '...'. If there is one or more ' characters within the
1455 ** name, then put \ before each special character.
1456 */
1457 if( strchr(zIn,'\'') ){
1458 if( isFilename && zIn[0]=='-' ){
1459 blob_append_char(pBlob, '.');
1460 blob_append_char(pBlob, '/');
1461 }
1462 for(i=0; (c = (unsigned char)zIn[i])!=0; i++){
1463 if( aSafeChar[c] && aSafeChar[c]!=2 ) blob_append_char(pBlob, '\\');
1464 blob_append_char(pBlob, (char)c);
1465 }
1466 }else{
1467 blob_append_char(pBlob, '\'');
1468 if( isFilename && zIn[0]=='-' ){
1469 blob_append_char(pBlob, '.');
1470 blob_append_char(pBlob, '/');
1471 }
1472 blob_append(pBlob, zIn, -1);
1473 blob_append_char(pBlob, '\'');
@@ -1484,10 +1485,14 @@
1485 ** result. Append each argument to "fossil test-echo" and run that
1486 ** using fossil_system() to verify that it really does get escaped
1487 ** correctly.
1488 **
1489 ** Other options:
1490 **
1491 ** --filename-args BOOL Subsequent arguments are assumed to be
1492 ** filenames if BOOL is true, or not if BOOL
1493 ** is false. Defaults on.
1494 **
1495 ** --hex HEX Skip the --hex flag and instead decode HEX
1496 ** into ascii. This provides a way to insert
1497 ** unusual characters as an argument for testing.
1498 **
@@ -1501,10 +1506,11 @@
1506 */
1507 void test_escaped_arg_command(void){
1508 int i;
1509 Blob x;
1510 const char *zArg;
1511 int isFilename = 1;
1512 char zBuf[100];
1513 blob_init(&x, 0, 0);
1514 for(i=2; i<g.argc; i++){
1515 zArg = g.argv[i];
1516 if( fossil_strcmp(zArg, "--hex")==0 && i+1<g.argc ){
@@ -1586,13 +1592,23 @@
1592 rc = fossil_system(blob_str(&x));
1593 if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x));
1594 blob_reset(&x);
1595 }
1596 continue;
1597 }else if( fossil_strcmp(zArg, "--filename-args")==0 ){
1598 if( i+1<g.argc ){
1599 i++;
1600 isFilename = is_truth(g.argv[i]);
1601 }
1602 continue;
1603 }
1604 fossil_print("%3d [%s]: ", i, zArg);
1605 if( isFilename ){
1606 blob_appendf(&x, "%$ test-echo %$", g.nameOfExe, zArg);
1607 }else{
1608 blob_appendf(&x, "%$ test-echo %!$", g.nameOfExe, zArg);
1609 }
1610 fossil_print("%s\n", blob_str(&x));
1611 fossil_system(blob_str(&x));
1612 blob_reset(&x);
1613 }
1614 }
1615
+3 -3
--- src/clone.c
+++ src/clone.c
@@ -290,15 +290,15 @@
290290
if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
291291
Blob cmd;
292292
fossil_print("opening the new %s repository in directory %s...\n",
293293
zRepo, zWorkDir);
294294
blob_init(&cmd, 0, 0);
295
- blob_append_escaped_arg(&cmd, g.nameOfExe);
295
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
296296
blob_append(&cmd, " open ", -1);
297
- blob_append_escaped_arg(&cmd, zRepo);
297
+ blob_append_escaped_arg(&cmd, zRepo, 1);
298298
blob_append(&cmd, " --workdir ", -1);
299
- blob_append_escaped_arg(&cmd, zWorkDir);
299
+ blob_append_escaped_arg(&cmd, zWorkDir, 1);
300300
if( allowNested ){
301301
blob_append(&cmd, " --nested", -1);
302302
}
303303
fossil_system(blob_str(&cmd));
304304
blob_reset(&cmd);
305305
--- src/clone.c
+++ src/clone.c
@@ -290,15 +290,15 @@
290 if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
291 Blob cmd;
292 fossil_print("opening the new %s repository in directory %s...\n",
293 zRepo, zWorkDir);
294 blob_init(&cmd, 0, 0);
295 blob_append_escaped_arg(&cmd, g.nameOfExe);
296 blob_append(&cmd, " open ", -1);
297 blob_append_escaped_arg(&cmd, zRepo);
298 blob_append(&cmd, " --workdir ", -1);
299 blob_append_escaped_arg(&cmd, zWorkDir);
300 if( allowNested ){
301 blob_append(&cmd, " --nested", -1);
302 }
303 fossil_system(blob_str(&cmd));
304 blob_reset(&cmd);
305
--- src/clone.c
+++ src/clone.c
@@ -290,15 +290,15 @@
290 if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
291 Blob cmd;
292 fossil_print("opening the new %s repository in directory %s...\n",
293 zRepo, zWorkDir);
294 blob_init(&cmd, 0, 0);
295 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
296 blob_append(&cmd, " open ", -1);
297 blob_append_escaped_arg(&cmd, zRepo, 1);
298 blob_append(&cmd, " --workdir ", -1);
299 blob_append_escaped_arg(&cmd, zWorkDir, 1);
300 if( allowNested ){
301 blob_append(&cmd, " --nested", -1);
302 }
303 fossil_system(blob_str(&cmd));
304 blob_reset(&cmd);
305
+3 -3
--- src/db.c
+++ src/db.c
@@ -3599,14 +3599,14 @@
35993599
}
36003600
if( zRepoDir==0 ) zRepoDir = zPwd;
36013601
zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
36023602
fossil_free(zNewBase);
36033603
blob_init(&cmd, 0, 0);
3604
- blob_append_escaped_arg(&cmd, g.nameOfExe);
3604
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
36053605
blob_append(&cmd, " clone", -1);
3606
- blob_append_escaped_arg(&cmd, zUri);
3607
- blob_append_escaped_arg(&cmd, zRepo);
3606
+ blob_append_escaped_arg(&cmd, zUri, 1);
3607
+ blob_append_escaped_arg(&cmd, zRepo, 1);
36083608
zCmd = blob_str(&cmd);
36093609
fossil_print("%s\n", zCmd);
36103610
if( zWorkDir ) file_chdir(zPwd, 0);
36113611
rc = fossil_system(zCmd);
36123612
if( rc ){
36133613
--- src/db.c
+++ src/db.c
@@ -3599,14 +3599,14 @@
3599 }
3600 if( zRepoDir==0 ) zRepoDir = zPwd;
3601 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3602 fossil_free(zNewBase);
3603 blob_init(&cmd, 0, 0);
3604 blob_append_escaped_arg(&cmd, g.nameOfExe);
3605 blob_append(&cmd, " clone", -1);
3606 blob_append_escaped_arg(&cmd, zUri);
3607 blob_append_escaped_arg(&cmd, zRepo);
3608 zCmd = blob_str(&cmd);
3609 fossil_print("%s\n", zCmd);
3610 if( zWorkDir ) file_chdir(zPwd, 0);
3611 rc = fossil_system(zCmd);
3612 if( rc ){
3613
--- src/db.c
+++ src/db.c
@@ -3599,14 +3599,14 @@
3599 }
3600 if( zRepoDir==0 ) zRepoDir = zPwd;
3601 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3602 fossil_free(zNewBase);
3603 blob_init(&cmd, 0, 0);
3604 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
3605 blob_append(&cmd, " clone", -1);
3606 blob_append_escaped_arg(&cmd, zUri, 1);
3607 blob_append_escaped_arg(&cmd, zRepo, 1);
3608 zCmd = blob_str(&cmd);
3609 fossil_print("%s\n", zCmd);
3610 if( zWorkDir ) file_chdir(zPwd, 0);
3611 rc = fossil_system(zCmd);
3612 if( rc ){
3613
+6 -6
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,15 +271,15 @@
271271
272272
/* Construct the external diff command */
273273
blob_zero(&cmd);
274274
blob_append(&cmd, zDiffCmd, -1);
275275
if( fSwapDiff ){
276
- blob_append_escaped_arg(&cmd, zFile2);
277
- blob_append_escaped_arg(&cmd, blob_str(&nameFile1));
276
+ blob_append_escaped_arg(&cmd, zFile2, 1);
277
+ blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
278278
}else{
279
- blob_append_escaped_arg(&cmd, blob_str(&nameFile1));
280
- blob_append_escaped_arg(&cmd, zFile2);
279
+ blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
280
+ blob_append_escaped_arg(&cmd, zFile2, 1);
281281
}
282282
283283
/* Run the external diff command */
284284
fossil_system(blob_str(&cmd));
285285
@@ -357,12 +357,12 @@
357357
blob_write_to_file(pFile2, blob_str(&temp2));
358358
359359
/* Construct the external diff command */
360360
blob_zero(&cmd);
361361
blob_append(&cmd, zDiffCmd, -1);
362
- blob_append_escaped_arg(&cmd, blob_str(&temp1));
363
- blob_append_escaped_arg(&cmd, blob_str(&temp2));
362
+ blob_append_escaped_arg(&cmd, blob_str(&temp1), 1);
363
+ blob_append_escaped_arg(&cmd, blob_str(&temp2), 1);
364364
365365
/* Run the external diff command */
366366
fossil_system(blob_str(&cmd));
367367
368368
/* Delete the temporary file and clean up memory used */
369369
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,15 +271,15 @@
271
272 /* Construct the external diff command */
273 blob_zero(&cmd);
274 blob_append(&cmd, zDiffCmd, -1);
275 if( fSwapDiff ){
276 blob_append_escaped_arg(&cmd, zFile2);
277 blob_append_escaped_arg(&cmd, blob_str(&nameFile1));
278 }else{
279 blob_append_escaped_arg(&cmd, blob_str(&nameFile1));
280 blob_append_escaped_arg(&cmd, zFile2);
281 }
282
283 /* Run the external diff command */
284 fossil_system(blob_str(&cmd));
285
@@ -357,12 +357,12 @@
357 blob_write_to_file(pFile2, blob_str(&temp2));
358
359 /* Construct the external diff command */
360 blob_zero(&cmd);
361 blob_append(&cmd, zDiffCmd, -1);
362 blob_append_escaped_arg(&cmd, blob_str(&temp1));
363 blob_append_escaped_arg(&cmd, blob_str(&temp2));
364
365 /* Run the external diff command */
366 fossil_system(blob_str(&cmd));
367
368 /* Delete the temporary file and clean up memory used */
369
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,15 +271,15 @@
271
272 /* Construct the external diff command */
273 blob_zero(&cmd);
274 blob_append(&cmd, zDiffCmd, -1);
275 if( fSwapDiff ){
276 blob_append_escaped_arg(&cmd, zFile2, 1);
277 blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
278 }else{
279 blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
280 blob_append_escaped_arg(&cmd, zFile2, 1);
281 }
282
283 /* Run the external diff command */
284 fossil_system(blob_str(&cmd));
285
@@ -357,12 +357,12 @@
357 blob_write_to_file(pFile2, blob_str(&temp2));
358
359 /* Construct the external diff command */
360 blob_zero(&cmd);
361 blob_append(&cmd, zDiffCmd, -1);
362 blob_append_escaped_arg(&cmd, blob_str(&temp1), 1);
363 blob_append_escaped_arg(&cmd, blob_str(&temp2), 1);
364
365 /* Run the external diff command */
366 fossil_system(blob_str(&cmd));
367
368 /* Delete the temporary file and clean up memory used */
369
--- src/http_transport.c
+++ src/http_transport.c
@@ -122,25 +122,26 @@
122122
socket_ssh_resolve_addr(pUrlData);
123123
transport_ssh_command(&zCmd);
124124
if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
125125
blob_appendf(&zCmd, " -p %d", pUrlData->port);
126126
}
127
+ blob_appendf(&zCmd, " --"); /* End of switches */
127128
if( pUrlData->user && pUrlData->user[0] ){
128129
zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
129
- blob_append_escaped_arg(&zCmd, zHost);
130
+ blob_append_escaped_arg(&zCmd, zHost, 0);
130131
fossil_free(zHost);
131132
}else{
132
- blob_append_escaped_arg(&zCmd, pUrlData->name);
133
+ blob_append_escaped_arg(&zCmd, pUrlData->name, 0);
133134
}
134135
if( !is_safe_fossil_command(pUrlData->fossil) ){
135136
fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
136137
"the server.", pUrlData->fossil);
137138
}
138
- blob_append_escaped_arg(&zCmd, pUrlData->fossil);
139
+ blob_append_escaped_arg(&zCmd, pUrlData->fossil, 1);
139140
blob_append(&zCmd, " test-http", 10);
140141
if( pUrlData->path && pUrlData->path[0] ){
141
- blob_append_escaped_arg(&zCmd, pUrlData->path);
142
+ blob_append_escaped_arg(&zCmd, pUrlData->path, 1);
142143
}else{
143144
fossil_fatal("ssh:// URI does not specify a path to the repository");
144145
}
145146
if( g.fSshTrace ){
146147
fossil_print("%s\n", blob_str(&zCmd)); /* Show the whole SSH command */
147148
--- src/http_transport.c
+++ src/http_transport.c
@@ -122,25 +122,26 @@
122 socket_ssh_resolve_addr(pUrlData);
123 transport_ssh_command(&zCmd);
124 if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
125 blob_appendf(&zCmd, " -p %d", pUrlData->port);
126 }
 
127 if( pUrlData->user && pUrlData->user[0] ){
128 zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
129 blob_append_escaped_arg(&zCmd, zHost);
130 fossil_free(zHost);
131 }else{
132 blob_append_escaped_arg(&zCmd, pUrlData->name);
133 }
134 if( !is_safe_fossil_command(pUrlData->fossil) ){
135 fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
136 "the server.", pUrlData->fossil);
137 }
138 blob_append_escaped_arg(&zCmd, pUrlData->fossil);
139 blob_append(&zCmd, " test-http", 10);
140 if( pUrlData->path && pUrlData->path[0] ){
141 blob_append_escaped_arg(&zCmd, pUrlData->path);
142 }else{
143 fossil_fatal("ssh:// URI does not specify a path to the repository");
144 }
145 if( g.fSshTrace ){
146 fossil_print("%s\n", blob_str(&zCmd)); /* Show the whole SSH command */
147
--- src/http_transport.c
+++ src/http_transport.c
@@ -122,25 +122,26 @@
122 socket_ssh_resolve_addr(pUrlData);
123 transport_ssh_command(&zCmd);
124 if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
125 blob_appendf(&zCmd, " -p %d", pUrlData->port);
126 }
127 blob_appendf(&zCmd, " --"); /* End of switches */
128 if( pUrlData->user && pUrlData->user[0] ){
129 zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
130 blob_append_escaped_arg(&zCmd, zHost, 0);
131 fossil_free(zHost);
132 }else{
133 blob_append_escaped_arg(&zCmd, pUrlData->name, 0);
134 }
135 if( !is_safe_fossil_command(pUrlData->fossil) ){
136 fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
137 "the server.", pUrlData->fossil);
138 }
139 blob_append_escaped_arg(&zCmd, pUrlData->fossil, 1);
140 blob_append(&zCmd, " test-http", 10);
141 if( pUrlData->path && pUrlData->path[0] ){
142 blob_append_escaped_arg(&zCmd, pUrlData->path, 1);
143 }else{
144 fossil_fatal("ssh:// URI does not specify a path to the repository");
145 }
146 if( g.fSshTrace ){
147 fossil_print("%s\n", blob_str(&zCmd)); /* Show the whole SSH command */
148
+8 -8
--- src/patch.c
+++ src/patch.c
@@ -396,11 +396,11 @@
396396
" WHERE patch.cfg.key='baseline'"
397397
" AND localdb.vvar.name='checkout-hash'"
398398
" AND patch.cfg.key<>localdb.vvar.name"
399399
);
400400
if( db_step(&q)==SQLITE_ROW ){
401
- blob_append_escaped_arg(&cmd, g.nameOfExe);
401
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
402402
blob_appendf(&cmd, " update %s", db_column_text(&q, 0));
403403
if( mFlags & PATCH_VERBOSE ){
404404
fossil_print("%-10s %s\n", "BASELINE", db_column_text(&q,0));
405405
}
406406
}
@@ -423,11 +423,11 @@
423423
" WHERE type IN ('merge','cherrypick','backout','integrate')"
424424
" AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
425425
);
426426
while( db_step(&q)==SQLITE_ROW ){
427427
const char *zType = db_column_text(&q,0);
428
- blob_append_escaped_arg(&cmd, g.nameOfExe);
428
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
429429
if( strcmp(zType,"merge")==0 ){
430430
blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));
431431
}else{
432432
blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));
433433
}
@@ -451,11 +451,11 @@
451451
452452
/* Deletions */
453453
db_prepare(&q, "SELECT pathname FROM patch.chng"
454454
" WHERE origname IS NULL AND delta IS NULL");
455455
while( db_step(&q)==SQLITE_ROW ){
456
- blob_append_escaped_arg(&cmd, g.nameOfExe);
456
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
457457
blob_appendf(&cmd, " rm --hard %$\n", db_column_text(&q,0));
458458
if( mFlags & PATCH_VERBOSE ){
459459
fossil_print("%-10s %s\n", "DELETE", db_column_text(&q,0));
460460
}
461461
}
@@ -478,11 +478,11 @@
478478
"SELECT origname, pathname FROM patch.chng"
479479
" WHERE origname IS NOT NULL"
480480
" AND origname<>pathname"
481481
);
482482
while( db_step(&q)==SQLITE_ROW ){
483
- blob_append_escaped_arg(&cmd, g.nameOfExe);
483
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
484484
blob_appendf(&cmd, " mv --hard %$ %$\n",
485485
db_column_text(&q,0), db_column_text(&q,1));
486486
if( mFlags & PATCH_VERBOSE ){
487487
fossil_print("%-10s %s -> %s\n", "RENAME",
488488
db_column_text(&q,0), db_column_text(&q,1));
@@ -552,11 +552,11 @@
552552
sqlite3_free(aOut);
553553
if( mFlags & PATCH_VERBOSE ){
554554
fossil_print("%-10s %s\n", "EDIT", zPathname);
555555
}
556556
}else{
557
- blob_append_escaped_arg(&cmd, g.nameOfExe);
557
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
558558
blob_appendf(&cmd, " add %$\n", zPathname);
559559
if( mFlags & PATCH_VERBOSE ){
560560
fossil_print("%-10s %s\n", "NEW", zPathname);
561561
}
562562
}
@@ -673,22 +673,22 @@
673673
zRemote = fossil_strdup(g.argv[3]);
674674
zDir = strchr(zRemote,':');
675675
if( zDir==0 ){
676676
zDir = zRemote;
677677
blob_init(&cmd, 0, 0);
678
- blob_append_escaped_arg(&cmd, g.nameOfExe);
678
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
679679
blob_appendf(&cmd, " patch %s%s %$ -", zRemoteCmd, zForce, zDir);
680680
}else{
681681
Blob remote;
682682
zDir[0] = 0;
683683
zDir++;
684684
transport_ssh_command(&cmd);
685
- blob_append_escaped_arg(&cmd, zRemote);
685
+ blob_append_escaped_arg(&cmd, zRemote, 0);
686686
blob_init(&remote, 0, 0);
687687
blob_appendf(&remote, "fossil patch %s%s --dir64 %z -",
688688
zRemoteCmd, zForce, encode64(zDir, -1));
689
- blob_append_escaped_arg(&cmd, blob_str(&remote));
689
+ blob_append_escaped_arg(&cmd, blob_str(&remote), 0);
690690
blob_reset(&remote);
691691
}
692692
if( mFlags & PATCH_VERBOSE ){
693693
fossil_print("# %s\n", blob_str(&cmd));
694694
fflush(stdout);
695695
--- src/patch.c
+++ src/patch.c
@@ -396,11 +396,11 @@
396 " WHERE patch.cfg.key='baseline'"
397 " AND localdb.vvar.name='checkout-hash'"
398 " AND patch.cfg.key<>localdb.vvar.name"
399 );
400 if( db_step(&q)==SQLITE_ROW ){
401 blob_append_escaped_arg(&cmd, g.nameOfExe);
402 blob_appendf(&cmd, " update %s", db_column_text(&q, 0));
403 if( mFlags & PATCH_VERBOSE ){
404 fossil_print("%-10s %s\n", "BASELINE", db_column_text(&q,0));
405 }
406 }
@@ -423,11 +423,11 @@
423 " WHERE type IN ('merge','cherrypick','backout','integrate')"
424 " AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
425 );
426 while( db_step(&q)==SQLITE_ROW ){
427 const char *zType = db_column_text(&q,0);
428 blob_append_escaped_arg(&cmd, g.nameOfExe);
429 if( strcmp(zType,"merge")==0 ){
430 blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));
431 }else{
432 blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));
433 }
@@ -451,11 +451,11 @@
451
452 /* Deletions */
453 db_prepare(&q, "SELECT pathname FROM patch.chng"
454 " WHERE origname IS NULL AND delta IS NULL");
455 while( db_step(&q)==SQLITE_ROW ){
456 blob_append_escaped_arg(&cmd, g.nameOfExe);
457 blob_appendf(&cmd, " rm --hard %$\n", db_column_text(&q,0));
458 if( mFlags & PATCH_VERBOSE ){
459 fossil_print("%-10s %s\n", "DELETE", db_column_text(&q,0));
460 }
461 }
@@ -478,11 +478,11 @@
478 "SELECT origname, pathname FROM patch.chng"
479 " WHERE origname IS NOT NULL"
480 " AND origname<>pathname"
481 );
482 while( db_step(&q)==SQLITE_ROW ){
483 blob_append_escaped_arg(&cmd, g.nameOfExe);
484 blob_appendf(&cmd, " mv --hard %$ %$\n",
485 db_column_text(&q,0), db_column_text(&q,1));
486 if( mFlags & PATCH_VERBOSE ){
487 fossil_print("%-10s %s -> %s\n", "RENAME",
488 db_column_text(&q,0), db_column_text(&q,1));
@@ -552,11 +552,11 @@
552 sqlite3_free(aOut);
553 if( mFlags & PATCH_VERBOSE ){
554 fossil_print("%-10s %s\n", "EDIT", zPathname);
555 }
556 }else{
557 blob_append_escaped_arg(&cmd, g.nameOfExe);
558 blob_appendf(&cmd, " add %$\n", zPathname);
559 if( mFlags & PATCH_VERBOSE ){
560 fossil_print("%-10s %s\n", "NEW", zPathname);
561 }
562 }
@@ -673,22 +673,22 @@
673 zRemote = fossil_strdup(g.argv[3]);
674 zDir = strchr(zRemote,':');
675 if( zDir==0 ){
676 zDir = zRemote;
677 blob_init(&cmd, 0, 0);
678 blob_append_escaped_arg(&cmd, g.nameOfExe);
679 blob_appendf(&cmd, " patch %s%s %$ -", zRemoteCmd, zForce, zDir);
680 }else{
681 Blob remote;
682 zDir[0] = 0;
683 zDir++;
684 transport_ssh_command(&cmd);
685 blob_append_escaped_arg(&cmd, zRemote);
686 blob_init(&remote, 0, 0);
687 blob_appendf(&remote, "fossil patch %s%s --dir64 %z -",
688 zRemoteCmd, zForce, encode64(zDir, -1));
689 blob_append_escaped_arg(&cmd, blob_str(&remote));
690 blob_reset(&remote);
691 }
692 if( mFlags & PATCH_VERBOSE ){
693 fossil_print("# %s\n", blob_str(&cmd));
694 fflush(stdout);
695
--- src/patch.c
+++ src/patch.c
@@ -396,11 +396,11 @@
396 " WHERE patch.cfg.key='baseline'"
397 " AND localdb.vvar.name='checkout-hash'"
398 " AND patch.cfg.key<>localdb.vvar.name"
399 );
400 if( db_step(&q)==SQLITE_ROW ){
401 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
402 blob_appendf(&cmd, " update %s", db_column_text(&q, 0));
403 if( mFlags & PATCH_VERBOSE ){
404 fossil_print("%-10s %s\n", "BASELINE", db_column_text(&q,0));
405 }
406 }
@@ -423,11 +423,11 @@
423 " WHERE type IN ('merge','cherrypick','backout','integrate')"
424 " AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
425 );
426 while( db_step(&q)==SQLITE_ROW ){
427 const char *zType = db_column_text(&q,0);
428 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
429 if( strcmp(zType,"merge")==0 ){
430 blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));
431 }else{
432 blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));
433 }
@@ -451,11 +451,11 @@
451
452 /* Deletions */
453 db_prepare(&q, "SELECT pathname FROM patch.chng"
454 " WHERE origname IS NULL AND delta IS NULL");
455 while( db_step(&q)==SQLITE_ROW ){
456 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
457 blob_appendf(&cmd, " rm --hard %$\n", db_column_text(&q,0));
458 if( mFlags & PATCH_VERBOSE ){
459 fossil_print("%-10s %s\n", "DELETE", db_column_text(&q,0));
460 }
461 }
@@ -478,11 +478,11 @@
478 "SELECT origname, pathname FROM patch.chng"
479 " WHERE origname IS NOT NULL"
480 " AND origname<>pathname"
481 );
482 while( db_step(&q)==SQLITE_ROW ){
483 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
484 blob_appendf(&cmd, " mv --hard %$ %$\n",
485 db_column_text(&q,0), db_column_text(&q,1));
486 if( mFlags & PATCH_VERBOSE ){
487 fossil_print("%-10s %s -> %s\n", "RENAME",
488 db_column_text(&q,0), db_column_text(&q,1));
@@ -552,11 +552,11 @@
552 sqlite3_free(aOut);
553 if( mFlags & PATCH_VERBOSE ){
554 fossil_print("%-10s %s\n", "EDIT", zPathname);
555 }
556 }else{
557 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
558 blob_appendf(&cmd, " add %$\n", zPathname);
559 if( mFlags & PATCH_VERBOSE ){
560 fossil_print("%-10s %s\n", "NEW", zPathname);
561 }
562 }
@@ -673,22 +673,22 @@
673 zRemote = fossil_strdup(g.argv[3]);
674 zDir = strchr(zRemote,':');
675 if( zDir==0 ){
676 zDir = zRemote;
677 blob_init(&cmd, 0, 0);
678 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
679 blob_appendf(&cmd, " patch %s%s %$ -", zRemoteCmd, zForce, zDir);
680 }else{
681 Blob remote;
682 zDir[0] = 0;
683 zDir++;
684 transport_ssh_command(&cmd);
685 blob_append_escaped_arg(&cmd, zRemote, 0);
686 blob_init(&remote, 0, 0);
687 blob_appendf(&remote, "fossil patch %s%s --dir64 %z -",
688 zRemoteCmd, zForce, encode64(zDir, -1));
689 blob_append_escaped_arg(&cmd, blob_str(&remote), 0);
690 blob_reset(&remote);
691 }
692 if( mFlags & PATCH_VERBOSE ){
693 fossil_print("# %s\n", blob_str(&cmd));
694 fflush(stdout);
695
+4 -2
--- src/printf.c
+++ src/printf.c
@@ -102,11 +102,13 @@
102102
#define etSTRINGID 23 /* String with length limit for a hash prefix: %S */
103103
#define etROOT 24 /* String value of g.zTop: %R */
104104
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
105105
Use %!j to include double-quotes around it. */
106106
#define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
107
- See blob_append_escaped_arg() for details */
107
+ See blob_append_escaped_arg() for details
108
+ "%$" -> adds "./" prefix if necessary.
109
+ "%!$" -> omits the "./" prefix. */
108110
109111
110112
/*
111113
** An "etByte" is an 8-bit unsigned value.
112114
*/
@@ -838,11 +840,11 @@
838840
length = width = 0;
839841
break;
840842
}
841843
case etSHELLESC: {
842844
char *zArg = va_arg(ap, char*);
843
- blob_append_escaped_arg(pBlob, zArg);
845
+ blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
844846
length = width = 0;
845847
break;
846848
}
847849
case etERROR:
848850
buf[0] = '%';
849851
--- src/printf.c
+++ src/printf.c
@@ -102,11 +102,13 @@
102 #define etSTRINGID 23 /* String with length limit for a hash prefix: %S */
103 #define etROOT 24 /* String value of g.zTop: %R */
104 #define etJSONSTR 25 /* String encoded as a JSON string literal: %j
105 Use %!j to include double-quotes around it. */
106 #define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
107 See blob_append_escaped_arg() for details */
 
 
108
109
110 /*
111 ** An "etByte" is an 8-bit unsigned value.
112 */
@@ -838,11 +840,11 @@
838 length = width = 0;
839 break;
840 }
841 case etSHELLESC: {
842 char *zArg = va_arg(ap, char*);
843 blob_append_escaped_arg(pBlob, zArg);
844 length = width = 0;
845 break;
846 }
847 case etERROR:
848 buf[0] = '%';
849
--- src/printf.c
+++ src/printf.c
@@ -102,11 +102,13 @@
102 #define etSTRINGID 23 /* String with length limit for a hash prefix: %S */
103 #define etROOT 24 /* String value of g.zTop: %R */
104 #define etJSONSTR 25 /* String encoded as a JSON string literal: %j
105 Use %!j to include double-quotes around it. */
106 #define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
107 See blob_append_escaped_arg() for details
108 "%$" -> adds "./" prefix if necessary.
109 "%!$" -> omits the "./" prefix. */
110
111
112 /*
113 ** An "etByte" is an 8-bit unsigned value.
114 */
@@ -838,11 +840,11 @@
840 length = width = 0;
841 break;
842 }
843 case etSHELLESC: {
844 char *zArg = va_arg(ap, char*);
845 blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
846 length = width = 0;
847 break;
848 }
849 case etERROR:
850 buf[0] = '%';
851
+5 -5
--- src/winhttp.c
+++ src/winhttp.c
@@ -540,19 +540,19 @@
540540
if( PB("HTTPS") ){
541541
blob_appendf(&options, " --https");
542542
}
543543
if( zBaseUrl ){
544544
blob_appendf(&options, " --baseurl ");
545
- blob_append_escaped_arg(&options, zBaseUrl);
545
+ blob_append_escaped_arg(&options, zBaseUrl, 0);
546546
}
547547
if( zNotFound ){
548548
blob_appendf(&options, " --notfound ");
549
- blob_append_escaped_arg(&options, zNotFound);
549
+ blob_append_escaped_arg(&options, zNotFound, 1);
550550
}
551551
if( g.zCkoutAlias ){
552552
blob_appendf(&options, " --ckout-alias ");
553
- blob_append_escaped_arg(&options, g.zCkoutAlias);
553
+ blob_append_escaped_arg(&options, g.zCkoutAlias, 0);
554554
}
555555
if( zFileGlob ){
556556
blob_appendf(&options, " --files-urlenc %T", zFileGlob);
557557
}
558558
if( g.useLocalauth ){
@@ -564,19 +564,19 @@
564564
if( flags & HTTP_SERVER_REPOLIST ){
565565
blob_appendf(&options, " --repolist");
566566
}
567567
if( g.zExtRoot && g.zExtRoot[0] ){
568568
blob_appendf(&options, " --extroot");
569
- blob_append_escaped_arg(&options, g.zExtRoot);
569
+ blob_append_escaped_arg(&options, g.zExtRoot, 1);
570570
}
571571
zSkin = skin_in_use();
572572
if( zSkin ){
573573
blob_appendf(&options, " --skin %s", zSkin);
574574
}
575575
if( g.zMainMenuFile ){
576576
blob_appendf(&options, " --mainmenu ");
577
- blob_append_escaped_arg(&options, g.zMainMenuFile);
577
+ blob_append_escaped_arg(&options, g.zMainMenuFile, 1);
578578
}
579579
#if USE_SEE
580580
zSavedKey = db_get_saved_encryption_key();
581581
savedKeySize = db_get_saved_encryption_key_size();
582582
if( zSavedKey!=0 && savedKeySize>0 ){
583583
--- src/winhttp.c
+++ src/winhttp.c
@@ -540,19 +540,19 @@
540 if( PB("HTTPS") ){
541 blob_appendf(&options, " --https");
542 }
543 if( zBaseUrl ){
544 blob_appendf(&options, " --baseurl ");
545 blob_append_escaped_arg(&options, zBaseUrl);
546 }
547 if( zNotFound ){
548 blob_appendf(&options, " --notfound ");
549 blob_append_escaped_arg(&options, zNotFound);
550 }
551 if( g.zCkoutAlias ){
552 blob_appendf(&options, " --ckout-alias ");
553 blob_append_escaped_arg(&options, g.zCkoutAlias);
554 }
555 if( zFileGlob ){
556 blob_appendf(&options, " --files-urlenc %T", zFileGlob);
557 }
558 if( g.useLocalauth ){
@@ -564,19 +564,19 @@
564 if( flags & HTTP_SERVER_REPOLIST ){
565 blob_appendf(&options, " --repolist");
566 }
567 if( g.zExtRoot && g.zExtRoot[0] ){
568 blob_appendf(&options, " --extroot");
569 blob_append_escaped_arg(&options, g.zExtRoot);
570 }
571 zSkin = skin_in_use();
572 if( zSkin ){
573 blob_appendf(&options, " --skin %s", zSkin);
574 }
575 if( g.zMainMenuFile ){
576 blob_appendf(&options, " --mainmenu ");
577 blob_append_escaped_arg(&options, g.zMainMenuFile);
578 }
579 #if USE_SEE
580 zSavedKey = db_get_saved_encryption_key();
581 savedKeySize = db_get_saved_encryption_key_size();
582 if( zSavedKey!=0 && savedKeySize>0 ){
583
--- src/winhttp.c
+++ src/winhttp.c
@@ -540,19 +540,19 @@
540 if( PB("HTTPS") ){
541 blob_appendf(&options, " --https");
542 }
543 if( zBaseUrl ){
544 blob_appendf(&options, " --baseurl ");
545 blob_append_escaped_arg(&options, zBaseUrl, 0);
546 }
547 if( zNotFound ){
548 blob_appendf(&options, " --notfound ");
549 blob_append_escaped_arg(&options, zNotFound, 1);
550 }
551 if( g.zCkoutAlias ){
552 blob_appendf(&options, " --ckout-alias ");
553 blob_append_escaped_arg(&options, g.zCkoutAlias, 0);
554 }
555 if( zFileGlob ){
556 blob_appendf(&options, " --files-urlenc %T", zFileGlob);
557 }
558 if( g.useLocalauth ){
@@ -564,19 +564,19 @@
564 if( flags & HTTP_SERVER_REPOLIST ){
565 blob_appendf(&options, " --repolist");
566 }
567 if( g.zExtRoot && g.zExtRoot[0] ){
568 blob_appendf(&options, " --extroot");
569 blob_append_escaped_arg(&options, g.zExtRoot, 1);
570 }
571 zSkin = skin_in_use();
572 if( zSkin ){
573 blob_appendf(&options, " --skin %s", zSkin);
574 }
575 if( g.zMainMenuFile ){
576 blob_appendf(&options, " --mainmenu ");
577 blob_append_escaped_arg(&options, g.zMainMenuFile, 1);
578 }
579 #if USE_SEE
580 zSavedKey = db_get_saved_encryption_key();
581 savedKeySize = db_get_saved_encryption_key_size();
582 if( zSavedKey!=0 && savedKeySize>0 ){
583

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button