Fossil SCM

More robust handling of missing CGI parameters. See discussion at [https://www.fossil-scm.org/forum/forumpost/e2e75f8aec|forum thread e2e75f8aec].

drh 2020-08-22 16:10 trunk
Commit d6f69343ca4673d5128f40be011d6d16bca6f33f5bcdaeaca45eec544f8a4447
1 file changed +32 -6
+32 -6
--- src/cgi.c
+++ src/cgi.c
@@ -1053,29 +1053,56 @@
10531053
** assume that PATH_INFO is an empty string and set REQUEST_URI equal
10541054
** to PATH_INFO.
10551055
**
10561056
** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
10571057
** PATH_INFO when it is empty.
1058
+**
1059
+** CGI Parameter quick reference:
1060
+**
1061
+** REQUEST_URI
1062
+** _____________|____________
1063
+** / \
1064
+** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1065
+** \________________/\____/\____________________/ \_/
1066
+** | | | |
1067
+** HTTP_HOST | PATH_INFO QUERY_STRING
1068
+** SCRIPT_NAME
10581069
*/
10591070
void cgi_init(void){
10601071
char *z;
10611072
const char *zType;
10621073
char *zSemi;
10631074
int len;
10641075
const char *zRequestUri = cgi_parameter("REQUEST_URI",0);
1065
- const char *zScriptName = cgi_parameter("SCRIPT_NAME",0);
1066
- const char *zPathInfo = cgi_parameter("PATH_INFO",0);
1076
+ const char *zScriptName = cgi_parameter("SCRIPT_NAME","");
1077
+ const char *zPathInfo = cgi_parameter("PATH_INFO","");
10671078
#ifdef _WIN32
10681079
const char *zServerSoftware = cgi_parameter("SERVER_SOFTWARE",0);
10691080
#endif
10701081
10711082
#ifdef FOSSIL_ENABLE_JSON
10721083
const int noJson = P("no_json")!=0;
10731084
#endif
10741085
g.isHTTP = 1;
10751086
cgi_destination(CGI_BODY);
1076
- if( zScriptName==0 ) malformed_request("missing SCRIPT_NAME");
1087
+
1088
+ /* We must have SCRIPT_NAME. If the web server did not supply it, try
1089
+ ** to compute it from REQUEST_URI and PATH_INFO. */
1090
+ if( zScriptName==0 ){
1091
+ size_t nRU, nPI;
1092
+ if( zRequestUri==0 || zPathInfo==0 ){
1093
+ malformed_request("missing SCRIPT_NAME"); /* Does not return */
1094
+ }
1095
+ nRU = strlen(zRequestUri);
1096
+ nPI = strlen(zPathInfo);
1097
+ if( nRU<nPI ){
1098
+ malformed_request("PATH_INFO is longer than REQUEST_URI");
1099
+ }
1100
+ zScriptName = mprintf("%.*s", (int)(nRU-nPI), zRequestUri);
1101
+ cgi_set_parameter("SCRIPT_NAME", zScriptName);
1102
+ }
1103
+
10771104
#ifdef _WIN32
10781105
/* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
10791106
** PATH_INFO for virtually the same purpose. Define REQUEST_URI the same as
10801107
** PATH_INFO and redefine PATH_INFO with SCRIPT_NAME removed from the
10811108
** beginning. */
@@ -1257,16 +1284,15 @@
12571284
}
12581285
}
12591286
12601287
/* If no match is found and the name begins with an upper-case
12611288
** letter, then check to see if there is an environment variable
1262
- ** with the given name. Handle environment variables with empty values
1263
- ** the same as non-existent environment variables.
1289
+ ** with the given name.
12641290
*/
12651291
if( fossil_isupper(zName[0]) ){
12661292
const char *zValue = fossil_getenv(zName);
1267
- if( zValue && zValue[0] ){
1293
+ if( zValue ){
12681294
cgi_set_parameter_nocopy(zName, zValue, 0);
12691295
CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
12701296
return zValue;
12711297
}
12721298
}
12731299
--- src/cgi.c
+++ src/cgi.c
@@ -1053,29 +1053,56 @@
1053 ** assume that PATH_INFO is an empty string and set REQUEST_URI equal
1054 ** to PATH_INFO.
1055 **
1056 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1057 ** PATH_INFO when it is empty.
 
 
 
 
 
 
 
 
 
 
 
1058 */
1059 void cgi_init(void){
1060 char *z;
1061 const char *zType;
1062 char *zSemi;
1063 int len;
1064 const char *zRequestUri = cgi_parameter("REQUEST_URI",0);
1065 const char *zScriptName = cgi_parameter("SCRIPT_NAME",0);
1066 const char *zPathInfo = cgi_parameter("PATH_INFO",0);
1067 #ifdef _WIN32
1068 const char *zServerSoftware = cgi_parameter("SERVER_SOFTWARE",0);
1069 #endif
1070
1071 #ifdef FOSSIL_ENABLE_JSON
1072 const int noJson = P("no_json")!=0;
1073 #endif
1074 g.isHTTP = 1;
1075 cgi_destination(CGI_BODY);
1076 if( zScriptName==0 ) malformed_request("missing SCRIPT_NAME");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1077 #ifdef _WIN32
1078 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
1079 ** PATH_INFO for virtually the same purpose. Define REQUEST_URI the same as
1080 ** PATH_INFO and redefine PATH_INFO with SCRIPT_NAME removed from the
1081 ** beginning. */
@@ -1257,16 +1284,15 @@
1257 }
1258 }
1259
1260 /* If no match is found and the name begins with an upper-case
1261 ** letter, then check to see if there is an environment variable
1262 ** with the given name. Handle environment variables with empty values
1263 ** the same as non-existent environment variables.
1264 */
1265 if( fossil_isupper(zName[0]) ){
1266 const char *zValue = fossil_getenv(zName);
1267 if( zValue && zValue[0] ){
1268 cgi_set_parameter_nocopy(zName, zValue, 0);
1269 CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
1270 return zValue;
1271 }
1272 }
1273
--- src/cgi.c
+++ src/cgi.c
@@ -1053,29 +1053,56 @@
1053 ** assume that PATH_INFO is an empty string and set REQUEST_URI equal
1054 ** to PATH_INFO.
1055 **
1056 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1057 ** PATH_INFO when it is empty.
1058 **
1059 ** CGI Parameter quick reference:
1060 **
1061 ** REQUEST_URI
1062 ** _____________|____________
1063 ** / \
1064 ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1065 ** \________________/\____/\____________________/ \_/
1066 ** | | | |
1067 ** HTTP_HOST | PATH_INFO QUERY_STRING
1068 ** SCRIPT_NAME
1069 */
1070 void cgi_init(void){
1071 char *z;
1072 const char *zType;
1073 char *zSemi;
1074 int len;
1075 const char *zRequestUri = cgi_parameter("REQUEST_URI",0);
1076 const char *zScriptName = cgi_parameter("SCRIPT_NAME","");
1077 const char *zPathInfo = cgi_parameter("PATH_INFO","");
1078 #ifdef _WIN32
1079 const char *zServerSoftware = cgi_parameter("SERVER_SOFTWARE",0);
1080 #endif
1081
1082 #ifdef FOSSIL_ENABLE_JSON
1083 const int noJson = P("no_json")!=0;
1084 #endif
1085 g.isHTTP = 1;
1086 cgi_destination(CGI_BODY);
1087
1088 /* We must have SCRIPT_NAME. If the web server did not supply it, try
1089 ** to compute it from REQUEST_URI and PATH_INFO. */
1090 if( zScriptName==0 ){
1091 size_t nRU, nPI;
1092 if( zRequestUri==0 || zPathInfo==0 ){
1093 malformed_request("missing SCRIPT_NAME"); /* Does not return */
1094 }
1095 nRU = strlen(zRequestUri);
1096 nPI = strlen(zPathInfo);
1097 if( nRU<nPI ){
1098 malformed_request("PATH_INFO is longer than REQUEST_URI");
1099 }
1100 zScriptName = mprintf("%.*s", (int)(nRU-nPI), zRequestUri);
1101 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1102 }
1103
1104 #ifdef _WIN32
1105 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
1106 ** PATH_INFO for virtually the same purpose. Define REQUEST_URI the same as
1107 ** PATH_INFO and redefine PATH_INFO with SCRIPT_NAME removed from the
1108 ** beginning. */
@@ -1257,16 +1284,15 @@
1284 }
1285 }
1286
1287 /* If no match is found and the name begins with an upper-case
1288 ** letter, then check to see if there is an environment variable
1289 ** with the given name.
 
1290 */
1291 if( fossil_isupper(zName[0]) ){
1292 const char *zValue = fossil_getenv(zName);
1293 if( zValue ){
1294 cgi_set_parameter_nocopy(zName, zValue, 0);
1295 CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
1296 return zValue;
1297 }
1298 }
1299

Keyboard Shortcuts

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