Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch short-cgi-params Excluding Merge-Ins
This is equivalent to a diff from e09d84f297 to e89269e51b
2013-05-02
| ||
19:44 | Fix --chdir on Windows/Cygwin when using non-ascii characters or characters invalid for win32 filenames. On Cygwin, allow enter_chroot_jail() using win32 paths as well. check-in: 12bc63aae5 user: jan.nijtmans tags: trunk | |
15:04 | rebase Closed-Leaf check-in: 9e4a7190af user: jan.nijtmans tags: clean-with-ignore | |
13:52 | rebase Closed-Leaf check-in: e89269e51b user: jan.nijtmans tags: short-cgi-params | |
13:28 | Allow boolean parameters sbs= and v= to taken values like "on", "off", "yes", and "no". Assign meaningful defaults even if the argument is omitted. check-in: e09d84f297 user: drh tags: trunk | |
07:58 | See alternative implementation on trunk. Was: Improve cgi parameter parsing in add_param_list(). Boolean options, like "v" and "sbs" can now take forms like "v=true" or simply "v" (in stead of "v=1") or "v=off" (in stead of "v=0"). /timeline already accepted the shortened form, now /event, /vdiff and other web pages do as well. check-in: 71d48d346c user: jan.nijtmans tags: short-cgi-params | |
00:15 | Keep the entry boxes filled in on the hash-color-test webpage. check-in: 8d3ff5a710 user: drh tags: trunk | |
Changes to src/cgi.c.
︙ | ︙ | |||
256 257 258 259 260 261 262 | for( zTok = strtok_r(zBuf, ",\"",&zPos); zTok && fossil_stricmp(zTok,zETag); zTok = strtok_r(0, ",\"",&zPos)){} fossil_free(zBuf); if(zTok) return 1; } } | | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | for( zTok = strtok_r(zBuf, ",\"",&zPos); zTok && fossil_stricmp(zTok,zETag); zTok = strtok_r(0, ",\"",&zPos)){} fossil_free(zBuf); if(zTok) return 1; } } return 0; } #endif /* ** Do a normal HTTP reply */ |
︙ | ︙ | |||
463 464 465 466 467 468 469 | /* ** Add a query parameter. The zName portion is fixed but a copy ** must be made of zValue. */ void cgi_setenv(const char *zName, const char *zValue){ cgi_set_parameter_nocopy(zName, mprintf("%s",zValue)); } | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | /* ** Add a query parameter. The zName portion is fixed but a copy ** must be made of zValue. */ void cgi_setenv(const char *zName, const char *zValue){ cgi_set_parameter_nocopy(zName, mprintf("%s",zValue)); } /* ** Add a list of query parameters or cookies to the parameter set. ** ** Each parameter is of the form NAME=VALUE. Both the NAME and the ** VALUE may be url-encoded ("+" for space, "%HH" for other special ** characters). But this routine assumes that NAME contains no |
︙ | ︙ | |||
496 497 498 499 500 501 502 | */ static void add_param_list(char *z, int terminator){ while( *z ){ char *zName; char *zValue; while( fossil_isspace(*z) ){ z++; } zName = z; | > | | > > > | < | < < < > | | > < | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | */ static void add_param_list(char *z, int terminator){ while( *z ){ char *zName; char *zValue; while( fossil_isspace(*z) ){ z++; } zName = z; zValue = 0; while( *z ){ if( *z==terminator ){ *z++ = 0; break; } if( !zValue && (*z=='=') ){ *z = 0; zValue = z+1; } z++; } if( zValue ){ dehttpize(zValue); }else{ zValue = zName; } if( fossil_islower(zName[0]) ){ cgi_set_parameter_nocopy(zName, zValue); } #ifdef FOSSIL_ENABLE_JSON json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) ); #endif /* FOSSIL_ENABLE_JSON */ |
︙ | ︙ | |||
580 581 582 583 584 585 586 | *pnContent = i; i += nBoundry; break; } } *pz = &z[i]; get_line_from_string(pz, pLen); | | | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | *pnContent = i; i += nBoundry; break; } } *pz = &z[i]; get_line_from_string(pz, pLen); return z; } /* ** Tokenize a line of text into as many as nArg tokens. Make ** azArg[] point to the start of each token. ** ** Tokens consist of space or semi-colon delimited words or |
︙ | ︙ | |||
687 688 689 690 691 692 693 | char *z = azArg[++i]; if( zName && z && fossil_islower(zName[0]) ){ cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z); } } } } | | | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | char *z = azArg[++i]; if( zName && z && fossil_islower(zName[0]) ){ cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z); } } } } } } #ifdef FOSSIL_ENABLE_JSON /* ** Internal helper for cson_data_source_FILE_n(). */ |
︙ | ︙ | |||
831 832 833 834 835 836 837 | cgi_destination(CGI_BODY); z = (char*)P("HTTP_COOKIE"); if( z ){ z = mprintf("%s",z); add_param_list(z, ';'); } | | | | 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | cgi_destination(CGI_BODY); z = (char*)P("HTTP_COOKIE"); if( z ){ z = mprintf("%s",z); add_param_list(z, ';'); } z = (char*)P("QUERY_STRING"); if( z ){ z = mprintf("%s",z); add_param_list(z, '&'); } z = (char*)P("REMOTE_ADDR"); if( z ){ g.zIpAddr = mprintf("%s", z); } len = atoi(PD("CONTENT_LENGTH", "0")); g.zContentType = zType = P("CONTENT_TYPE"); if( len>0 && zType ){ blob_zero(&g.cgiIn); if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 || strncmp(zType,"multipart/form-data",19)==0 ){ z = fossil_malloc( len+1 ); len = fread(z, 1, len, g.httpIn); z[len] = 0; cgi_trace(z); if( zType[0]=='a' ){ add_param_list(z, '&'); |
︙ | ︙ | |||
877 878 879 880 881 882 883 | g.json.isJsonMode = 1; cgi_parse_POST_JSON(g.httpIn, (unsigned int)len); /* FIXMEs: - See if fossil really needs g.cgiIn to be set for this purpose (i don't think it does). If it does then fill g.cgiIn and refactor to parse the JSON from there. | | | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | g.json.isJsonMode = 1; cgi_parse_POST_JSON(g.httpIn, (unsigned int)len); /* FIXMEs: - See if fossil really needs g.cgiIn to be set for this purpose (i don't think it does). If it does then fill g.cgiIn and refactor to parse the JSON from there. - After parsing POST JSON, copy the "first layer" of keys/values to cgi_setenv(), honoring the upper-case distinction used in add_param_list(). However... - If we do that then we might get a disconnect in precedence of GET/POST arguments. i prefer for GET entries to take precedence over like-named POST entries, but in order for that to happen we |
︙ | ︙ | |||
1194 1195 1196 1197 1198 1199 1200 | } cgi_setenv("REQUEST_URI", zToken); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); if( zIpAddr==0 && | | | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | } cgi_setenv("REQUEST_URI", zToken); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); if( zIpAddr==0 && getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, &size)>=0 ){ zIpAddr = inet_ntoa(remoteName.sin_addr); } if( zIpAddr ){ cgi_setenv("REMOTE_ADDR", zIpAddr); g.zIpAddr = mprintf("%s", zIpAddr); } /* Get all the optional fields that follow the first line. */ while( fgets(zLine,sizeof(zLine),g.httpIn) ){ char *zFieldName; char *zVal; cgi_trace(zLine); |
︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | } } cgi_init(); cgi_trace(0); } #if INTERFACE | | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | } } cgi_init(); cgi_trace(0); } #if INTERFACE /* ** Bitmap values for the flags parameter to cgi_http_server(). */ #define HTTP_SERVER_LOCALHOST 0x0001 /* Bind to 127.0.0.1 only */ #endif /* INTERFACE */ /* |
︙ | ︙ | |||
1383 1384 1385 1386 1387 1388 1389 | } } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ){ nchildren--; } } | | | 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | } } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ){ nchildren--; } } /* NOT REACHED */ fossil_exit(1); #endif /* NOT REACHED */ return 0; } |
︙ | ︙ | |||
1471 1472 1473 1474 1475 1476 1477 | }else if( p->tm_mon>11 ){ p->tm_year += p->tm_mon/12; p->tm_mon %= 12; } isLeapYr = p->tm_year%4==0 && (p->tm_year%100!=0 || (p->tm_year+300)%400==0); p->tm_yday = priorDays[p->tm_mon] + p->tm_mday - 1; if( isLeapYr && p->tm_mon>1 ) p->tm_yday++; | | | 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 | }else if( p->tm_mon>11 ){ p->tm_year += p->tm_mon/12; p->tm_mon %= 12; } isLeapYr = p->tm_year%4==0 && (p->tm_year%100!=0 || (p->tm_year+300)%400==0); p->tm_yday = priorDays[p->tm_mon] + p->tm_mday - 1; if( isLeapYr && p->tm_mon>1 ) p->tm_yday++; nDay = (p->tm_year-70)*365 + (p->tm_year-69)/4 -p->tm_year/100 + (p->tm_year+300)/400 + p->tm_yday; t = ((nDay*24 + p->tm_hour)*60 + p->tm_min)*60 + p->tm_sec; return t; } /* ** Check the objectTime against the If-Modified-Since request header. If the |
︙ | ︙ |
Changes to src/event.c.
︙ | ︙ | |||
183 184 185 186 187 188 189 | @ <div> } blob_init(&comment, pEvent->zComment, -1); wiki_convert(&comment, 0, WIKI_INLINE); blob_reset(&comment); @ </div> @ </blockquote><hr /> | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | @ <div> } blob_init(&comment, pEvent->zComment, -1); wiki_convert(&comment, 0, WIKI_INLINE); blob_reset(&comment); @ </div> @ </blockquote><hr /> } wiki_convert(&tail, 0, 0); style_footer(); manifest_destroy(pEvent); } /* |
︙ | ︙ | |||
225 226 227 228 229 230 231 | int nEventId = strlen(zEventId); if( nEventId!=40 || !validate16(zEventId, 40) ){ fossil_redirect_home(); return; } } zTag = mprintf("event-%s", zEventId); | | | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | int nEventId = strlen(zEventId); if( nEventId!=40 || !validate16(zEventId, 40) ){ fossil_redirect_home(); return; } } zTag = mprintf("event-%s", zEventId); rid = db_int(0, "SELECT rid FROM tagxref" " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" " ORDER BY mtime DESC", zTag ); free(zTag); /* Need both check-in and wiki-write or wiki-create privileges in order |
︙ | ︙ | |||
305 306 307 308 309 310 311 | Blob tags, one; int i, j; Stmt q; char *zBlob; /* Load the tags string into a blob */ blob_zero(&tags); | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | Blob tags, one; int i, j; Stmt q; char *zBlob; /* Load the tags string into a blob */ blob_zero(&tags); blob_append(&tags, zTags, -1); /* Collapse all sequences of whitespace and "," characters into ** a single space character */ zBlob = blob_str(&tags); for(i=j=0; zBlob[i]; i++, j++){ if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){ while( fossil_isspace(zBlob[i+1]) ){ i++; } |
︙ | ︙ | |||
334 335 336 337 338 339 340 | /* Extract the tags in sorted order and make an entry in the ** artifact for each. */ db_prepare(&q, "SELECT x FROM newtags ORDER BY x"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0)); } db_finalize(&q); | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | /* Extract the tags in sorted order and make an entry in the ** artifact for each. */ db_prepare(&q, "SELECT x FROM newtags ORDER BY x"); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0)); } db_finalize(&q); } if( g.zLogin ){ blob_appendf(&event, "U %F\n", g.zLogin); } blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody); md5sum_blob(&event, &cksum); blob_appendf(&event, "Z %b\n", &cksum); blob_reset(&cksum); |
︙ | ︙ | |||
404 405 406 407 408 409 410 | @ <tr><td align="right" valign="top"><b>Event Time:</b></td> @ <td valign="top"> @ <input type="text" name="t" size="25" value="%h(zETime)" /> @ </td></tr> @ <tr><td align="right" valign="top"><b>Timeline Comment:</b></td> @ <td valign="top"> | | | | | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | @ <tr><td align="right" valign="top"><b>Event Time:</b></td> @ <td valign="top"> @ <input type="text" name="t" size="25" value="%h(zETime)" /> @ </td></tr> @ <tr><td align="right" valign="top"><b>Timeline Comment:</b></td> @ <td valign="top"> @ <textarea name="c" class="eventedit" cols="80" @ rows="3" wrap="virtual">%h(zComment)</textarea> @ </td></tr> @ <tr><td align="right" valign="top"><b>Background Color:</b></td> @ <td valign="top"> render_color_chooser(0, zClr, 0, "clr", "cclr"); @ </td></tr> @ <tr><td align="right" valign="top"><b>Tags:</b></td> @ <td valign="top"> @ <input type="text" name="g" size="40" value="%h(zTags)" /> @ </td></tr> @ <tr><td align="right" valign="top"><b>Page Content:</b></td> @ <td valign="top"> @ <textarea name="w" class="eventedit" cols="80" @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> @ </td></tr> @ <tr><td colspan="2"> @ <input type="submit" name="preview" value="Preview Your Changes" /> @ <input type="submit" name="submit" value="Apply These Changes" /> @ <input type="submit" name="cancel" value="Cancel" /> @ </td></tr></table> @ </div></form> style_footer(); } |
Changes to src/info.c.
︙ | ︙ | |||
388 389 390 391 392 393 394 | } if( diffFlags ){ @ <pre style="white-space:pre;"> append_diff(zOld, zNew, diffFlags, pRe); @ </pre> }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ @ | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | } if( diffFlags ){ @ <pre style="white-space:pre;"> append_diff(zOld, zNew, diffFlags, pRe); @ </pre> }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ @ @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a> } @ </p> } } /* ** Construct an appropriate diffFlag for text_diff() based on query |
︙ | ︙ | |||
453 454 455 456 457 458 459 460 461 462 463 464 465 466 | int verboseFlag; /* True to show diffs */ int sideBySide; /* True for side-by-side diffs */ u64 diffFlags; /* Flag parameter for text_diff() */ const char *zName; /* Name of the checkin to be displayed */ const char *zUuid; /* UUID of zName */ const char *zParent; /* UUID of the parent checkin (if any) */ const char *zRe; /* regex parameter */ ReCompiled *pRe = 0; /* regex */ login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } zName = P("name"); rid = name_to_rid_www("name"); if( rid==0 ){ | > | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | int verboseFlag; /* True to show diffs */ int sideBySide; /* True for side-by-side diffs */ u64 diffFlags; /* Flag parameter for text_diff() */ const char *zName; /* Name of the checkin to be displayed */ const char *zUuid; /* UUID of zName */ const char *zParent; /* UUID of the parent checkin (if any) */ const char *zRe; /* regex parameter */ const char *zSbs; ReCompiled *pRe = 0; /* regex */ login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } zName = P("name"); rid = name_to_rid_www("name"); if( rid==0 ){ |
︙ | ︙ | |||
482 483 484 485 486 487 488 | "SELECT uuid, datetime(mtime, 'localtime'), user, comment," " datetime(omtime, 'localtime'), mtime" " FROM blob, event" " WHERE blob.rid=%d" " AND event.objid=%d", rid, rid ); | > | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | "SELECT uuid, datetime(mtime, 'localtime'), user, comment," " datetime(omtime, 'localtime'), mtime" " FROM blob, event" " WHERE blob.rid=%d" " AND event.objid=%d", rid, rid ); zSbs = P("sbs"); /* Note that "sbs=1" is the default value */ sideBySide = (zSbs==0) || ((*zSbs!=0) && !is_false(zSbs)); if( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); char *zTitle = mprintf("Check-in [%.10s]", zUuid); char *zEUser, *zEComment; const char *zUser; const char *zComment; const char *zDate; |
︙ | ︙ | |||
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 | Manifest *pFrom, *pTo; ManifestFile *pFileFrom, *pFileTo; const char *zBranch; const char *zFrom; const char *zTo; const char *zRe; const char *zVerbose; ReCompiled *pRe = 0; login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } login_anonymous_available(); zRe = P("regex"); if( zRe ) re_compile(&pRe, zRe, 0); zBranch = P("branch"); if( zBranch && zBranch[0] ){ cgi_replace_parameter("from", mprintf("root:%s", zBranch)); cgi_replace_parameter("to", zBranch); } pTo = vdiff_parse_manifest("to", &ridTo); if( pTo==0 ) return; pFrom = vdiff_parse_manifest("from", &ridFrom); if( pFrom==0 ) return; | > > | | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 | Manifest *pFrom, *pTo; ManifestFile *pFileFrom, *pFileTo; const char *zBranch; const char *zFrom; const char *zTo; const char *zRe; const char *zVerbose; const char *zSbs; ReCompiled *pRe = 0; login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } login_anonymous_available(); zRe = P("regex"); if( zRe ) re_compile(&pRe, zRe, 0); zBranch = P("branch"); if( zBranch && zBranch[0] ){ cgi_replace_parameter("from", mprintf("root:%s", zBranch)); cgi_replace_parameter("to", zBranch); } pTo = vdiff_parse_manifest("to", &ridTo); if( pTo==0 ) return; pFrom = vdiff_parse_manifest("from", &ridFrom); if( pFrom==0 ) return; zSbs = P("sbs"); /* Note that "sbs=1" is the default value */ sideBySide = (zSbs==0) || ((*zSbs!=0) && !is_false(zSbs)); zVerbose = P("v"); if( !zVerbose ){ zVerbose = P("verbose"); } if( !zVerbose ){ zVerbose = P("detail"); /* deprecated */ } verboseFlag = (zVerbose!=0) && (*zVerbose!=0) && !is_false(zVerbose); if( !verboseFlag && sideBySide ) verboseFlag = 1; zFrom = P("from"); zTo = P("to"); if( !sideBySide ){ style_submenu_element("Side-by-side Diff", "sbsdiff", "%R/vdiff?from=%T&to=%T&sbs=1", zFrom, zTo); } if( sideBySide || !verboseFlag ) { style_submenu_element("Unified Diff", "udiff", "%R/vdiff?from=%T&to=%T%s&sbs=0&v", zFrom, zTo); } style_submenu_element("Invert", "invert", "%R/vdiff?from=%T&to=%T&sbs=%d%s", zTo, zFrom, sideBySide, (verboseFlag && !sideBySide)?"&v":""); style_header("Check-in Differences"); @ <h2>Difference From:</h2><blockquote> checkin_description(ridFrom); @ </blockquote><h2>To:</h2><blockquote> checkin_description(ridTo); @ </blockquote> if( pRe ){ |
︙ | ︙ | |||
1244 1245 1246 1247 1248 1249 1250 | void diff_page(void){ int v1, v2; int isPatch; int sideBySide; Blob c1, c2, diff, *pOut; char *zV1; char *zV2; | | > | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 | void diff_page(void){ int v1, v2; int isPatch; int sideBySide; Blob c1, c2, diff, *pOut; char *zV1; char *zV2; const char *zRe, *zSbs; ReCompiled *pRe = 0; u64 diffFlags; const char *zStyle = "sbsdiff"; login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } v1 = name_to_rid_www("v1"); v2 = name_to_rid_www("v2"); if( v1==0 || v2==0 ) fossil_redirect_home(); zSbs = P("sbs"); /* Note that "sbs=1" is the default value */ sideBySide = (zSbs==0) || ((*zSbs!=0) && !is_false(zSbs)); zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); isPatch = P("patch")!=0; if( isPatch ){ pOut = cgi_output_blob(); cgi_set_content_type("text/plain"); diffFlags = 4; |
︙ | ︙ |