Fossil SCM

The taint markings and detection now appears to be working.

drh 2025-04-19 18:43 th1-taint
Commit d1bb87bcfdd4ad327bf23aa141c24417c10585b62a3267d65561ae9955efeb4e
3 files changed +1 -1 +9 -7 +54 -7
+1 -1
--- src/printf.c
+++ src/printf.c
@@ -1121,11 +1121,11 @@
11211121
}else if( (z = P(azEnv[i]))!=0 && z[0]!=0 ){
11221122
fprintf(out, "%s=%s\n", azEnv[i], z);
11231123
}
11241124
}
11251125
}
1126
- fclose(out);
1126
+ if( out!=stderr ) fclose(out);
11271127
}
11281128
11291129
/*
11301130
** The following variable becomes true while processing a fatal error
11311131
** or a panic. If additional "recursive-fatal" errors occur while
11321132
--- src/printf.c
+++ src/printf.c
@@ -1121,11 +1121,11 @@
1121 }else if( (z = P(azEnv[i]))!=0 && z[0]!=0 ){
1122 fprintf(out, "%s=%s\n", azEnv[i], z);
1123 }
1124 }
1125 }
1126 fclose(out);
1127 }
1128
1129 /*
1130 ** The following variable becomes true while processing a fatal error
1131 ** or a panic. If additional "recursive-fatal" errors occur while
1132
--- src/printf.c
+++ src/printf.c
@@ -1121,11 +1121,11 @@
1121 }else if( (z = P(azEnv[i]))!=0 && z[0]!=0 ){
1122 fprintf(out, "%s=%s\n", azEnv[i], z);
1123 }
1124 }
1125 }
1126 if( out!=stderr ) fclose(out);
1127 }
1128
1129 /*
1130 ** The following variable becomes true while processing a fatal error
1131 ** or a panic. If additional "recursive-fatal" errors occur while
1132
+9 -7
--- src/th.c
+++ src/th.c
@@ -780,11 +780,11 @@
780780
}
781781
}
782782
}
783783
784784
if( rc==TH_OK ){
785
- Th_SetResult(interp, output.zBuf, output.nBuf);
785
+ Th_SetResult(interp, output.zBuf, output.nBuf|output.bTaint);
786786
}
787787
thBufferFree(interp, &output);
788788
return rc;
789789
}
790790
@@ -859,19 +859,19 @@
859859
const char *zWord;
860860
int nWord;
861861
862862
thNextSpace(interp, zInput, nInput, &nWord);
863863
zInput += nWord;
864
- nInput = nList-(zInput-zList);
864
+ nInput = TH1_LEN(nList)-(zInput-zList);
865865
866866
if( TH_OK!=(rc = thNextWord(interp, zInput, nInput, &nWord, 0))
867867
|| TH_OK!=(rc = thSubstWord(interp, zInput, nWord))
868868
){
869869
goto finish;
870870
}
871
- zInput = &zInput[nWord];
872
- nInput = nList-(zInput-zList);
871
+ zInput = &zInput[TH1_LEN(nWord)];
872
+ nInput = TH1_LEN(nList)-(zInput-zList);
873873
if( nWord>0 ){
874874
zWord = Th_GetResult(interp, &nWord);
875875
thBufferWrite(interp, &strbuf, zWord, nWord);
876876
thBufferAddChar(interp, &strbuf, 0);
877877
thBufferWrite(interp, &lenbuf, &nWord, sizeof(int));
@@ -894,11 +894,11 @@
894894
zElem = (char *)&anElem[nCount];
895895
th_memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
896896
th_memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
897897
for(i=0; i<nCount;i++){
898898
azElem[i] = zElem;
899
- zElem += (anElem[i] + 1);
899
+ zElem += (TH1_LEN(anElem[i]) + 1);
900900
}
901901
*pazElem = azElem;
902902
*panElem = anElem;
903903
}
904904
if( pnCount ){
@@ -926,11 +926,11 @@
926926
const char *zStr, /* The tainted string */
927927
int nStr /* Length of the tainted string */
928928
){
929929
nStr = TH1_LEN(nStr);
930930
if( nStr>0 ){
931
- fossil_errorlog("warning: tainted %s: \"%.s\"", zWhere, nStr, zStr);
931
+ fossil_errorlog("warning: tainted %s: \"%.*s\"", zWhere, nStr, zStr);
932932
}else{
933933
fossil_errorlog("warning: tainted %s", zWhere);
934934
}
935935
return 0;
936936
}
@@ -940,11 +940,11 @@
940940
** in the current stack frame.
941941
*/
942942
static int thEvalLocal(Th_Interp *interp, const char *zProgram, int nProgram){
943943
int rc = TH_OK;
944944
const char *zInput = zProgram;
945
- int nInput = nProgram;
945
+ int nInput = TH1_LEN(nProgram);
946946
947947
if( TH1_TAINTED(nProgram)
948948
&& Th_ReportTaint(interp, "script", zProgram, nProgram)
949949
){
950950
return TH_ERROR;
@@ -1104,10 +1104,12 @@
11041104
}else{
11051105
int nInput = nProgram;
11061106
11071107
if( nInput<0 ){
11081108
nInput = th_strlen(zProgram);
1109
+ }else{
1110
+ nInput = TH1_LEN(nInput);
11091111
}
11101112
rc = thEvalLocal(interp, zProgram, nInput);
11111113
}
11121114
11131115
interp->pFrame = pSavedFrame;
11141116
--- src/th.c
+++ src/th.c
@@ -780,11 +780,11 @@
780 }
781 }
782 }
783
784 if( rc==TH_OK ){
785 Th_SetResult(interp, output.zBuf, output.nBuf);
786 }
787 thBufferFree(interp, &output);
788 return rc;
789 }
790
@@ -859,19 +859,19 @@
859 const char *zWord;
860 int nWord;
861
862 thNextSpace(interp, zInput, nInput, &nWord);
863 zInput += nWord;
864 nInput = nList-(zInput-zList);
865
866 if( TH_OK!=(rc = thNextWord(interp, zInput, nInput, &nWord, 0))
867 || TH_OK!=(rc = thSubstWord(interp, zInput, nWord))
868 ){
869 goto finish;
870 }
871 zInput = &zInput[nWord];
872 nInput = nList-(zInput-zList);
873 if( nWord>0 ){
874 zWord = Th_GetResult(interp, &nWord);
875 thBufferWrite(interp, &strbuf, zWord, nWord);
876 thBufferAddChar(interp, &strbuf, 0);
877 thBufferWrite(interp, &lenbuf, &nWord, sizeof(int));
@@ -894,11 +894,11 @@
894 zElem = (char *)&anElem[nCount];
895 th_memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
896 th_memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
897 for(i=0; i<nCount;i++){
898 azElem[i] = zElem;
899 zElem += (anElem[i] + 1);
900 }
901 *pazElem = azElem;
902 *panElem = anElem;
903 }
904 if( pnCount ){
@@ -926,11 +926,11 @@
926 const char *zStr, /* The tainted string */
927 int nStr /* Length of the tainted string */
928 ){
929 nStr = TH1_LEN(nStr);
930 if( nStr>0 ){
931 fossil_errorlog("warning: tainted %s: \"%.s\"", zWhere, nStr, zStr);
932 }else{
933 fossil_errorlog("warning: tainted %s", zWhere);
934 }
935 return 0;
936 }
@@ -940,11 +940,11 @@
940 ** in the current stack frame.
941 */
942 static int thEvalLocal(Th_Interp *interp, const char *zProgram, int nProgram){
943 int rc = TH_OK;
944 const char *zInput = zProgram;
945 int nInput = nProgram;
946
947 if( TH1_TAINTED(nProgram)
948 && Th_ReportTaint(interp, "script", zProgram, nProgram)
949 ){
950 return TH_ERROR;
@@ -1104,10 +1104,12 @@
1104 }else{
1105 int nInput = nProgram;
1106
1107 if( nInput<0 ){
1108 nInput = th_strlen(zProgram);
 
 
1109 }
1110 rc = thEvalLocal(interp, zProgram, nInput);
1111 }
1112
1113 interp->pFrame = pSavedFrame;
1114
--- src/th.c
+++ src/th.c
@@ -780,11 +780,11 @@
780 }
781 }
782 }
783
784 if( rc==TH_OK ){
785 Th_SetResult(interp, output.zBuf, output.nBuf|output.bTaint);
786 }
787 thBufferFree(interp, &output);
788 return rc;
789 }
790
@@ -859,19 +859,19 @@
859 const char *zWord;
860 int nWord;
861
862 thNextSpace(interp, zInput, nInput, &nWord);
863 zInput += nWord;
864 nInput = TH1_LEN(nList)-(zInput-zList);
865
866 if( TH_OK!=(rc = thNextWord(interp, zInput, nInput, &nWord, 0))
867 || TH_OK!=(rc = thSubstWord(interp, zInput, nWord))
868 ){
869 goto finish;
870 }
871 zInput = &zInput[TH1_LEN(nWord)];
872 nInput = TH1_LEN(nList)-(zInput-zList);
873 if( nWord>0 ){
874 zWord = Th_GetResult(interp, &nWord);
875 thBufferWrite(interp, &strbuf, zWord, nWord);
876 thBufferAddChar(interp, &strbuf, 0);
877 thBufferWrite(interp, &lenbuf, &nWord, sizeof(int));
@@ -894,11 +894,11 @@
894 zElem = (char *)&anElem[nCount];
895 th_memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
896 th_memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
897 for(i=0; i<nCount;i++){
898 azElem[i] = zElem;
899 zElem += (TH1_LEN(anElem[i]) + 1);
900 }
901 *pazElem = azElem;
902 *panElem = anElem;
903 }
904 if( pnCount ){
@@ -926,11 +926,11 @@
926 const char *zStr, /* The tainted string */
927 int nStr /* Length of the tainted string */
928 ){
929 nStr = TH1_LEN(nStr);
930 if( nStr>0 ){
931 fossil_errorlog("warning: tainted %s: \"%.*s\"", zWhere, nStr, zStr);
932 }else{
933 fossil_errorlog("warning: tainted %s", zWhere);
934 }
935 return 0;
936 }
@@ -940,11 +940,11 @@
940 ** in the current stack frame.
941 */
942 static int thEvalLocal(Th_Interp *interp, const char *zProgram, int nProgram){
943 int rc = TH_OK;
944 const char *zInput = zProgram;
945 int nInput = TH1_LEN(nProgram);
946
947 if( TH1_TAINTED(nProgram)
948 && Th_ReportTaint(interp, "script", zProgram, nProgram)
949 ){
950 return TH_ERROR;
@@ -1104,10 +1104,12 @@
1104 }else{
1105 int nInput = nProgram;
1106
1107 if( nInput<0 ){
1108 nInput = th_strlen(zProgram);
1109 }else{
1110 nInput = TH1_LEN(nInput);
1111 }
1112 rc = thEvalLocal(interp, zProgram, nInput);
1113 }
1114
1115 interp->pFrame = pSavedFrame;
1116
+54 -7
--- src/th_main.c
+++ src/th_main.c
@@ -382,25 +382,26 @@
382382
** g.th1Flags has the TH_INIT_NO_ENCODE flag.
383383
**
384384
** If pOut is NULL and the global pThOut is not then that blob
385385
** is used for output.
386386
*/
387
-static void sendText(Blob * pOut, const char *z, int n, int encode){
387
+static void sendText(Blob *pOut, const char *z, int n, int encode){
388388
if(0==pOut && pThOut!=0){
389389
pOut = pThOut;
390390
}
391391
if(TH_INIT_NO_ENCODE & g.th1Flags){
392392
encode = 0;
393
- if( TH1_TAINTED(n) && Th_ReportTaint(0, "output string", z, n) ){
393
+ }
394
+ if( encode==0 && n>0 && TH1_TAINTED(n) ){
395
+ if( Th_ReportTaint(0, "output string", z, n) ){
394396
return;
395397
}
398
+ n = TH1_LEN(n);
396399
}
397400
if( enableOutput && n ){
398401
if( n<0 ){
399402
n = strlen(z);
400
- }else{
401
- n = TH1_LEN(n);
402403
}
403404
if( encode ){
404405
z = htmlize(z, n);
405406
n = strlen(z);
406407
}
@@ -1865,10 +1866,47 @@
18651866
sqlite3_snprintf(sizeof(zUTime), zUTime, "%llu", x);
18661867
Th_SetResult(interp, zUTime, -1);
18671868
return TH_OK;
18681869
}
18691870
1871
+/*
1872
+** TH1 command: taint STRING
1873
+**
1874
+** Return a copy of STRING that is marked as tainted.
1875
+*/
1876
+static int taintCmd(
1877
+ Th_Interp *interp,
1878
+ void *p,
1879
+ int argc,
1880
+ const char **argv,
1881
+ int *argl
1882
+){
1883
+ if( argc!=2 ){
1884
+ return Th_WrongNumArgs(interp, "STRING");
1885
+ }
1886
+ Th_SetResult(interp, argv[1], TH1_ADD_TAINT(argl[1]));
1887
+ return TH_OK;
1888
+}
1889
+
1890
+/*
1891
+** TH1 command: untaint STRING
1892
+**
1893
+** Return a copy of STRING that is marked as untainted.
1894
+*/
1895
+static int untaintCmd(
1896
+ Th_Interp *interp,
1897
+ void *p,
1898
+ int argc,
1899
+ const char **argv,
1900
+ int *argl
1901
+){
1902
+ if( argc!=2 ){
1903
+ return Th_WrongNumArgs(interp, "STRING");
1904
+ }
1905
+ Th_SetResult(interp, argv[1], TH1_LEN(argl[1]));
1906
+ return TH_OK;
1907
+}
18701908
18711909
/*
18721910
** TH1 command: randhex N
18731911
**
18741912
** Return N*2 random hexadecimal digits with N<50. If N is omitted,
@@ -1940,11 +1978,13 @@
19401978
int res = TH_OK;
19411979
int nVar;
19421980
char *zErr = 0;
19431981
int noComplain = 0;
19441982
1945
- if( argc>3 && argl[1]==11 && strncmp(argv[1], "-nocomplain", 11)==0 ){
1983
+ if( argc>3 && TH1_LEN(argl[1])==11
1984
+ && strncmp(argv[1], "-nocomplain", 11)==0
1985
+ ){
19461986
argc--;
19471987
argv++;
19481988
argl++;
19491989
noComplain = 1;
19501990
}
@@ -1956,12 +1996,15 @@
19561996
Th_ErrorMessage(interp, "database is not open", 0, 0);
19571997
return TH_ERROR;
19581998
}
19591999
zSql = argv[1];
19602000
nSql = argl[1];
1961
- if( TH1_TAINTED(nSql) && Th_ReportTaint(interp,"query SQL",zSql,nSql) ){
1962
- return TH_ERROR;
2001
+ if( TH1_TAINTED(nSql) ){
2002
+ if( Th_ReportTaint(interp,"query SQL",zSql,nSql) ){
2003
+ return TH_ERROR;
2004
+ }
2005
+ nSql = TH1_LEN(nSql);
19632006
}
19642007
19652008
while( res==TH_OK && nSql>0 ){
19662009
zErr = 0;
19672010
report_restrict_sql(&zErr);
@@ -2408,13 +2451,15 @@
24082451
{"setting", settingCmd, 0},
24092452
{"styleFooter", styleFooterCmd, 0},
24102453
{"styleHeader", styleHeaderCmd, 0},
24112454
{"styleScript", styleScriptCmd, 0},
24122455
{"submenu", submenuCmd, 0},
2456
+ {"taint", taintCmd, 0},
24132457
{"tclReady", tclReadyCmd, 0},
24142458
{"trace", traceCmd, 0},
24152459
{"stime", stimeCmd, 0},
2460
+ {"untaint", untaintCmd, 0},
24162461
{"unversioned", unversionedCmd, 0},
24172462
{"utime", utimeCmd, 0},
24182463
{"verifyCsrf", verifyCsrfCmd, 0},
24192464
{"verifyLogin", verifyLoginCmd, 0},
24202465
{"wiki", wikiCmd, (void*)&aFlags[0]},
@@ -3013,10 +3058,11 @@
30133058
if( find_option("set-user-caps", 0, 0)!=0 ){
30143059
const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
30153060
login_set_capabilities(zCap ? zCap : "sx", 0);
30163061
g.useLocalauth = 1;
30173062
}
3063
+ db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
30183064
verify_all_options();
30193065
if( g.argc<3 ){
30203066
usage("FILE");
30213067
}
30223068
blob_zero(&in);
@@ -3065,10 +3111,11 @@
30653111
if( find_option("set-user-caps", 0, 0)!=0 ){
30663112
const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
30673113
login_set_capabilities(zCap ? zCap : "sx", 0);
30683114
g.useLocalauth = 1;
30693115
}
3116
+ db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
30703117
verify_all_options();
30713118
if( g.argc!=3 ){
30723119
usage("script");
30733120
}
30743121
if(file_isfile(g.argv[2], ExtFILE)){
30753122
--- src/th_main.c
+++ src/th_main.c
@@ -382,25 +382,26 @@
382 ** g.th1Flags has the TH_INIT_NO_ENCODE flag.
383 **
384 ** If pOut is NULL and the global pThOut is not then that blob
385 ** is used for output.
386 */
387 static void sendText(Blob * pOut, const char *z, int n, int encode){
388 if(0==pOut && pThOut!=0){
389 pOut = pThOut;
390 }
391 if(TH_INIT_NO_ENCODE & g.th1Flags){
392 encode = 0;
393 if( TH1_TAINTED(n) && Th_ReportTaint(0, "output string", z, n) ){
 
 
394 return;
395 }
 
396 }
397 if( enableOutput && n ){
398 if( n<0 ){
399 n = strlen(z);
400 }else{
401 n = TH1_LEN(n);
402 }
403 if( encode ){
404 z = htmlize(z, n);
405 n = strlen(z);
406 }
@@ -1865,10 +1866,47 @@
1865 sqlite3_snprintf(sizeof(zUTime), zUTime, "%llu", x);
1866 Th_SetResult(interp, zUTime, -1);
1867 return TH_OK;
1868 }
1869
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1870
1871 /*
1872 ** TH1 command: randhex N
1873 **
1874 ** Return N*2 random hexadecimal digits with N<50. If N is omitted,
@@ -1940,11 +1978,13 @@
1940 int res = TH_OK;
1941 int nVar;
1942 char *zErr = 0;
1943 int noComplain = 0;
1944
1945 if( argc>3 && argl[1]==11 && strncmp(argv[1], "-nocomplain", 11)==0 ){
 
 
1946 argc--;
1947 argv++;
1948 argl++;
1949 noComplain = 1;
1950 }
@@ -1956,12 +1996,15 @@
1956 Th_ErrorMessage(interp, "database is not open", 0, 0);
1957 return TH_ERROR;
1958 }
1959 zSql = argv[1];
1960 nSql = argl[1];
1961 if( TH1_TAINTED(nSql) && Th_ReportTaint(interp,"query SQL",zSql,nSql) ){
1962 return TH_ERROR;
 
 
 
1963 }
1964
1965 while( res==TH_OK && nSql>0 ){
1966 zErr = 0;
1967 report_restrict_sql(&zErr);
@@ -2408,13 +2451,15 @@
2408 {"setting", settingCmd, 0},
2409 {"styleFooter", styleFooterCmd, 0},
2410 {"styleHeader", styleHeaderCmd, 0},
2411 {"styleScript", styleScriptCmd, 0},
2412 {"submenu", submenuCmd, 0},
 
2413 {"tclReady", tclReadyCmd, 0},
2414 {"trace", traceCmd, 0},
2415 {"stime", stimeCmd, 0},
 
2416 {"unversioned", unversionedCmd, 0},
2417 {"utime", utimeCmd, 0},
2418 {"verifyCsrf", verifyCsrfCmd, 0},
2419 {"verifyLogin", verifyLoginCmd, 0},
2420 {"wiki", wikiCmd, (void*)&aFlags[0]},
@@ -3013,10 +3058,11 @@
3013 if( find_option("set-user-caps", 0, 0)!=0 ){
3014 const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
3015 login_set_capabilities(zCap ? zCap : "sx", 0);
3016 g.useLocalauth = 1;
3017 }
 
3018 verify_all_options();
3019 if( g.argc<3 ){
3020 usage("FILE");
3021 }
3022 blob_zero(&in);
@@ -3065,10 +3111,11 @@
3065 if( find_option("set-user-caps", 0, 0)!=0 ){
3066 const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
3067 login_set_capabilities(zCap ? zCap : "sx", 0);
3068 g.useLocalauth = 1;
3069 }
 
3070 verify_all_options();
3071 if( g.argc!=3 ){
3072 usage("script");
3073 }
3074 if(file_isfile(g.argv[2], ExtFILE)){
3075
--- src/th_main.c
+++ src/th_main.c
@@ -382,25 +382,26 @@
382 ** g.th1Flags has the TH_INIT_NO_ENCODE flag.
383 **
384 ** If pOut is NULL and the global pThOut is not then that blob
385 ** is used for output.
386 */
387 static void sendText(Blob *pOut, const char *z, int n, int encode){
388 if(0==pOut && pThOut!=0){
389 pOut = pThOut;
390 }
391 if(TH_INIT_NO_ENCODE & g.th1Flags){
392 encode = 0;
393 }
394 if( encode==0 && n>0 && TH1_TAINTED(n) ){
395 if( Th_ReportTaint(0, "output string", z, n) ){
396 return;
397 }
398 n = TH1_LEN(n);
399 }
400 if( enableOutput && n ){
401 if( n<0 ){
402 n = strlen(z);
 
 
403 }
404 if( encode ){
405 z = htmlize(z, n);
406 n = strlen(z);
407 }
@@ -1865,10 +1866,47 @@
1866 sqlite3_snprintf(sizeof(zUTime), zUTime, "%llu", x);
1867 Th_SetResult(interp, zUTime, -1);
1868 return TH_OK;
1869 }
1870
1871 /*
1872 ** TH1 command: taint STRING
1873 **
1874 ** Return a copy of STRING that is marked as tainted.
1875 */
1876 static int taintCmd(
1877 Th_Interp *interp,
1878 void *p,
1879 int argc,
1880 const char **argv,
1881 int *argl
1882 ){
1883 if( argc!=2 ){
1884 return Th_WrongNumArgs(interp, "STRING");
1885 }
1886 Th_SetResult(interp, argv[1], TH1_ADD_TAINT(argl[1]));
1887 return TH_OK;
1888 }
1889
1890 /*
1891 ** TH1 command: untaint STRING
1892 **
1893 ** Return a copy of STRING that is marked as untainted.
1894 */
1895 static int untaintCmd(
1896 Th_Interp *interp,
1897 void *p,
1898 int argc,
1899 const char **argv,
1900 int *argl
1901 ){
1902 if( argc!=2 ){
1903 return Th_WrongNumArgs(interp, "STRING");
1904 }
1905 Th_SetResult(interp, argv[1], TH1_LEN(argl[1]));
1906 return TH_OK;
1907 }
1908
1909 /*
1910 ** TH1 command: randhex N
1911 **
1912 ** Return N*2 random hexadecimal digits with N<50. If N is omitted,
@@ -1940,11 +1978,13 @@
1978 int res = TH_OK;
1979 int nVar;
1980 char *zErr = 0;
1981 int noComplain = 0;
1982
1983 if( argc>3 && TH1_LEN(argl[1])==11
1984 && strncmp(argv[1], "-nocomplain", 11)==0
1985 ){
1986 argc--;
1987 argv++;
1988 argl++;
1989 noComplain = 1;
1990 }
@@ -1956,12 +1996,15 @@
1996 Th_ErrorMessage(interp, "database is not open", 0, 0);
1997 return TH_ERROR;
1998 }
1999 zSql = argv[1];
2000 nSql = argl[1];
2001 if( TH1_TAINTED(nSql) ){
2002 if( Th_ReportTaint(interp,"query SQL",zSql,nSql) ){
2003 return TH_ERROR;
2004 }
2005 nSql = TH1_LEN(nSql);
2006 }
2007
2008 while( res==TH_OK && nSql>0 ){
2009 zErr = 0;
2010 report_restrict_sql(&zErr);
@@ -2408,13 +2451,15 @@
2451 {"setting", settingCmd, 0},
2452 {"styleFooter", styleFooterCmd, 0},
2453 {"styleHeader", styleHeaderCmd, 0},
2454 {"styleScript", styleScriptCmd, 0},
2455 {"submenu", submenuCmd, 0},
2456 {"taint", taintCmd, 0},
2457 {"tclReady", tclReadyCmd, 0},
2458 {"trace", traceCmd, 0},
2459 {"stime", stimeCmd, 0},
2460 {"untaint", untaintCmd, 0},
2461 {"unversioned", unversionedCmd, 0},
2462 {"utime", utimeCmd, 0},
2463 {"verifyCsrf", verifyCsrfCmd, 0},
2464 {"verifyLogin", verifyLoginCmd, 0},
2465 {"wiki", wikiCmd, (void*)&aFlags[0]},
@@ -3013,10 +3058,11 @@
3058 if( find_option("set-user-caps", 0, 0)!=0 ){
3059 const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
3060 login_set_capabilities(zCap ? zCap : "sx", 0);
3061 g.useLocalauth = 1;
3062 }
3063 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
3064 verify_all_options();
3065 if( g.argc<3 ){
3066 usage("FILE");
3067 }
3068 blob_zero(&in);
@@ -3065,10 +3111,11 @@
3111 if( find_option("set-user-caps", 0, 0)!=0 ){
3112 const char *zCap = fossil_getenv("TH1_TEST_USER_CAPS");
3113 login_set_capabilities(zCap ? zCap : "sx", 0);
3114 g.useLocalauth = 1;
3115 }
3116 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
3117 verify_all_options();
3118 if( g.argc!=3 ){
3119 usage("script");
3120 }
3121 if(file_isfile(g.argv[2], ExtFILE)){
3122

Keyboard Shortcuts

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