Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Emit only \n, not \r\n, even in places where protocols technically require a full \r\n. Provide a compile-time option -DSEND_CR=1 that includes the CRs when necessary. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | omit-cr |
| Files: | files | file ages | folders |
| SHA3-256: |
0dcce257b04e2bfb8f85bd5ecda8cc90 |
| User & Date: | drh 2024-10-12 12:03:48.877 |
Context
|
2024-10-12
| ||
| 22:12 | Add a experimental 'open in /pikchrshow' link beneath the source code view of rendered pikchrs. This has only been tested in the forum view and needs further experimentation, and perhaps a way to disable it, in other views. ... (check-in: ca27e69179 user: stephan tags: omit-cr) | |
| 12:03 | Emit only \n, not \r\n, even in places where protocols technically require a full \r\n. Provide a compile-time option -DSEND_CR=1 that includes the CRs when necessary. ... (check-in: 0dcce257b0 user: drh tags: omit-cr) | |
| 11:10 | Update the built-in SQLite to the latest 3.47.0 beta for testing. ... (check-in: 753bf7d57a user: drh tags: trunk) | |
Changes
Changes to src/ajax.c.
| ︙ | ︙ | |||
336 337 338 339 340 341 342 |
case AJAX_RENDER_HTML_INLINE: zRenderMode = "htmlInline"; break;
case AJAX_RENDER_HTML_IFRAME: zRenderMode = "htmlIframe"; break;
case AJAX_RENDER_PLAIN_TEXT: zRenderMode = "text"; break;
case AJAX_RENDER_GUESS:
assert(!"cannot happen");
}
if(zRenderMode!=0){
| | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
case AJAX_RENDER_HTML_INLINE: zRenderMode = "htmlInline"; break;
case AJAX_RENDER_HTML_IFRAME: zRenderMode = "htmlIframe"; break;
case AJAX_RENDER_PLAIN_TEXT: zRenderMode = "text"; break;
case AJAX_RENDER_GUESS:
assert(!"cannot happen");
}
if(zRenderMode!=0){
cgi_printf_header("x-ajax-render-mode: %s" CRLF, zRenderMode);
}
}
#if INTERFACE
/*
** Internal mapping of ajax sub-route names to various metadata.
*/
|
| ︙ | ︙ |
Changes to src/alerts.c.
| ︙ | ︙ | |||
435 436 437 438 439 440 441 |
static void append_base64(Blob *pOut, Blob *pMsg){
int n, i, k;
char zBuf[100];
n = blob_size(pMsg);
for(i=0; i<n; i+=54){
k = translateBase64(blob_buffer(pMsg)+i, i+54<n ? 54 : n-i, zBuf);
blob_append(pOut, zBuf, k);
| | | | | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
static void append_base64(Blob *pOut, Blob *pMsg){
int n, i, k;
char zBuf[100];
n = blob_size(pMsg);
for(i=0; i<n; i+=54){
k = translateBase64(blob_buffer(pMsg)+i, i+54<n ? 54 : n-i, zBuf);
blob_append(pOut, zBuf, k);
blob_append(pOut, CRLF, CRLF_SZ);
}
}
#endif
/*
** Encode pMsg using the quoted-printable email encoding and
** append it onto pOut
*/
static void append_quoted(Blob *pOut, Blob *pMsg){
char *zIn = blob_str(pMsg);
char c;
int iCol = 0;
while( (c = *(zIn++))!=0 ){
if( (c>='!' && c<='~' && c!='=' && c!=':')
|| (c==' ' && zIn[0]!='\r' && zIn[0]!='\n')
){
blob_append_char(pOut, c);
iCol++;
if( iCol>=70 ){
blob_append(pOut, "=" CRLF, CRLF_SZ+1);
iCol = 0;
}
}else if( c=='\r' && zIn[0]=='\n' ){
zIn++;
blob_append(pOut, CRLF, CRLF_SZ);
iCol = 0;
}else if( c=='\n' ){
blob_append(pOut, CRLF, CRLF_SZ);
iCol = 0;
}else{
char x[3];
x[0] = '=';
x[1] = "0123456789ABCDEF"[(c>>4)&0xf];
x[2] = "0123456789ABCDEF"[c&0xf];
blob_append(pOut, x, 3);
|
| ︙ | ︙ | |||
958 959 960 961 962 963 964 |
}else{
pOut = &all;
}
blob_append(pOut, blob_buffer(pHdr), blob_size(pHdr));
if( p->zFrom==0 || p->zFrom[0]==0 ){
return; /* email-self is not set. Error will be reported separately */
}else if( zFromName ){
| | | | | | | | | | | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 |
}else{
pOut = &all;
}
blob_append(pOut, blob_buffer(pHdr), blob_size(pHdr));
if( p->zFrom==0 || p->zFrom[0]==0 ){
return; /* email-self is not set. Error will be reported separately */
}else if( zFromName ){
blob_appendf(pOut, "From: %s <%s@%s>" CRLF,
zFromName, alert_mailbox_name(zFromName), alert_hostname(p->zFrom));
blob_appendf(pOut, "Sender: <%s>" CRLF, p->zFrom);
}else{
blob_appendf(pOut, "From: <%s>" CRLF, p->zFrom);
}
blob_appendf(pOut, "Date: %z" CRLF, cgi_rfc822_datestamp(time(0)));
if( p->zListId && p->zListId[0] ){
blob_appendf(pOut, "List-Id: %s" CRLF, p->zListId);
}
if( strstr(blob_str(pHdr), CRLF "Message-Id:")==0 ){
/* Message-id format: "<$(date)x$(random)@$(from-host)>" where $(date) is
** the current unix-time in hex, $(random) is a 64-bit random number,
** and $(from) is the domain part of the email-self setting. */
sqlite3_randomness(sizeof(r1), &r1);
r2 = time(0);
blob_appendf(pOut, "Message-Id: <%llxx%016llx@%s>" CRLF,
r2, r1, alert_hostname(p->zFrom));
}
blob_add_final_newline(pBody);
blob_appendf(pOut, "MIME-Version: 1.0" CRLF);
blob_appendf(pOut, "Content-Type: text/plain; charset=\"UTF-8\"" CRLF);
#if 0
blob_appendf(pOut, "Content-Transfer-Encoding: base64" CRLF CRLF);
append_base64(pOut, pBody);
#else
blob_appendf(pOut, "Content-Transfer-Encoding: quoted-printable" CRLF CRLF);
append_quoted(pOut, pBody);
#endif
if( p->pStmt ){
int i, rc;
sqlite3_bind_text(p->pStmt, 1, blob_str(&all), -1, SQLITE_TRANSIENT);
for(i=0; i<100 && sqlite3_step(p->pStmt)==SQLITE_BUSY; i++){
sqlite3_sleep(10);
|
| ︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 |
}
}else if( strcmp(p->zDest, "stdout")==0 ){
char **azTo = 0;
int nTo = 0;
int i;
email_header_to(pHdr, &nTo, &azTo);
for(i=0; i<nTo; i++){
| | | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 |
}
}else if( strcmp(p->zDest, "stdout")==0 ){
char **azTo = 0;
int nTo = 0;
int i;
email_header_to(pHdr, &nTo, &azTo);
for(i=0; i<nTo; i++){
fossil_print("X-To-Test-%d: [%s]" CRLF, i, azTo[i]);
}
email_header_to_free(nTo, azTo);
blob_add_final_newline(&all);
fossil_print("%s", blob_str(&all));
}
blob_reset(&all);
}
|
| ︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 |
blob_init(&body, 0, 0);
blob_init(&hdr, 0, 0);
blob_appendf(&hdr,"To: ");
for(i=3; i<g.argc; i++){
if( i>3 ) blob_append(&hdr, ", ", 2);
blob_appendf(&hdr, "<%s>", g.argv[i]);
}
| | | | 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
blob_init(&body, 0, 0);
blob_init(&hdr, 0, 0);
blob_appendf(&hdr,"To: ");
for(i=3; i<g.argc; i++){
if( i>3 ) blob_append(&hdr, ", ", 2);
blob_appendf(&hdr, "<%s>", g.argv[i]);
}
blob_append(&hdr, CRLF, CRLF_SZ);
if( zSubject==0 ) zSubject = "fossil alerts test-message";
blob_appendf(&hdr, "Subject: %s" CRLF, zSubject);
if( zSource ){
blob_read_from_file(&body, zSource, ExtFILE);
}else{
prompt_for_user_comment(&body, &prompt);
}
blob_add_final_newline(&body);
pSender = alert_sender_new(zDest, mFlags);
|
| ︙ | ︙ | |||
2312 2313 2314 2315 2316 2317 2318 |
if( bSubmit ){
/* If we get this far, it means that a valid unsubscribe request has
** been submitted. Send the appropriate email. */
Blob hdr, body;
AlertSender *pSender = alert_sender_new(0,0);
blob_init(&hdr,0,0);
blob_init(&body,0,0);
| | | | 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 |
if( bSubmit ){
/* If we get this far, it means that a valid unsubscribe request has
** been submitted. Send the appropriate email. */
Blob hdr, body;
AlertSender *pSender = alert_sender_new(0,0);
blob_init(&hdr,0,0);
blob_init(&body,0,0);
blob_appendf(&hdr, "To: <%s>" CRLF, zEAddr);
blob_appendf(&hdr, "Subject: Unsubscribe Instructions" CRLF);
blob_appendf(&body, zUnsubMsg/*works-like:"%s%s%s%s%s%s"*/,
g.zBaseURL, g.zBaseURL, zCode, g.zBaseURL, g.zBaseURL, zCode);
alert_send(pSender, &hdr, &body, 0);
style_header("Unsubscribe Instructions Sent");
if( pSender->zErr ){
@ <h1>Internal Error</h1>
@ <p>The following error was encountered while trying to send an
|
| ︙ | ︙ | |||
2737 2738 2739 2740 2741 2742 2743 |
p->zFromName = z && z[0] ? fossil_strdup(z) : 0;
p->zPriors = alert_compute_priors(fpid);
p->pNext = 0;
blob_init(&p->hdr, 0, 0);
zUuid = db_column_text(&q, 1);
zTitle = db_column_text(&q, 3);
if( p->needMod ){
| | | | | | 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 |
p->zFromName = z && z[0] ? fossil_strdup(z) : 0;
p->zPriors = alert_compute_priors(fpid);
p->pNext = 0;
blob_init(&p->hdr, 0, 0);
zUuid = db_column_text(&q, 1);
zTitle = db_column_text(&q, 3);
if( p->needMod ){
blob_appendf(&p->hdr, "Subject: %s Pending Moderation: %s" CRLF,
zSub, zTitle);
}else{
blob_appendf(&p->hdr, "Subject: %s %s" CRLF, zSub, zTitle);
blob_appendf(&p->hdr, "Message-Id: <%.32s@%s>" CRLF,
zUuid, alert_hostname(zFrom));
zIrt = db_column_text(&q, 4);
if( zIrt && zIrt[0] ){
blob_appendf(&p->hdr, "In-Reply-To: <%.32s@%s>" CRLF,
zIrt, alert_hostname(zFrom));
}
}
blob_init(&p->txt, 0, 0);
if( p->needMod ){
blob_appendf(&p->txt,
"** Pending moderator approval (%s/modreq) **\n",
|
| ︙ | ︙ | |||
2913 2914 2915 2916 2917 2918 2919 |
const char *zCode, /* The subscriber code */
int lastContact, /* Last contact (days since 1970) */
const char *zEAddr, /* Subscriber email address. Send to this. */
const char *zSub, /* Subscription codes */
const char *zRepoName, /* Name of the sending Fossil repostory */
const char *zUrl /* URL for the sending Fossil repostory */
){
| | | | 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 |
const char *zCode, /* The subscriber code */
int lastContact, /* Last contact (days since 1970) */
const char *zEAddr, /* Subscriber email address. Send to this. */
const char *zSub, /* Subscription codes */
const char *zRepoName, /* Name of the sending Fossil repostory */
const char *zUrl /* URL for the sending Fossil repostory */
){
blob_appendf(pHdr,"To: <%s>" CRLF, zEAddr);
blob_appendf(pHdr,"Subject: %s Subscription to %s expires soon" CRLF,
zRepoName, zUrl);
blob_appendf(pBody,
"\nTo renew your subscription, click the following link:\n"
"\n %s/renew/%s\n\n",
zUrl, zCode
);
blob_appendf(pBody,
|
| ︙ | ︙ | |||
3165 3166 3167 3168 3169 3170 3171 |
}
if( strchr(zCap,xType)==0 ) continue;
}
if( blob_size(&p->hdr)>0 ){
/* This alert should be sent as a separate email */
Blob fhdr, fbody;
blob_init(&fhdr, 0, 0);
| | | | | | | | | 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 |
}
if( strchr(zCap,xType)==0 ) continue;
}
if( blob_size(&p->hdr)>0 ){
/* This alert should be sent as a separate email */
Blob fhdr, fbody;
blob_init(&fhdr, 0, 0);
blob_appendf(&fhdr, "To: <%s>" CRLF, zEmail);
blob_append(&fhdr, blob_buffer(&p->hdr), blob_size(&p->hdr));
blob_init(&fbody, blob_buffer(&p->txt), blob_size(&p->txt));
blob_appendf(&fhdr, "List-Unsubscribe: <%s/oneclickunsub/%s>" CRLF,
zUrl, zCode);
blob_appendf(&fhdr,
"List-Unsubscribe-Post: List-Unsubscribe=One-Click" CRLF);
blob_appendf(&fbody, "\n-- \nUnsubscribe: %s/unsubscribe/%s\n",
zUrl, zCode);
/* blob_appendf(&fbody, "Subscription settings: %s/alerts/%s\n",
** zUrl, zCode); */
alert_send(pSender,&fhdr,&fbody,p->zFromName);
nSent++;
blob_reset(&fhdr);
blob_reset(&fbody);
}else{
/* Events other than forum posts are gathered together into
** a single email message */
if( nHit==0 ){
blob_appendf(&hdr,"To: <%s>" CRLF, zEmail);
blob_appendf(&hdr,"Subject: %s activity alert" CRLF, zRepoName);
blob_appendf(&body,
"This is an automated email sent by the Fossil repository "
"at %s to report changes.\n",
zUrl
);
}
nHit++;
blob_append(&body, "\n", 1);
blob_append(&body, blob_buffer(&p->txt), blob_size(&p->txt));
}
}
if( nHit==0 ) continue;
blob_appendf(&hdr, "List-Unsubscribe: <%s/oneclickunsub/%s>" CRLF,
zUrl, zCode);
blob_appendf(&hdr, "List-Unsubscribe-Post: List-Unsubscribe=One-Click"CRLF);
blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n",
zUrl, zCode);
alert_send(pSender,&hdr,&body,0);
nSent++;
blob_truncate(&hdr, 0);
blob_truncate(&body, 0);
}
|
| ︙ | ︙ | |||
3330 3331 3332 3333 3334 3335 3336 |
&& P("from")!=0
&& cgi_csrf_safe(2)
&& captcha_is_correct(0)
){
Blob hdr, body;
AlertSender *pSender = alert_sender_new(0,0);
blob_init(&hdr, 0, 0);
| | | 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 |
&& P("from")!=0
&& cgi_csrf_safe(2)
&& captcha_is_correct(0)
){
Blob hdr, body;
AlertSender *pSender = alert_sender_new(0,0);
blob_init(&hdr, 0, 0);
blob_appendf(&hdr, "To: <%s>" CRLF "Subject: %s administrator message" CRLF,
zAdminEmail, db_get("email-subname","Fossil Repo"));
blob_init(&body, 0, 0);
blob_appendf(&body, "Message from [%s]\n", PT("from")/*safe-for-%s*/);
blob_appendf(&body, "Subject: [%s]\n\n", PT("subject")/*safe-for-%s*/);
blob_appendf(&body, "%s", PT("msg")/*safe-for-%s*/);
alert_send(pSender, &hdr, &body, 0);
style_header("Message Sent");
|
| ︙ | ︙ | |||
3420 3421 3422 3423 3424 3425 3426 |
int bTest2 = fossil_strcmp(P("name"),"test2")==0;
Blob hdr, body;
blob_init(&body, 0, 0);
blob_init(&hdr, 0, 0);
blob_appendf(&body, "%s", PT("msg")/*safe-for-%s*/);
pSender = alert_sender_new(bTest2 ? "blob" : 0, 0);
if( zTo[0] ){
| | > > | 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 |
int bTest2 = fossil_strcmp(P("name"),"test2")==0;
Blob hdr, body;
blob_init(&body, 0, 0);
blob_init(&hdr, 0, 0);
blob_appendf(&body, "%s", PT("msg")/*safe-for-%s*/);
pSender = alert_sender_new(bTest2 ? "blob" : 0, 0);
if( zTo[0] ){
blob_appendf(&hdr, "To: <%s>" CRLF
"Subject: %s %s" CRLF,
zTo, zSub, zSubject);
alert_send(pSender, &hdr, &body, 0);
}
if( bAll || bAA || bMods ){
Stmt q;
int nUsed = blob_size(&body);
const char *zURL = db_get("email-url",0);
if( bAll ){
|
| ︙ | ︙ | |||
3446 3447 3448 3449 3450 3451 3452 |
" AND suname=login"
" AND fullcap(cap) GLOB '*5*'");
}
while( db_step(&q)==SQLITE_ROW ){
const char *zCode = db_column_text(&q, 1);
zTo = db_column_text(&q, 0);
blob_truncate(&hdr, 0);
| | > > | 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 |
" AND suname=login"
" AND fullcap(cap) GLOB '*5*'");
}
while( db_step(&q)==SQLITE_ROW ){
const char *zCode = db_column_text(&q, 1);
zTo = db_column_text(&q, 0);
blob_truncate(&hdr, 0);
blob_appendf(&hdr, "To: <%s>" CRLF
"Subject: %s %s" CRLF,
zTo, zSub, zSubject);
if( zURL ){
blob_truncate(&body, nUsed);
blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n",
zURL, zCode);
}
alert_send(pSender, &hdr, &body, 0);
}
|
| ︙ | ︙ |
Changes to src/captcha.c.
| ︙ | ︙ | |||
800 801 802 803 804 805 806 |
}
captcha_generate(3);
@ </form>
if( !bTest ){
if( P("fossil-goto")==0 ){
cgi_set_cookie("fossil-goto", cgi_reconstruct_original_url(), 0, 600);
}
| | | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
}
captcha_generate(3);
@ </form>
if( !bTest ){
if( P("fossil-goto")==0 ){
cgi_set_cookie("fossil-goto", cgi_reconstruct_original_url(), 0, 600);
}
cgi_append_header("X-Robot: 1" CRLF);
style_finish_page();
}
return 1;
}
/*
** WEBPAGE: ityaar
|
| ︙ | ︙ | |||
824 825 826 827 828 829 830 |
int bTest = atoi(PD("istest","0"));
if( captcha_is_correct(1) ){
if( bTest==0 ){
if( !login_cookie_wellformed() ){
/* ^^^^--- Don't overwrite a valid login on another repo! */
login_set_anon_cookie(0, 0);
}
| | | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 |
int bTest = atoi(PD("istest","0"));
if( captcha_is_correct(1) ){
if( bTest==0 ){
if( !login_cookie_wellformed() ){
/* ^^^^--- Don't overwrite a valid login on another repo! */
login_set_anon_cookie(0, 0);
}
cgi_append_header("X-Robot: 0" CRLF);
}
login_redirect_to_g();
}else{
g.isHuman = 0;
(void)exclude_spiders(bTest);
if( bTest ){
@ <hr><p>Wrong code. Try again
|
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
314 315 316 317 318 319 320 |
if( zPath[0]==0 ) zPath = "/";
}
if( g.zBaseURL!=0 && fossil_strncmp(g.zBaseURL, "https:", 6)==0 ){
zSecure = " secure;";
}
if( lifetime!=0 ){
blob_appendf(&extraHeader,
| | | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
if( zPath[0]==0 ) zPath = "/";
}
if( g.zBaseURL!=0 && fossil_strncmp(g.zBaseURL, "https:", 6)==0 ){
zSecure = " secure;";
}
if( lifetime!=0 ){
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly; %s" CRLF,
zName, lifetime>0 ? zValue : "null", zPath, lifetime, zSecure);
}else{
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; HttpOnly; %s" CRLF,
zName, zValue, zPath, zSecure);
}
}
/*
** Return true if the response should be sent with Content-Encoding: gzip.
|
| ︙ | ︙ | |||
487 488 489 490 491 492 493 |
if( rangeEnd>0
&& iReplyStatus==200
&& fossil_strcmp(P("REQUEST_METHOD"),"GET")==0
){
iReplyStatus = 206;
zReplyStatus = "Partial Content";
}
| | | | | | | | | | | | | | | | | | | 487 488 489 490 491 492 493 494 495 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 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 |
if( rangeEnd>0
&& iReplyStatus==200
&& fossil_strcmp(P("REQUEST_METHOD"),"GET")==0
){
iReplyStatus = 206;
zReplyStatus = "Partial Content";
}
blob_appendf(&hdr, "HTTP/1.0 %d %s" CRLF, iReplyStatus, zReplyStatus);
blob_appendf(&hdr, "Date: %s" CRLF, cgi_rfc822_datestamp(time(0)));
blob_appendf(&hdr, "Connection: close" CRLF);
blob_appendf(&hdr, "X-UA-Compatible: IE=edge" CRLF);
}else{
assert( rangeEnd==0 );
blob_appendf(&hdr, "Status: %d %s" CRLF, iReplyStatus, zReplyStatus);
}
if( etag_tag()[0]!=0
&& iReplyStatus==200
&& strcmp(zContentType,"text/html")!=0
){
/* Do not cache HTML replies as those will have been generated and
** will likely, therefore, contains a nonce and we want that nonce to
** be different every time. */
blob_appendf(&hdr, "ETag: %s" CRLF, etag_tag());
blob_appendf(&hdr, "Cache-Control: max-age=%d" CRLF, etag_maxage());
if( etag_mtime()>0 ){
blob_appendf(&hdr, "Last-Modified: %s" CRLF,
cgi_rfc822_datestamp(etag_mtime()));
}
}else if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
** after configuration changes and/or Fossil binary recompiles. */
blob_appendf(&hdr, "Cache-Control: max-age=315360000, immutable" CRLF);
}else{
blob_appendf(&hdr, "Cache-control: no-cache" CRLF);
}
if( blob_size(&extraHeader)>0 ){
blob_appendf(&hdr, "%s", blob_buffer(&extraHeader));
}
/* Add headers to turn on useful security options in browsers. */
blob_appendf(&hdr, "X-Frame-Options: SAMEORIGIN" CRLF);
/* The previous stops fossil pages appearing in frames or iframes, preventing
** click-jacking attacks on supporting browsers.
**
** Other good headers would be
** Strict-Transport-Security: max-age=62208000
** if we're using https. However, this would break sites which serve different
** content on http and https protocols. Also,
** X-Content-Security-Policy: allow 'self'
** would help mitigate some XSS and data injection attacks, but will break
** deliberate inclusion of external resources, such as JavaScript syntax
** highlighter scripts.
**
** These headers are probably best added by the web server hosting fossil as
** a CGI script.
*/
if( iReplyStatus!=304 ) {
blob_appendf(&hdr, "Content-Type: %s%s" CRLF, zContentType,
content_type_charset(zContentType));
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
cgi_combine_header_and_body();
blob_compress(&cgiContent[0], &cgiContent[0]);
}
if( is_gzippable() && iReplyStatus!=206 ){
int i;
gzip_begin(0);
for( i=0; i<2; i++ ){
int size = blob_size(&cgiContent[i]);
if( size>0 ) gzip_step(blob_buffer(&cgiContent[i]), size);
blob_reset(&cgiContent[i]);
}
gzip_finish(&cgiContent[0]);
blob_appendf(&hdr, "Content-Encoding: gzip" CRLF);
blob_appendf(&hdr, "Vary: Accept-Encoding" CRLF);
}
total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]);
if( iReplyStatus==206 ){
blob_appendf(&hdr, "Content-Range: bytes %d-%d/%d" CRLF,
rangeStart, rangeEnd-1, total_size);
total_size = rangeEnd - rangeStart;
}
blob_appendf(&hdr, "Content-Length: %d" CRLF, total_size);
}else{
total_size = 0;
}
blob_appendf(&hdr, CRLF);
cgi_fwrite(blob_buffer(&hdr), blob_size(&hdr));
blob_reset(&hdr);
if( total_size>0
&& iReplyStatus!=304
&& fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
){
int i, size;
|
| ︙ | ︙ | |||
618 619 620 621 622 623 624 |
int iStat,
const char *zStat
){
char *zLocation;
CGIDEBUG(("redirect to %s\n", zURL));
if( fossil_strncmp(zURL,"http:",5)==0
|| fossil_strncmp(zURL,"https:",6)==0 ){
| | | | | 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
int iStat,
const char *zStat
){
char *zLocation;
CGIDEBUG(("redirect to %s\n", zURL));
if( fossil_strncmp(zURL,"http:",5)==0
|| fossil_strncmp(zURL,"https:",6)==0 ){
zLocation = mprintf("Location: %s" CRLF, zURL);
}else if( *zURL=='/' ){
int n1 = (int)strlen(g.zBaseURL);
int n2 = (int)strlen(g.zTop);
if( g.zBaseURL[n1-1]=='/' ) zURL++;
zLocation = mprintf("Location: %.*s%s" CRLF, n1-n2, g.zBaseURL, zURL);
}else{
zLocation = mprintf("Location: %s/%s" CRLF, g.zBaseURL, zURL);
}
cgi_append_header(zLocation);
cgi_reset_content();
cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zLocation);
cgi_set_status(iStat, zStat);
free(zLocation);
cgi_reply();
|
| ︙ | ︙ | |||
656 657 658 659 660 661 662 |
** Add a "Content-disposition: attachment; filename=%s" header to the reply.
*/
void cgi_content_disposition_filename(const char *zFilename){
char *z;
int i, n;
/* 0123456789 123456789 123456789 123456789 123456*/
| | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 |
** Add a "Content-disposition: attachment; filename=%s" header to the reply.
*/
void cgi_content_disposition_filename(const char *zFilename){
char *z;
int i, n;
/* 0123456789 123456789 123456789 123456789 123456*/
z = mprintf("Content-Disposition: attachment; filename=\"%s\";" CRLF,
file_tail(zFilename));
n = (int)strlen(z);
for(i=43; i<n-4; i++){
char c = z[i];
if( fossil_isalnum(c) ) continue;
if( c=='.' || c=='-' || c=='/' ) continue;
z[i] = '_';
|
| ︙ | ︙ | |||
1012 1013 1014 1015 1016 1017 1018 | } *pz = &z[i]; *pLen -= i; return z; } /* | | | 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | } *pz = &z[i]; *pLen -= i; return z; } /* ** The input *pz points to content that is terminated by a \n or \r\n ** followed by the boundary marker zBoundary. An extra "--" may or ** may not be appended to the boundary marker. There are *pLen characters ** in *pz. ** ** This routine adds a "\000" to the end of the content (overwriting ** the "\r\n") and returns a pointer to the content. The *pz input ** is adjusted to point to the first line following the boundary. |
| ︙ | ︙ |
Changes to src/chat.c.
| ︙ | ︙ | |||
1300 1301 1302 1303 1304 1305 1306 |
sqlite3_randomness(sizeof(r),r);
sqlite3_snprintf(sizeof(zBoundary),zBoundary,
"--------%016llu%016llu%016llu", r[0], r[1], r[2]);
blob_appendf(&up, "%s", zBoundary);
zLMTime = db_text(0,
"SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S','now','localtime')");
if( zLMTime ){
| > | > | > | > | > | > | > | > | > | | | | | | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
sqlite3_randomness(sizeof(r),r);
sqlite3_snprintf(sizeof(zBoundary),zBoundary,
"--------%016llu%016llu%016llu", r[0], r[1], r[2]);
blob_appendf(&up, "%s", zBoundary);
zLMTime = db_text(0,
"SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S','now','localtime')");
if( zLMTime ){
blob_appendf(&up,
CRLF "Content-Disposition: form-data; name=\"lmtime\"" CRLF
CRLF "%z" CRLF "%s",
zLMTime, zBoundary);
}
if( g.url.user && g.url.user[0] ){
blob_appendf(&up,
CRLF "Content-Disposition: form-data; name=\"resid\"" CRLF
CRLF "%z" CRLF "%s",
obscure(g.url.user), zBoundary);
}
zPw = g.url.passwd;
if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
if( zPw && zPw[0] ){
blob_appendf(&up,
CRLF "Content-Disposition: form-data; name=\"token\"" CRLF
CRLF "%z" CRLF "%s",
obscure(zPw), zBoundary);
}
if( zMsg && zMsg[0] ){
blob_appendf(&up,
CRLF "Content-Disposition: form-data; name=\"msg\"" CRLF
CRLF "%s" CRLF "%s",
zMsg, zBoundary);
}
if( zFilename && blob_read_from_file(&fcontent, zFilename, ExtFILE)>0 ){
char *zFN = mprintf("%s", file_tail(zAs ? zAs : zFilename));
int i;
const char *zMime = mimetype_from_name(zFN);
for(i=0; zFN[i]; i++){
char c = zFN[i];
if( fossil_isalnum(c) ) continue;
if( c=='.' ) continue;
if( c=='-' ) continue;
zFN[i] = '_';
}
blob_appendf(&up,
CRLF "Content-Disposition: form-data; name=\"file\";"
" filename=\"%s\"" CRLF, zFN);
blob_appendf(&up,"Content-Type: %s" CRLF CRLF, zMime);
blob_append(&up, fcontent.aData, fcontent.nUsed);
blob_appendf(&up,CRLF "%s", zBoundary);
}
blob_append(&up,"--" CRLF, CRLF_SZ+2);
http_exchange(&up, &down, mFlags, 4, "multipart/form-data");
blob_reset(&up);
if( sqlite3_strglob("{\"isError\": true,*", blob_str(&down))==0 ){
if( strstr(blob_str(&down), "not logged in")!=0 ){
fossil_print("ERROR: username and/or password is incorrect\n");
}else{
fossil_print("ERROR: %s\n", blob_str(&down));
|
| ︙ | ︙ |
Changes to src/config.h.
| ︙ | ︙ | |||
264 265 266 267 268 269 270 271 272 273 274 275 276 277 | /* ** Number of elements in an array */ #define count(X) (int)(sizeof(X)/sizeof(X[0])) #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) /* ** The pledge() interface is currently only available on OpenBSD 5.9 ** and later. Make calls to fossil_pledge() no-ops on all platforms ** that omit the HAVE_PLEDGE configuration parameter. */ #if !defined(HAVE_PLEDGE) # define fossil_pledge(A) | > > > > > > > > > > > > > > > > > > > | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | /* ** Number of elements in an array */ #define count(X) (int)(sizeof(X)/sizeof(X[0])) #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) /* ** Fossil normally only sends a \n, not a full \r\n, for line endings ** even on protocols that specifically require \r\n (HTTP, SMTP, etc.) ** This is in rebellion to the silliness that is \r\n. Everybody ** understands a bare \n. Fossil deliberately violates the spec in an ** attempt to promote change. ** ** If you prefer to follow the protocol exactly, compile with -DSEND_CR=1 */ #if defined(SEND_CR) && SEND_CR+0>=1 /* This case for strict compliance */ # define CRLF "\r\n" # define CRLF_SZ 2 #else /* Default: Send only \n */ # define CRLF "\n" # define CRLF_SZ 1 #endif /* ** The pledge() interface is currently only available on OpenBSD 5.9 ** and later. Make calls to fossil_pledge() no-ops on all platforms ** that omit the HAVE_PLEDGE configuration parameter. */ #if !defined(HAVE_PLEDGE) # define fossil_pledge(A) |
| ︙ | ︙ |
Changes to src/extcgi.c.
| ︙ | ︙ | |||
333 334 335 336 337 338 339 |
}else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
int j;
for(i=13; fossil_isspace(zLine[i]); i++){}
for(j=i; zLine[j] && zLine[j]!=';'; j++){}
zMime = mprintf("%.*s", j-i, &zLine[i]);
}else{
cgi_append_header(zLine);
| | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
}else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
int j;
for(i=13; fossil_isspace(zLine[i]); i++){}
for(j=i; zLine[j] && zLine[j]!=';'; j++){}
zMime = mprintf("%.*s", j-i, &zLine[i]);
}else{
cgi_append_header(zLine);
cgi_append_header(CRLF);
}
}
}
blob_read_from_channel(&reply, fromChild, nContent);
zFailReason = 0; /* Indicate success */
ext_not_found:
|
| ︙ | ︙ |
Changes to src/fileedit.c.
| ︙ | ︙ | |||
1063 1064 1065 1066 1067 1068 1069 |
}
{ /* Send the is-exec bit via response header so that the UI can be
** updated to account for that. */
int fperm = 0;
char * zFuuid = fileedit_file_uuid(zFilename, vid, &fperm);
const char * zPerm = mfile_permint_mstring(fperm);
assert(zFuuid);
| | | | 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 |
}
{ /* Send the is-exec bit via response header so that the UI can be
** updated to account for that. */
int fperm = 0;
char * zFuuid = fileedit_file_uuid(zFilename, vid, &fperm);
const char * zPerm = mfile_permint_mstring(fperm);
assert(zFuuid);
cgi_printf_header("x-fileedit-file-perm:%s" CRLF, zPerm);
fossil_free(zFuuid);
}
{ /* Send branch name via response header for UI usability reasons */
char * zBranch = branch_of_rid(vid);
if(zBranch!=0 && zBranch[0]!=0){
cgi_printf_header("x-fileedit-checkin-branch: %s" CRLF, zBranch);
}
fossil_free(zBranch);
}
cgi_set_content_type(zMime);
cgi_set_content(&content);
}
|
| ︙ | ︙ |
Changes to src/http.c.
| ︙ | ︙ | |||
135 136 137 138 139 140 141 |
Blob *pPayload, /* the payload that will be sent */
Blob *pHdr, /* construct the header here */
const char *zAltMimetype /* Alternative mimetype */
){
int nPayload = pPayload ? blob_size(pPayload) : 0;
blob_zero(pHdr);
| | | | | | | | | | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
Blob *pPayload, /* the payload that will be sent */
Blob *pHdr, /* construct the header here */
const char *zAltMimetype /* Alternative mimetype */
){
int nPayload = pPayload ? blob_size(pPayload) : 0;
blob_zero(pHdr);
blob_appendf(pHdr, "%s %s%s HTTP/1.0" CRLF,
nPayload>0 ? "POST" : "GET", g.url.path,
g.url.path[0]==0 ? "/" : "");
if( g.url.proxyAuth ){
blob_appendf(pHdr, "Proxy-Authorization: %s" CRLF, g.url.proxyAuth);
}
if( g.zHttpAuth && g.zHttpAuth[0] ){
const char *zCredentials = g.zHttpAuth;
char *zEncoded = encode64(zCredentials, -1);
blob_appendf(pHdr, "Authorization: Basic %s" CRLF, zEncoded);
fossil_free(zEncoded);
}
blob_appendf(pHdr, "Host: %s" CRLF, g.url.hostname);
blob_appendf(pHdr, "User-Agent: %s" CRLF, get_user_agent());
if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH" CRLF);
if( nPayload ){
if( zAltMimetype ){
blob_appendf(pHdr, "Content-Type: %s" CRLF, zAltMimetype);
}else if( g.fHttpTrace ){
blob_appendf(pHdr, "Content-Type: application/x-fossil-debug" CRLF);
}else{
blob_appendf(pHdr, "Content-Type: application/x-fossil" CRLF);
}
blob_appendf(pHdr, "Content-Length: %d" CRLF, blob_size(pPayload));
}
blob_append(pHdr, CRLF, CRLF_SZ);
}
/*
** Use Fossil credentials for HTTP Basic Authorization prompt
*/
static int use_fossil_creds_for_httpauth_prompt(void){
Blob x;
|
| ︙ | ︙ |
Changes to src/http_ssl.c.
| ︙ | ︙ | |||
377 378 379 380 381 382 383 |
/* See RFC2817 for details */
static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
int rc, httpVerMin;
char *bbuf;
Blob snd, reply;
int done=0,end=0;
blob_zero(&snd);
| | | | | | | | | < < < | > | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
/* See RFC2817 for details */
static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
int rc, httpVerMin;
char *bbuf;
Blob snd, reply;
int done=0,end=0;
blob_zero(&snd);
blob_appendf(&snd, "CONNECT %s:%d HTTP/1.1" CRLF, pUrlData->hostname,
pUrlData->proxyOrigPort);
blob_appendf(&snd, "Host: %s:%d" CRLF,
pUrlData->hostname, pUrlData->proxyOrigPort);
if( pUrlData->proxyAuth ){
blob_appendf(&snd, "Proxy-Authorization: %s" CRLF, pUrlData->proxyAuth);
}
blob_append(&snd, "Proxy-Connection: keep-alive" CRLF, -1);
blob_appendf(&snd, "User-Agent: %s" CRLF, get_user_agent());
blob_append(&snd, CRLF, CRLF_SZ);
BIO_write(bio, blob_buffer(&snd), blob_size(&snd));
blob_reset(&snd);
/* Wait for end of reply */
blob_zero(&reply);
do{
int len;
char buf[256];
len = BIO_read(bio, buf, sizeof(buf));
blob_append(&reply, buf, len);
bbuf = blob_buffer(&reply);
len = blob_size(&reply);
while(end < len) {
if( bbuf[end]=='\n' ) {
if( (end+1<len && bbuf[end+1]=='\n')
|| (end+2<len && bbuf[end+1]=='\r' && bbuf[end+1]=='\n')
){
done = 1;
break;
}
}
end++;
}
}while(!done);
|
| ︙ | ︙ |
Changes to src/pikchrshow.c.
| ︙ | ︙ | |||
269 270 271 272 273 274 275 |
TODO: respond with JSON instead.*/
cgi_set_content_type("text/html");
if(zContent && *zContent){
Blob out = empty_blob;
const int isErr =
pikchr_process(zContent, pikFlags, 0, &out);
if(isErr){
| | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
TODO: respond with JSON instead.*/
cgi_set_content_type("text/html");
if(zContent && *zContent){
Blob out = empty_blob;
const int isErr =
pikchr_process(zContent, pikFlags, 0, &out);
if(isErr){
cgi_printf_header("x-pikchrshow-is-error: %d" CRLF, isErr);
}
CX("%b", &out);
blob_reset(&out);
}else{
CX("<pre>No content! Nothing to render</pre>");
}
return;
|
| ︙ | ︙ |
Changes to src/smtp.c.
| ︙ | ︙ | |||
373 374 375 376 377 378 379 |
** Have the client send a QUIT message.
*/
int smtp_client_quit(SmtpSession *p){
Blob in = BLOB_INITIALIZER;
int iCode = 0;
int bMore = 0;
char *zArg = 0;
| | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
** Have the client send a QUIT message.
*/
int smtp_client_quit(SmtpSession *p){
Blob in = BLOB_INITIALIZER;
int iCode = 0;
int bMore = 0;
char *zArg = 0;
smtp_send_line(p, "QUIT" CRLF);
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
p->atEof = 1;
socket_close();
return 0;
}
|
| ︙ | ︙ | |||
400 401 402 403 404 405 406 |
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=220 ){
smtp_client_quit(p);
return 1;
}
| | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=220 ){
smtp_client_quit(p);
return 1;
}
smtp_send_line(p, "EHLO %s" CRLF, p->zFrom);
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=250 ){
smtp_client_quit(p);
return 1;
}
|
| ︙ | ︙ | |||
454 455 456 457 458 459 460 |
fossil_fatal("ERROR: %s\n", p->zErr);
}
smtp_session_free(p);
}
/*
** Send the content of an email message followed by a single
| | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
fossil_fatal("ERROR: %s\n", p->zErr);
}
smtp_session_free(p);
}
/*
** Send the content of an email message followed by a single
** "." line. All lines must be \r\n terminated. (NOT!) Any isolated
** \n line terminators in the input must be converted. Also,
** a line beginning with "." must have the dot doubled per
** https://tools.ietf.org/html/rfc5321#section-4.5.2
*/
static void smtp_send_email_body(
const char *zMsg, /* Message to send */
size_t (*xSend)(void*,const void*,size_t), /* Sender callback function */
|
| ︙ | ︙ | |||
480 481 482 483 484 485 486 |
if( n && z[n-1]=='\r' ) n--;
if( z[0]=='.' ){
blob_append(&out, "..", 2); /* RFC 5321 § 4.5.2 */
blob_append(&out, z+1, n-1);
}else{
blob_append(&out, z, n);
}
| | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
if( n && z[n-1]=='\r' ) n--;
if( z[0]=='.' ){
blob_append(&out, "..", 2); /* RFC 5321 § 4.5.2 */
blob_append(&out, z+1, n-1);
}else{
blob_append(&out, z, n);
}
blob_append(&out, CRLF, CRLF_SZ);
}
blob_append(&out, "." CRLF, CRLF_SZ+1);
xSend(pArg, blob_buffer(&out), blob_size(&out));
blob_reset(&out);
blob_reset(&line);
}
/* A sender function appropriate for use by smtp_send_email_body() to
** send all content to the console, for testing.
|
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
){
int i;
int iCode = 0;
int bMore = 0;
char *zArg = 0;
Blob in;
blob_init(&in, 0, 0);
| | | | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
){
int i;
int iCode = 0;
int bMore = 0;
char *zArg = 0;
Blob in;
blob_init(&in, 0, 0);
smtp_send_line(p, "MAIL FROM:<%s>" CRLF, zFrom);
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=250 ) return 1;
for(i=0; i<nTo; i++){
smtp_send_line(p, "RCPT TO:<%s>" CRLF, azTo[i]);
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=250 ) return 1;
}
smtp_send_line(p, "DATA" CRLF);
do{
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
}while( bMore );
if( iCode!=354 ) return 1;
smtp_send_email_body(zMsg, socket_send, 0);
if( p->smtpFlags & SMTP_TRACE_STDOUT ){
fossil_print("C: # message content\nC: .\n");
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
616 617 618 619 620 621 622 |
}
blob_append(&csp, zFormat, -1);
zCsp = blob_str(&csp);
/* No whitespace other than actual space characters allowed in the CSP
** string. See https://fossil-scm.org/forum/forumpost/d29e3af43c */
for(i=0; zCsp[i]; i++){ if( fossil_isspace(zCsp[i]) ) zCsp[i] = ' '; }
if( toHeader ){
| | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 |
}
blob_append(&csp, zFormat, -1);
zCsp = blob_str(&csp);
/* No whitespace other than actual space characters allowed in the CSP
** string. See https://fossil-scm.org/forum/forumpost/d29e3af43c */
for(i=0; zCsp[i]; i++){ if( fossil_isspace(zCsp[i]) ) zCsp[i] = ' '; }
if( toHeader ){
cgi_printf_header("Content-Security-Policy: %s" CRLF, zCsp);
}
return zCsp;
}
/*
** Default HTML page header text through <body>. If the repository-specific
** header template lacks a <body> tag, then all of the following is
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
2181 2182 2183 2184 2185 2186 2187 |
zParams = strrchr(argv[nArg], '?');
if( strlen(urlData.path)>0 && zParams!=argv[nArg] ){
zSep = "";
}else{
zSep = "/";
}
blob_zero(&hdr);
| | | | | | | | | | 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 |
zParams = strrchr(argv[nArg], '?');
if( strlen(urlData.path)>0 && zParams!=argv[nArg] ){
zSep = "";
}else{
zSep = "/";
}
blob_zero(&hdr);
blob_appendf(&hdr, "%s %s%s%s HTTP/1.0" CRLF,
zType, zSep, urlData.path, zParams ? zParams : "");
if( urlData.proxyAuth ){
blob_appendf(&hdr, "Proxy-Authorization: %s" CRLF, urlData.proxyAuth);
}
if( urlData.passwd && urlData.user && urlData.passwd[0]=='#' ){
char *zCredentials = mprintf("%s:%s", urlData.user, &urlData.passwd[1]);
char *zEncoded = encode64(zCredentials, -1);
blob_appendf(&hdr, "Authorization: Basic %s" CRLF, zEncoded);
fossil_free(zEncoded);
fossil_free(zCredentials);
}
blob_appendf(&hdr, "Host: %s" CRLF
"User-Agent: %s" CRLF, urlData.hostname, get_user_agent());
if( zType[0]=='P' ){
blob_appendf(&hdr, "Content-Type: application/x-www-form-urlencoded" CRLF
"Content-Length: %d" CRLF CRLF, blob_size(&payload));
}else{
blob_appendf(&hdr, CRLF);
}
if( transport_open(&urlData) ){
Th_ErrorMessage(interp, transport_errmsg(&urlData), 0, 0);
blob_reset(&hdr);
blob_reset(&payload);
return TH_ERROR;
}
|
| ︙ | ︙ |
Changes to src/winhttp.c.
| ︙ | ︙ | |||
373 374 375 376 377 378 379 |
}
if( got==0 ){
wanted = 0;
break;
}
amt += got;
zBuf[amt] = 0;
| | | | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
}
if( got==0 ){
wanted = 0;
break;
}
amt += got;
zBuf[amt] = 0;
z = strstr(zBuf, "\n\n");
if( z ){
wanted = find_content_length(zBuf) + (&z[2]-zBuf) - amt;
break;
}else{
z = strstr(zBuf, "\n\r\n");
if( z ){
wanted = find_content_length(zBuf) + (&z[3]-zBuf) - amt;
break;
}
}
}
if( amt>=szHdr ) goto end_request;
out = fossil_fopen(zRequestFName, "wb");
if( out==0 ) goto end_request;
|
| ︙ | ︙ |
Changes to tools/codecheck1.c.
| ︙ | ︙ | |||
228 229 230 231 232 233 234 |
return z;
}
/*
** Return true if the input is a string literal.
*/
static int is_string_lit(const char *z){
| | > | > | > > | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
return z;
}
/*
** Return true if the input is a string literal.
*/
static int is_string_lit(const char *z){
int len, eType;
while( 1 /* exit by return */ ){
z = next_non_whitespace(z, &len, &eType);
if( len==4 ){
if( strncmp(z, "NULL", 4)==0 ) return 1;
if( strncmp(z, "CRLF", 4)==0 ) return 1;
}
return z[0]=='"';
}
}
/*
** Return true if the input is an expression of string literals:
**
** EXPR ? "..." : "..."
*/
|
| ︙ | ︙ |