Fossil SCM

Enhancements to CGI query parameter processing in an attempt to deal with the issue described at [forum:/forumpost/049e8650ed|forum post 049e8650ed].

drh 2021-01-31 00:31 trunk
Commit 140cb312ca6e5c83fe0478ee2772d9d0f2695f2d55b5df4ee0c59e638b90db00
1 file changed +32 -20
+32 -20
--- src/cgi.c
+++ src/cgi.c
@@ -196,11 +196,11 @@
196196
197197
/*
198198
** Set the reply content type
199199
*/
200200
void cgi_set_content_type(const char *zType){
201
- zContentType = mprintf("%s", zType);
201
+ zContentType = fossil_strdup(zType);
202202
}
203203
204204
/*
205205
** Set the reply content to the specified BLOB.
206206
*/
@@ -213,11 +213,11 @@
213213
214214
/*
215215
** Set the reply status code
216216
*/
217217
void cgi_set_status(int iStat, const char *zStat){
218
- zReplyStatus = mprintf("%s", zStat);
218
+ zReplyStatus = fossil_strdup(zStat);
219219
iReplyStatus = iStat;
220220
}
221221
222222
/*
223223
** Append text to the header of an HTTP reply
@@ -580,14 +580,14 @@
580580
** is its fully decoded value.
581581
**
582582
** Copies are made of both the zName and zValue parameters.
583583
*/
584584
void cgi_set_parameter(const char *zName, const char *zValue){
585
- cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue), 0);
585
+ cgi_set_parameter_nocopy(fossil_strdup(zName),fossil_strdup(zValue), 0);
586586
}
587587
void cgi_set_query_parameter(const char *zName, const char *zValue){
588
- cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue), 1);
588
+ cgi_set_parameter_nocopy(fossil_strdup(zName),fossil_strdup(zValue), 1);
589589
}
590590
591591
/*
592592
** Replace a parameter with a new value.
593593
*/
@@ -650,11 +650,11 @@
650650
/*
651651
** Add a query parameter. The zName portion is fixed but a copy
652652
** must be made of zValue.
653653
*/
654654
void cgi_setenv(const char *zName, const char *zValue){
655
- cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
655
+ cgi_set_parameter_nocopy(zName, fossil_strdup(zValue), 0);
656656
}
657657
658658
/*
659659
** Add a list of query parameters or cookies to the parameter set.
660660
**
@@ -1050,10 +1050,15 @@
10501050
** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
10511051
** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
10521052
** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
10531053
** assume that PATH_INFO is an empty string and set REQUEST_URI equal
10541054
** to PATH_INFO.
1055
+**
1056
+** Sometimes PATH_INFO is missing and SCRIPT_NAME is not a prefix of
1057
+** REQUEST_URI. (See https://fossil-scm.org/forum/forumpost/049e8650ed)
1058
+** In that case, truncate SCRIPT_NAME so that it is a proper prefix
1059
+** of REQUEST_URI.
10551060
**
10561061
** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
10571062
** PATH_INFO when it is empty.
10581063
**
10591064
** CGI Parameter quick reference:
@@ -1095,11 +1100,11 @@
10951100
nRU = strlen(zRequestUri);
10961101
nPI = strlen(zPathInfo);
10971102
if( nRU<nPI ){
10981103
malformed_request("PATH_INFO is longer than REQUEST_URI");
10991104
}
1100
- zScriptName = mprintf("%.*s", (int)(nRU-nPI), zRequestUri);
1105
+ zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
11011106
cgi_set_parameter("SCRIPT_NAME", zScriptName);
11021107
}
11031108
11041109
#ifdef _WIN32
11051110
/* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1109,11 +1114,11 @@
11091114
if( zServerSoftware && strstr(zServerSoftware, "Microsoft-IIS") ){
11101115
int i, j;
11111116
cgi_set_parameter("REQUEST_URI", zPathInfo);
11121117
for(i=0; zPathInfo[i]==zScriptName[i] && zPathInfo[i]; i++){}
11131118
for(j=i; zPathInfo[j] && zPathInfo[j]!='?'; j++){}
1114
- zPathInfo = mprintf("%.*s", j-i, zPathInfo+i);
1119
+ zPathInfo = fossil_strndup(zPathInfo+i, j-i);
11151120
cgi_replace_parameter("PATH_INFO", zPathInfo);
11161121
}
11171122
#endif
11181123
if( zRequestUri==0 ){
11191124
const char *z = zPathInfo;
@@ -1126,12 +1131,19 @@
11261131
}
11271132
if( zPathInfo==0 ){
11281133
int i, j;
11291134
for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
11301135
for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){}
1131
- zPathInfo = mprintf("%.*s", j-i, zRequestUri+i);
1132
- cgi_set_parameter("PATH_INFO", zPathInfo);
1136
+ zPathInfo = fossil_strndup(zRequestUri+i, j-i);
1137
+ cgi_set_parameter_nocopy("PATH_INFO", zPathInfo, 0);
1138
+ if( j>i && zScriptName[i]!=0 ){
1139
+ /* If SCRIPT_NAME is not a prefix of REQUEST_URI, truncate it so
1140
+ ** that it is. See https://fossil-scm.org/forum/forumpost/049e8650ed
1141
+ */
1142
+ char *zNew = fossil_strndup(zScriptName, i);
1143
+ cgi_replace_parameter("SCRIPT_NAME", zNew);
1144
+ }
11331145
}
11341146
#ifdef FOSSIL_ENABLE_JSON
11351147
if(noJson==0 && json_request_is_json_api(zPathInfo)){
11361148
/* We need to change some following behaviour depending on whether
11371149
** we are operating in JSON mode or not. We cannot, however, be
@@ -1145,30 +1157,30 @@
11451157
"Internal misconfiguration of g.json.isJsonMode");
11461158
}
11471159
#endif
11481160
z = (char*)P("HTTP_COOKIE");
11491161
if( z ){
1150
- z = mprintf("%s",z);
1162
+ z = fossil_strdup(z);
11511163
add_param_list(z, ';');
11521164
}
11531165
11541166
z = (char*)P("QUERY_STRING");
11551167
if( z ){
1156
- z = mprintf("%s",z);
1168
+ z = fossil_strdup(z);
11571169
add_param_list(z, '&');
11581170
}
11591171
11601172
z = (char*)P("REMOTE_ADDR");
11611173
if( z ){
1162
- g.zIpAddr = mprintf("%s", z);
1174
+ g.zIpAddr = fossil_strdup(z);
11631175
}
11641176
11651177
len = atoi(PD("CONTENT_LENGTH", "0"));
11661178
zType = P("CONTENT_TYPE");
11671179
zSemi = zType ? strchr(zType, ';') : 0;
11681180
if( zSemi ){
1169
- g.zContentType = mprintf("%.*s", (int)(zSemi-zType), zType);
1181
+ g.zContentType = fossil_strndup(zType, (int)(zSemi-zType));
11701182
zType = g.zContentType;
11711183
}else{
11721184
g.zContentType = zType;
11731185
}
11741186
blob_zero(&g.cgiIn);
@@ -1695,11 +1707,11 @@
16951707
if( zIpAddr==0 ){
16961708
zIpAddr = cgi_remote_ip(fileno(g.httpIn));
16971709
}
16981710
if( zIpAddr ){
16991711
cgi_setenv("REMOTE_ADDR", zIpAddr);
1700
- g.zIpAddr = mprintf("%s", zIpAddr);
1712
+ g.zIpAddr = fossil_strdup(zIpAddr);
17011713
}
17021714
17031715
17041716
/* Get all the optional fields that follow the first line.
17051717
*/
@@ -1746,11 +1758,11 @@
17461758
}else if( fossil_strcmp(zFieldName,"authorization:")==0 ){
17471759
cgi_setenv("HTTP_AUTHORIZATION", zVal);
17481760
}else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
17491761
const char *zIpAddr = cgi_accept_forwarded_for(zVal);
17501762
if( zIpAddr!=0 ){
1751
- g.zIpAddr = mprintf("%s", zIpAddr);
1763
+ g.zIpAddr = fossil_strdup(zIpAddr);
17521764
cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
17531765
}
17541766
}else if( fossil_strcmp(zFieldName,"range:")==0 ){
17551767
int x1 = 0;
17561768
int x2 = 0;
@@ -1786,11 +1798,11 @@
17861798
if( nCycles==0 ){ json_bootstrap_early(); }
17871799
#endif
17881800
if( zIpAddr ){
17891801
if( nCycles==0 ){
17901802
cgi_setenv("REMOTE_ADDR", zIpAddr);
1791
- g.zIpAddr = mprintf("%s", zIpAddr);
1803
+ g.zIpAddr = fossil_strdup(zIpAddr);
17921804
}
17931805
}else{
17941806
fossil_panic("missing SSH IP address");
17951807
}
17961808
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
@@ -1848,11 +1860,11 @@
18481860
for(i=0; zToken[i] && zToken[i]!='?'; i++){}
18491861
if( zToken[i] ) zToken[i++] = 0;
18501862
if( nCycles==0 ){
18511863
cgi_setenv("PATH_INFO", zToken);
18521864
}else{
1853
- cgi_replace_parameter("PATH_INFO", mprintf("%s",zToken));
1865
+ cgi_replace_parameter("PATH_INFO", fossil_strdup(zToken));
18541866
}
18551867
18561868
/* Get all the optional fields that follow the first line.
18571869
*/
18581870
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
@@ -1870,11 +1882,11 @@
18701882
zFieldName[i] = fossil_tolower(zFieldName[i]);
18711883
}
18721884
if( fossil_strcmp(zFieldName,"content-length:")==0 ){
18731885
content_length = atoi(zVal);
18741886
}else if( fossil_strcmp(zFieldName,"content-type:")==0 ){
1875
- g.zContentType = zType = mprintf("%s", zVal);
1887
+ g.zContentType = zType = fossil_strdup(zVal);
18761888
}else if( fossil_strcmp(zFieldName,"host:")==0 ){
18771889
if( nCycles==0 ){
18781890
cgi_setenv("HTTP_HOST", zVal);
18791891
}
18801892
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
@@ -1947,11 +1959,11 @@
19471959
19481960
/* Got all probes now first transport_open is completed
19491961
** so return the command that was requested
19501962
*/
19511963
g.fSshClient |= CGI_SSH_COMPAT;
1952
- return mprintf("%s", zToken);
1964
+ return fossil_strdup(zToken);
19531965
}
19541966
19551967
/*
19561968
** This routine handles the old fossil SSH transport_flip
19571969
** and transport_open communications if detected.
@@ -2323,11 +2335,11 @@
23232335
const char *cgi_ssh_remote_addr(const char *zDefault){
23242336
char *zIndex;
23252337
const char *zSshConn = fossil_getenv("SSH_CONNECTION");
23262338
23272339
if( zSshConn && zSshConn[0] ){
2328
- char *zSshClient = mprintf("%s",zSshConn);
2340
+ char *zSshClient = fossil_strdup(zSshConn);
23292341
if( (zIndex = strchr(zSshClient,' '))!=0 ){
23302342
zSshClient[zIndex-zSshClient] = '\0';
23312343
return zSshClient;
23322344
}
23332345
}
23342346
--- src/cgi.c
+++ src/cgi.c
@@ -196,11 +196,11 @@
196
197 /*
198 ** Set the reply content type
199 */
200 void cgi_set_content_type(const char *zType){
201 zContentType = mprintf("%s", zType);
202 }
203
204 /*
205 ** Set the reply content to the specified BLOB.
206 */
@@ -213,11 +213,11 @@
213
214 /*
215 ** Set the reply status code
216 */
217 void cgi_set_status(int iStat, const char *zStat){
218 zReplyStatus = mprintf("%s", zStat);
219 iReplyStatus = iStat;
220 }
221
222 /*
223 ** Append text to the header of an HTTP reply
@@ -580,14 +580,14 @@
580 ** is its fully decoded value.
581 **
582 ** Copies are made of both the zName and zValue parameters.
583 */
584 void cgi_set_parameter(const char *zName, const char *zValue){
585 cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue), 0);
586 }
587 void cgi_set_query_parameter(const char *zName, const char *zValue){
588 cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue), 1);
589 }
590
591 /*
592 ** Replace a parameter with a new value.
593 */
@@ -650,11 +650,11 @@
650 /*
651 ** Add a query parameter. The zName portion is fixed but a copy
652 ** must be made of zValue.
653 */
654 void cgi_setenv(const char *zName, const char *zValue){
655 cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
656 }
657
658 /*
659 ** Add a list of query parameters or cookies to the parameter set.
660 **
@@ -1050,10 +1050,15 @@
1050 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1051 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1052 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
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:
@@ -1095,11 +1100,11 @@
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
@@ -1109,11 +1114,11 @@
1109 if( zServerSoftware && strstr(zServerSoftware, "Microsoft-IIS") ){
1110 int i, j;
1111 cgi_set_parameter("REQUEST_URI", zPathInfo);
1112 for(i=0; zPathInfo[i]==zScriptName[i] && zPathInfo[i]; i++){}
1113 for(j=i; zPathInfo[j] && zPathInfo[j]!='?'; j++){}
1114 zPathInfo = mprintf("%.*s", j-i, zPathInfo+i);
1115 cgi_replace_parameter("PATH_INFO", zPathInfo);
1116 }
1117 #endif
1118 if( zRequestUri==0 ){
1119 const char *z = zPathInfo;
@@ -1126,12 +1131,19 @@
1126 }
1127 if( zPathInfo==0 ){
1128 int i, j;
1129 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
1130 for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){}
1131 zPathInfo = mprintf("%.*s", j-i, zRequestUri+i);
1132 cgi_set_parameter("PATH_INFO", zPathInfo);
 
 
 
 
 
 
 
1133 }
1134 #ifdef FOSSIL_ENABLE_JSON
1135 if(noJson==0 && json_request_is_json_api(zPathInfo)){
1136 /* We need to change some following behaviour depending on whether
1137 ** we are operating in JSON mode or not. We cannot, however, be
@@ -1145,30 +1157,30 @@
1145 "Internal misconfiguration of g.json.isJsonMode");
1146 }
1147 #endif
1148 z = (char*)P("HTTP_COOKIE");
1149 if( z ){
1150 z = mprintf("%s",z);
1151 add_param_list(z, ';');
1152 }
1153
1154 z = (char*)P("QUERY_STRING");
1155 if( z ){
1156 z = mprintf("%s",z);
1157 add_param_list(z, '&');
1158 }
1159
1160 z = (char*)P("REMOTE_ADDR");
1161 if( z ){
1162 g.zIpAddr = mprintf("%s", z);
1163 }
1164
1165 len = atoi(PD("CONTENT_LENGTH", "0"));
1166 zType = P("CONTENT_TYPE");
1167 zSemi = zType ? strchr(zType, ';') : 0;
1168 if( zSemi ){
1169 g.zContentType = mprintf("%.*s", (int)(zSemi-zType), zType);
1170 zType = g.zContentType;
1171 }else{
1172 g.zContentType = zType;
1173 }
1174 blob_zero(&g.cgiIn);
@@ -1695,11 +1707,11 @@
1695 if( zIpAddr==0 ){
1696 zIpAddr = cgi_remote_ip(fileno(g.httpIn));
1697 }
1698 if( zIpAddr ){
1699 cgi_setenv("REMOTE_ADDR", zIpAddr);
1700 g.zIpAddr = mprintf("%s", zIpAddr);
1701 }
1702
1703
1704 /* Get all the optional fields that follow the first line.
1705 */
@@ -1746,11 +1758,11 @@
1746 }else if( fossil_strcmp(zFieldName,"authorization:")==0 ){
1747 cgi_setenv("HTTP_AUTHORIZATION", zVal);
1748 }else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
1749 const char *zIpAddr = cgi_accept_forwarded_for(zVal);
1750 if( zIpAddr!=0 ){
1751 g.zIpAddr = mprintf("%s", zIpAddr);
1752 cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
1753 }
1754 }else if( fossil_strcmp(zFieldName,"range:")==0 ){
1755 int x1 = 0;
1756 int x2 = 0;
@@ -1786,11 +1798,11 @@
1786 if( nCycles==0 ){ json_bootstrap_early(); }
1787 #endif
1788 if( zIpAddr ){
1789 if( nCycles==0 ){
1790 cgi_setenv("REMOTE_ADDR", zIpAddr);
1791 g.zIpAddr = mprintf("%s", zIpAddr);
1792 }
1793 }else{
1794 fossil_panic("missing SSH IP address");
1795 }
1796 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
@@ -1848,11 +1860,11 @@
1848 for(i=0; zToken[i] && zToken[i]!='?'; i++){}
1849 if( zToken[i] ) zToken[i++] = 0;
1850 if( nCycles==0 ){
1851 cgi_setenv("PATH_INFO", zToken);
1852 }else{
1853 cgi_replace_parameter("PATH_INFO", mprintf("%s",zToken));
1854 }
1855
1856 /* Get all the optional fields that follow the first line.
1857 */
1858 while( fgets(zLine,sizeof(zLine),g.httpIn) ){
@@ -1870,11 +1882,11 @@
1870 zFieldName[i] = fossil_tolower(zFieldName[i]);
1871 }
1872 if( fossil_strcmp(zFieldName,"content-length:")==0 ){
1873 content_length = atoi(zVal);
1874 }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){
1875 g.zContentType = zType = mprintf("%s", zVal);
1876 }else if( fossil_strcmp(zFieldName,"host:")==0 ){
1877 if( nCycles==0 ){
1878 cgi_setenv("HTTP_HOST", zVal);
1879 }
1880 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
@@ -1947,11 +1959,11 @@
1947
1948 /* Got all probes now first transport_open is completed
1949 ** so return the command that was requested
1950 */
1951 g.fSshClient |= CGI_SSH_COMPAT;
1952 return mprintf("%s", zToken);
1953 }
1954
1955 /*
1956 ** This routine handles the old fossil SSH transport_flip
1957 ** and transport_open communications if detected.
@@ -2323,11 +2335,11 @@
2323 const char *cgi_ssh_remote_addr(const char *zDefault){
2324 char *zIndex;
2325 const char *zSshConn = fossil_getenv("SSH_CONNECTION");
2326
2327 if( zSshConn && zSshConn[0] ){
2328 char *zSshClient = mprintf("%s",zSshConn);
2329 if( (zIndex = strchr(zSshClient,' '))!=0 ){
2330 zSshClient[zIndex-zSshClient] = '\0';
2331 return zSshClient;
2332 }
2333 }
2334
--- src/cgi.c
+++ src/cgi.c
@@ -196,11 +196,11 @@
196
197 /*
198 ** Set the reply content type
199 */
200 void cgi_set_content_type(const char *zType){
201 zContentType = fossil_strdup(zType);
202 }
203
204 /*
205 ** Set the reply content to the specified BLOB.
206 */
@@ -213,11 +213,11 @@
213
214 /*
215 ** Set the reply status code
216 */
217 void cgi_set_status(int iStat, const char *zStat){
218 zReplyStatus = fossil_strdup(zStat);
219 iReplyStatus = iStat;
220 }
221
222 /*
223 ** Append text to the header of an HTTP reply
@@ -580,14 +580,14 @@
580 ** is its fully decoded value.
581 **
582 ** Copies are made of both the zName and zValue parameters.
583 */
584 void cgi_set_parameter(const char *zName, const char *zValue){
585 cgi_set_parameter_nocopy(fossil_strdup(zName),fossil_strdup(zValue), 0);
586 }
587 void cgi_set_query_parameter(const char *zName, const char *zValue){
588 cgi_set_parameter_nocopy(fossil_strdup(zName),fossil_strdup(zValue), 1);
589 }
590
591 /*
592 ** Replace a parameter with a new value.
593 */
@@ -650,11 +650,11 @@
650 /*
651 ** Add a query parameter. The zName portion is fixed but a copy
652 ** must be made of zValue.
653 */
654 void cgi_setenv(const char *zName, const char *zValue){
655 cgi_set_parameter_nocopy(zName, fossil_strdup(zValue), 0);
656 }
657
658 /*
659 ** Add a list of query parameters or cookies to the parameter set.
660 **
@@ -1050,10 +1050,15 @@
1050 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1051 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1052 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
1053 ** assume that PATH_INFO is an empty string and set REQUEST_URI equal
1054 ** to PATH_INFO.
1055 **
1056 ** Sometimes PATH_INFO is missing and SCRIPT_NAME is not a prefix of
1057 ** REQUEST_URI. (See https://fossil-scm.org/forum/forumpost/049e8650ed)
1058 ** In that case, truncate SCRIPT_NAME so that it is a proper prefix
1059 ** of REQUEST_URI.
1060 **
1061 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1062 ** PATH_INFO when it is empty.
1063 **
1064 ** CGI Parameter quick reference:
@@ -1095,11 +1100,11 @@
1100 nRU = strlen(zRequestUri);
1101 nPI = strlen(zPathInfo);
1102 if( nRU<nPI ){
1103 malformed_request("PATH_INFO is longer than REQUEST_URI");
1104 }
1105 zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
1106 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1107 }
1108
1109 #ifdef _WIN32
1110 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1109,11 +1114,11 @@
1114 if( zServerSoftware && strstr(zServerSoftware, "Microsoft-IIS") ){
1115 int i, j;
1116 cgi_set_parameter("REQUEST_URI", zPathInfo);
1117 for(i=0; zPathInfo[i]==zScriptName[i] && zPathInfo[i]; i++){}
1118 for(j=i; zPathInfo[j] && zPathInfo[j]!='?'; j++){}
1119 zPathInfo = fossil_strndup(zPathInfo+i, j-i);
1120 cgi_replace_parameter("PATH_INFO", zPathInfo);
1121 }
1122 #endif
1123 if( zRequestUri==0 ){
1124 const char *z = zPathInfo;
@@ -1126,12 +1131,19 @@
1131 }
1132 if( zPathInfo==0 ){
1133 int i, j;
1134 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
1135 for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){}
1136 zPathInfo = fossil_strndup(zRequestUri+i, j-i);
1137 cgi_set_parameter_nocopy("PATH_INFO", zPathInfo, 0);
1138 if( j>i && zScriptName[i]!=0 ){
1139 /* If SCRIPT_NAME is not a prefix of REQUEST_URI, truncate it so
1140 ** that it is. See https://fossil-scm.org/forum/forumpost/049e8650ed
1141 */
1142 char *zNew = fossil_strndup(zScriptName, i);
1143 cgi_replace_parameter("SCRIPT_NAME", zNew);
1144 }
1145 }
1146 #ifdef FOSSIL_ENABLE_JSON
1147 if(noJson==0 && json_request_is_json_api(zPathInfo)){
1148 /* We need to change some following behaviour depending on whether
1149 ** we are operating in JSON mode or not. We cannot, however, be
@@ -1145,30 +1157,30 @@
1157 "Internal misconfiguration of g.json.isJsonMode");
1158 }
1159 #endif
1160 z = (char*)P("HTTP_COOKIE");
1161 if( z ){
1162 z = fossil_strdup(z);
1163 add_param_list(z, ';');
1164 }
1165
1166 z = (char*)P("QUERY_STRING");
1167 if( z ){
1168 z = fossil_strdup(z);
1169 add_param_list(z, '&');
1170 }
1171
1172 z = (char*)P("REMOTE_ADDR");
1173 if( z ){
1174 g.zIpAddr = fossil_strdup(z);
1175 }
1176
1177 len = atoi(PD("CONTENT_LENGTH", "0"));
1178 zType = P("CONTENT_TYPE");
1179 zSemi = zType ? strchr(zType, ';') : 0;
1180 if( zSemi ){
1181 g.zContentType = fossil_strndup(zType, (int)(zSemi-zType));
1182 zType = g.zContentType;
1183 }else{
1184 g.zContentType = zType;
1185 }
1186 blob_zero(&g.cgiIn);
@@ -1695,11 +1707,11 @@
1707 if( zIpAddr==0 ){
1708 zIpAddr = cgi_remote_ip(fileno(g.httpIn));
1709 }
1710 if( zIpAddr ){
1711 cgi_setenv("REMOTE_ADDR", zIpAddr);
1712 g.zIpAddr = fossil_strdup(zIpAddr);
1713 }
1714
1715
1716 /* Get all the optional fields that follow the first line.
1717 */
@@ -1746,11 +1758,11 @@
1758 }else if( fossil_strcmp(zFieldName,"authorization:")==0 ){
1759 cgi_setenv("HTTP_AUTHORIZATION", zVal);
1760 }else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
1761 const char *zIpAddr = cgi_accept_forwarded_for(zVal);
1762 if( zIpAddr!=0 ){
1763 g.zIpAddr = fossil_strdup(zIpAddr);
1764 cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
1765 }
1766 }else if( fossil_strcmp(zFieldName,"range:")==0 ){
1767 int x1 = 0;
1768 int x2 = 0;
@@ -1786,11 +1798,11 @@
1798 if( nCycles==0 ){ json_bootstrap_early(); }
1799 #endif
1800 if( zIpAddr ){
1801 if( nCycles==0 ){
1802 cgi_setenv("REMOTE_ADDR", zIpAddr);
1803 g.zIpAddr = fossil_strdup(zIpAddr);
1804 }
1805 }else{
1806 fossil_panic("missing SSH IP address");
1807 }
1808 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
@@ -1848,11 +1860,11 @@
1860 for(i=0; zToken[i] && zToken[i]!='?'; i++){}
1861 if( zToken[i] ) zToken[i++] = 0;
1862 if( nCycles==0 ){
1863 cgi_setenv("PATH_INFO", zToken);
1864 }else{
1865 cgi_replace_parameter("PATH_INFO", fossil_strdup(zToken));
1866 }
1867
1868 /* Get all the optional fields that follow the first line.
1869 */
1870 while( fgets(zLine,sizeof(zLine),g.httpIn) ){
@@ -1870,11 +1882,11 @@
1882 zFieldName[i] = fossil_tolower(zFieldName[i]);
1883 }
1884 if( fossil_strcmp(zFieldName,"content-length:")==0 ){
1885 content_length = atoi(zVal);
1886 }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){
1887 g.zContentType = zType = fossil_strdup(zVal);
1888 }else if( fossil_strcmp(zFieldName,"host:")==0 ){
1889 if( nCycles==0 ){
1890 cgi_setenv("HTTP_HOST", zVal);
1891 }
1892 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
@@ -1947,11 +1959,11 @@
1959
1960 /* Got all probes now first transport_open is completed
1961 ** so return the command that was requested
1962 */
1963 g.fSshClient |= CGI_SSH_COMPAT;
1964 return fossil_strdup(zToken);
1965 }
1966
1967 /*
1968 ** This routine handles the old fossil SSH transport_flip
1969 ** and transport_open communications if detected.
@@ -2323,11 +2335,11 @@
2335 const char *cgi_ssh_remote_addr(const char *zDefault){
2336 char *zIndex;
2337 const char *zSshConn = fossil_getenv("SSH_CONNECTION");
2338
2339 if( zSshConn && zSshConn[0] ){
2340 char *zSshClient = fossil_strdup(zSshConn);
2341 if( (zIndex = strchr(zSshClient,' '))!=0 ){
2342 zSshClient[zIndex-zSshClient] = '\0';
2343 return zSshClient;
2344 }
2345 }
2346

Keyboard Shortcuts

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