Fossil SCM

If the '--cgiupperparamsok' command line option or 'uppercase_params' CGI control line are present, allow parameter names to start with an uppercase letter.

mistachkin 2019-08-27 05:34 noJsonCgiFlag
Commit ab0d81f893b1f60c13cc11be0169685f34cf3c3ea662f808d80c630f6af869a7
3 files changed +17 -4 +1 -1 +10
+17 -4
--- src/cgi.c
+++ src/cgi.c
@@ -562,10 +562,23 @@
562562
*/
563563
void cgi_setenv(const char *zName, const char *zValue){
564564
cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
565565
}
566566
567
+
568
+/*
569
+** Returns non-zero if the specified character is lower case -OR-
570
+** CGI has been configured to allow uppercase parameter names.
571
+*/
572
+int cgi_char_allowed(char c){
573
+ if( fossil_islower(c) ){
574
+ return 1; /* lowercase letter, always OK */
575
+ }else if( fossil_isupper(c) && g.cgiUpperParamsOk ){
576
+ return 1; /* uppercase letter, OK if allowed explicitly */
577
+ }
578
+ return 0; /* something else, never OK */
579
+}
567580
568581
/*
569582
** Add a list of query parameters or cookies to the parameter set.
570583
**
571584
** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -615,11 +628,11 @@
615628
dehttpize(zValue);
616629
}else{
617630
if( *z ){ *z++ = 0; }
618631
zValue = "";
619632
}
620
- if( fossil_islower(zName[0]) && fossil_no_strange_characters(zName+1) ){
633
+ if( cgi_char_allowed(zName[0]) && fossil_no_strange_characters(zName+1) ){
621634
cgi_set_parameter_nocopy(zName, zValue, isQP);
622635
}
623636
#ifdef FOSSIL_ENABLE_JSON
624637
json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
625638
#endif /* FOSSIL_ENABLE_JSON */
@@ -759,11 +772,11 @@
759772
if( zBoundry==0 ) return;
760773
while( (zLine = get_line_from_string(&z, &len))!=0 ){
761774
if( zLine[0]==0 ){
762775
int nContent = 0;
763776
zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
764
- if( zName && zValue && fossil_islower(zName[0]) ){
777
+ if( zName && zValue && cgi_char_allowed(zName[0]) ){
765778
cgi_set_parameter_nocopy(zName, zValue, 1);
766779
if( showBytes ){
767780
cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
768781
mprintf("%d",nContent), 1);
769782
}
@@ -779,17 +792,17 @@
779792
i++;
780793
}else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
781794
zName = azArg[++i];
782795
}else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
783796
char *z = azArg[++i];
784
- if( zName && z && fossil_islower(zName[0]) ){
797
+ if( zName && z && cgi_char_allowed(zName[0]) ){
785798
cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z, 1);
786799
}
787800
showBytes = 1;
788801
}else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
789802
char *z = azArg[++i];
790
- if( zName && z && fossil_islower(zName[0]) ){
803
+ if( zName && z && cgi_char_allowed(zName[0]) ){
791804
cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z, 1);
792805
}
793806
}
794807
}
795808
}
796809
--- src/cgi.c
+++ src/cgi.c
@@ -562,10 +562,23 @@
562 */
563 void cgi_setenv(const char *zName, const char *zValue){
564 cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
565 }
566
 
 
 
 
 
 
 
 
 
 
 
 
 
567
568 /*
569 ** Add a list of query parameters or cookies to the parameter set.
570 **
571 ** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -615,11 +628,11 @@
615 dehttpize(zValue);
616 }else{
617 if( *z ){ *z++ = 0; }
618 zValue = "";
619 }
620 if( fossil_islower(zName[0]) && fossil_no_strange_characters(zName+1) ){
621 cgi_set_parameter_nocopy(zName, zValue, isQP);
622 }
623 #ifdef FOSSIL_ENABLE_JSON
624 json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
625 #endif /* FOSSIL_ENABLE_JSON */
@@ -759,11 +772,11 @@
759 if( zBoundry==0 ) return;
760 while( (zLine = get_line_from_string(&z, &len))!=0 ){
761 if( zLine[0]==0 ){
762 int nContent = 0;
763 zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
764 if( zName && zValue && fossil_islower(zName[0]) ){
765 cgi_set_parameter_nocopy(zName, zValue, 1);
766 if( showBytes ){
767 cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
768 mprintf("%d",nContent), 1);
769 }
@@ -779,17 +792,17 @@
779 i++;
780 }else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
781 zName = azArg[++i];
782 }else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
783 char *z = azArg[++i];
784 if( zName && z && fossil_islower(zName[0]) ){
785 cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z, 1);
786 }
787 showBytes = 1;
788 }else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
789 char *z = azArg[++i];
790 if( zName && z && fossil_islower(zName[0]) ){
791 cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z, 1);
792 }
793 }
794 }
795 }
796
--- src/cgi.c
+++ src/cgi.c
@@ -562,10 +562,23 @@
562 */
563 void cgi_setenv(const char *zName, const char *zValue){
564 cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
565 }
566
567
568 /*
569 ** Returns non-zero if the specified character is lower case -OR-
570 ** CGI has been configured to allow uppercase parameter names.
571 */
572 int cgi_char_allowed(char c){
573 if( fossil_islower(c) ){
574 return 1; /* lowercase letter, always OK */
575 }else if( fossil_isupper(c) && g.cgiUpperParamsOk ){
576 return 1; /* uppercase letter, OK if allowed explicitly */
577 }
578 return 0; /* something else, never OK */
579 }
580
581 /*
582 ** Add a list of query parameters or cookies to the parameter set.
583 **
584 ** Each parameter is of the form NAME=VALUE. Both the NAME and the
@@ -615,11 +628,11 @@
628 dehttpize(zValue);
629 }else{
630 if( *z ){ *z++ = 0; }
631 zValue = "";
632 }
633 if( cgi_char_allowed(zName[0]) && fossil_no_strange_characters(zName+1) ){
634 cgi_set_parameter_nocopy(zName, zValue, isQP);
635 }
636 #ifdef FOSSIL_ENABLE_JSON
637 json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
638 #endif /* FOSSIL_ENABLE_JSON */
@@ -759,11 +772,11 @@
772 if( zBoundry==0 ) return;
773 while( (zLine = get_line_from_string(&z, &len))!=0 ){
774 if( zLine[0]==0 ){
775 int nContent = 0;
776 zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
777 if( zName && zValue && cgi_char_allowed(zName[0]) ){
778 cgi_set_parameter_nocopy(zName, zValue, 1);
779 if( showBytes ){
780 cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
781 mprintf("%d",nContent), 1);
782 }
@@ -779,17 +792,17 @@
792 i++;
793 }else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
794 zName = azArg[++i];
795 }else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
796 char *z = azArg[++i];
797 if( zName && z && cgi_char_allowed(zName[0]) ){
798 cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z, 1);
799 }
800 showBytes = 1;
801 }else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
802 char *z = azArg[++i];
803 if( zName && z && cgi_char_allowed(zName[0]) ){
804 cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z, 1);
805 }
806 }
807 }
808 }
809
+1 -1
--- src/dispatch.c
+++ src/dispatch.c
@@ -194,11 +194,11 @@
194194
zName = "";
195195
}else{
196196
if( *z ){ *z++ = 0; }
197197
zValue = "";
198198
}
199
- if( fossil_islower(zName[0]) ){
199
+ if( cgi_char_allowed(zName[0]) ){
200200
cgi_replace_query_parameter(zName, zValue);
201201
}
202202
}
203203
return 0;
204204
}
205205
--- src/dispatch.c
+++ src/dispatch.c
@@ -194,11 +194,11 @@
194 zName = "";
195 }else{
196 if( *z ){ *z++ = 0; }
197 zValue = "";
198 }
199 if( fossil_islower(zName[0]) ){
200 cgi_replace_query_parameter(zName, zValue);
201 }
202 }
203 return 0;
204 }
205
--- src/dispatch.c
+++ src/dispatch.c
@@ -194,11 +194,11 @@
194 zName = "";
195 }else{
196 if( *z ){ *z++ = 0; }
197 zValue = "";
198 }
199 if( cgi_char_allowed(zName[0]) ){
200 cgi_replace_query_parameter(zName, zValue);
201 }
202 }
203 return 0;
204 }
205
+10
--- src/main.c
+++ src/main.c
@@ -211,10 +211,11 @@
211211
Blob httpHeader; /* Complete text of the HTTP request header */
212212
UrlData url; /* Information about current URL */
213213
const char *zLogin; /* Login name. NULL or "" if not logged in. */
214214
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
215215
** SSL client identity */
216
+ int cgiUpperParamsOk; /* Allow CGI parameters to start with uppercase */
216217
int useLocalauth; /* No login required if from 127.0.0.1 */
217218
int noPswd; /* Logged in without password (on 127.0.0.1) */
218219
int userUid; /* Integer user id */
219220
int isHuman; /* True if access by a human, not a spider or bot */
220221
int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
@@ -730,10 +731,11 @@
730731
fossil_exit(1);
731732
}else{
732733
const char *zChdir = find_option("chdir",0,1);
733734
g.isHTTP = 0;
734735
g.rcvid = 0;
736
+ g.cgiUpperParamsOk = find_option("cgiupperparamsok", 0, 0)!=0;
735737
g.fQuiet = find_option("quiet", 0, 0)!=0;
736738
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
737739
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
738740
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
739741
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
@@ -2009,10 +2011,18 @@
20092011
fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT);
20102012
blob_read_from_file(&config, zFile, ExtFILE);
20112013
while( blob_line(&config, &line) ){
20122014
if( !blob_token(&line, &key) ) continue;
20132015
if( blob_buffer(&key)[0]=='#' ) continue;
2016
+ if( blob_eq(&key, "uppercase_params") ){
2017
+ /* uppercase_params
2018
+ **
2019
+ ** Allow CGI parameters to start with an uppercase letter.
2020
+ */
2021
+ g.cgiUpperParamsOk = 1;
2022
+ continue;
2023
+ }
20142024
if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
20152025
/* repository: FILENAME
20162026
**
20172027
** The name of the Fossil repository to be served via CGI. Most
20182028
** fossil CGI scripts have a single non-comment line that contains
20192029
--- src/main.c
+++ src/main.c
@@ -211,10 +211,11 @@
211 Blob httpHeader; /* Complete text of the HTTP request header */
212 UrlData url; /* Information about current URL */
213 const char *zLogin; /* Login name. NULL or "" if not logged in. */
214 const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
215 ** SSL client identity */
 
216 int useLocalauth; /* No login required if from 127.0.0.1 */
217 int noPswd; /* Logged in without password (on 127.0.0.1) */
218 int userUid; /* Integer user id */
219 int isHuman; /* True if access by a human, not a spider or bot */
220 int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
@@ -730,10 +731,11 @@
730 fossil_exit(1);
731 }else{
732 const char *zChdir = find_option("chdir",0,1);
733 g.isHTTP = 0;
734 g.rcvid = 0;
 
735 g.fQuiet = find_option("quiet", 0, 0)!=0;
736 g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
737 g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
738 g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
739 g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
@@ -2009,10 +2011,18 @@
2009 fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT);
2010 blob_read_from_file(&config, zFile, ExtFILE);
2011 while( blob_line(&config, &line) ){
2012 if( !blob_token(&line, &key) ) continue;
2013 if( blob_buffer(&key)[0]=='#' ) continue;
 
 
 
 
 
 
 
 
2014 if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
2015 /* repository: FILENAME
2016 **
2017 ** The name of the Fossil repository to be served via CGI. Most
2018 ** fossil CGI scripts have a single non-comment line that contains
2019
--- src/main.c
+++ src/main.c
@@ -211,10 +211,11 @@
211 Blob httpHeader; /* Complete text of the HTTP request header */
212 UrlData url; /* Information about current URL */
213 const char *zLogin; /* Login name. NULL or "" if not logged in. */
214 const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
215 ** SSL client identity */
216 int cgiUpperParamsOk; /* Allow CGI parameters to start with uppercase */
217 int useLocalauth; /* No login required if from 127.0.0.1 */
218 int noPswd; /* Logged in without password (on 127.0.0.1) */
219 int userUid; /* Integer user id */
220 int isHuman; /* True if access by a human, not a spider or bot */
221 int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
@@ -730,10 +731,11 @@
731 fossil_exit(1);
732 }else{
733 const char *zChdir = find_option("chdir",0,1);
734 g.isHTTP = 0;
735 g.rcvid = 0;
736 g.cgiUpperParamsOk = find_option("cgiupperparamsok", 0, 0)!=0;
737 g.fQuiet = find_option("quiet", 0, 0)!=0;
738 g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
739 g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
740 g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
741 g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
@@ -2009,10 +2011,18 @@
2011 fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT);
2012 blob_read_from_file(&config, zFile, ExtFILE);
2013 while( blob_line(&config, &line) ){
2014 if( !blob_token(&line, &key) ) continue;
2015 if( blob_buffer(&key)[0]=='#' ) continue;
2016 if( blob_eq(&key, "uppercase_params") ){
2017 /* uppercase_params
2018 **
2019 ** Allow CGI parameters to start with an uppercase letter.
2020 */
2021 g.cgiUpperParamsOk = 1;
2022 continue;
2023 }
2024 if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
2025 /* repository: FILENAME
2026 **
2027 ** The name of the Fossil repository to be served via CGI. Most
2028 ** fossil CGI scripts have a single non-comment line that contains
2029

Keyboard Shortcuts

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