Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch rptview-submenu-paralink Excluding Merge-Ins
This is equivalent to a diff from a004b1729c to 59010c7c09
2021-08-17
| ||
15:41 | Improvements to the /urllist page → the sync URLs and Git mirrors are combined into a single section. Add the url_unparse() interface for freeing memory from a url_parse_local(). ... (check-in: 9bdbcd39cb user: drh tags: trunk) | |
2021-08-16
| ||
00:11 | Relax <tt>isSnippetMark()</tt> so that almost arbitrary search terms are highlighted. This change is preliminary and [forum:/forumpost/042e179e0c25b8|needs further analysis]. ... (Leaf check-in: 6b37b55f75 user: george tags: search-terms-highlighting) | |
2021-08-15
| ||
23:49 | Merge from trunk ... (Leaf check-in: 59010c7c09 user: george tags: rptview-submenu-paralink) | |
23:27 | Merge from trunk ... (Leaf check-in: 282c6f956f user: george tags: wcontent-subsets) | |
23:13 | Merge from trunk ... (Leaf check-in: 5b67899db0 user: george tags: th1-doc-vars) | |
18:38 | Remove a harmless unused variable. ... (check-in: a004b1729c user: drh tags: trunk) | |
00:43 | Improve the /urllist page so that it shows all servers with which the repository has synced. ... (check-in: 89e5c03a32 user: drh tags: trunk) | |
2021-06-15
| ||
22:31 | Do not allow links with "../" substring or <tt>'<'</tt> character. The former enforces that the link maps into a repo-local page; the later enforces defense against injection of malicious HTML elements. ... (check-in: 6261c94b1e user: george tags: rptview-submenu-paralink) | |
Changes to src/report.c.
︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 | fossil_free((void *)azVals); return rc; } /* ** WEBPAGE: rptview ** | | | > > > > > > > > | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 | fossil_free((void *)azVals); return rc; } /* ** WEBPAGE: rptview ** ** Generate a report. The "rn" query parameter is the report number ** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists, ** then the output consists of lines of tab-separated fields instead of ** an HTML table. ** ** Submenu of the /rptview page can be extended with additional ** hyperlinks by providing query parameter(s) of the form rvsmplXY=Z. ** Optional ending XY consists of a digit X from the set {1,2,3,4,5} ** and an optional letter Y that (if present) must be either 'a' or 's'. ** Mandatory Z is a repo-local hyperlink's target (wihout leading '/'). ** ** For details see the wiki page "branch/rptview-submenu-paralink". */ void rptview_page(void){ rptview_page_content(0, 1, 1); } /* ** Render a report. |
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | if( zQS[0] ){ style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS); style_submenu_element("Reports","%R/reportlist?%s",zQS); } else { style_submenu_element("Raw","%R/%s?tablist=1",g.zPath); style_submenu_element("Reports","%R/reportlist"); } if( g.perm.Admin || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ style_submenu_element("Edit", "rptedit?rn=%d", rn); } if( g.perm.TktFmt ){ style_submenu_element("SQL", "rptsql?rn=%d",rn); } | > > | 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 | if( zQS[0] ){ style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS); style_submenu_element("Reports","%R/reportlist?%s",zQS); } else { style_submenu_element("Raw","%R/%s?tablist=1",g.zPath); style_submenu_element("Reports","%R/reportlist"); } style_submenu_parametric("rv"); if( g.perm.Admin || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ style_submenu_element("Edit", "rptedit?rn=%d", rn); } if( g.perm.TktFmt ){ style_submenu_element("SQL", "rptsql?rn=%d",rn); } |
︙ | ︙ |
Changes to src/style.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ** ** style_submenu_element() ** style_submenu_entry() ** style_submenu_checkbox() ** style_submenu_binary() ** style_submenu_multichoice() ** style_submenu_sql() ** ** prior to calling style_finish_page(). The style_finish_page() routine ** will generate the appropriate HTML text just below the main ** menu. */ static struct Submenu { const char *zLabel; /* Button label */ | > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | ** ** style_submenu_element() ** style_submenu_entry() ** style_submenu_checkbox() ** style_submenu_binary() ** style_submenu_multichoice() ** style_submenu_sql() ** style_submenu_parametric() ** ** prior to calling style_finish_page(). The style_finish_page() routine ** will generate the appropriate HTML text just below the main ** menu. */ static struct Submenu { const char *zLabel; /* Button label */ |
︙ | ︙ | |||
364 365 366 367 368 369 370 371 372 373 374 375 376 377 | aSubmenuCtrl[nSubmenuCtrl].iSize = n/2; aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az; aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL; aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI; nSubmenuCtrl++; } } /* ** Disable or enable the submenu */ void style_submenu_enable(int onOff){ submenuEnable = onOff; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 365 366 367 368 369 370 371 372 373 374 375 376 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 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 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 478 479 | aSubmenuCtrl[nSubmenuCtrl].iSize = n/2; aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az; aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL; aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI; nSubmenuCtrl++; } } /* Add hyperlinks depending on the existence and values of special ** parameters in the request's query string. The names of a query's ** parameters that are investigated are obtainted by concatenation of ** the caller-provided zPrefix with suffix "smplXY", where optional ** ending XY consists of a digit X from the set {1,2,3,4,5} and an ** optional letter Y which (if present) must be either 'a' or 's'. ** zPrefix must start with a lowercase letter, ** be short and have no strange characters. Parameter's value ** is well-formed if its first filepath segment (separated by '/') ** has no strange characters. Malformed values are silently ignored. ** ** The text for the resulting submenu label equals to the value of the ** parameter modulus some prettification for better UX: ** 1) If a parameter's value starts with a lowercase letter and ** contains '/' then it goes unchanged into the user-visible label. ** 2a) If the first letter is uppercase then the label is ** truncated at the first '/' (if any), ** 2b) otherwise the first letter is capitalized. ** 3) Underscores in the first path segment are replaced with spaces. ** 4) If the resulting label starts with an uppercase letter ** then it is prepended with "✧" symbol for explicit distinction ** from the built-in labels ** ** Important security-related note: ** zLabel and zLink are formatted using %s because it is expected that ** style_finish_page() provides propper escaping via %h format. */ void style_submenu_parametric( const char *zPrefix /* common prefix of the query parameters names */ ){ static const char *suffix = "smpl"; /* common suffix for param names */ static const short sfxlen = 4; /* length of the above suffix */ static const char sfxext[3] = {'a','s',0}; /* extra suffix ending */ const char *zQS; /* QUERY_STRING */ char zN[32]; /* buffer for parameter names to probe */ short i,j,l; /* zPrefix must be tidy and short; also filter out ENV/CGI variables */ assert( zPrefix != 0 && fossil_islower(zPrefix[0]) ); l = strnlen( zPrefix, sizeof(zN) ); assert( l+sfxlen+3 <= sizeof(zN) ); assert( fossil_no_strange_characters(zPrefix) ); /* concatenate zPrefix and suffix */ strcpy( zN, zPrefix ); strcpy( zN + l, suffix ); l += sfxlen; zN[l+2] = 0; /* nul-terminator after ...smplXY suffix */ zQS = PD("QUERY_STRING",""); for( i = 0; i <= 5; i++ ){ zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */ for( j = (i ? 0 : sizeof(sfxext)-1); j < sizeof(sfxext); j++ ){ const char *zV, *z; zN[l+1] = sfxext[j]; zV = PD(zN,""); if( zV[0] == 0 || zV[0] == '/' || zV[0] == '_' || zV[0] == '-' ){ continue; } /* require the first path segment to be unfancy ASCII string */ for( z = zV; z[0] && z[0] != '/' ;){ if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++; else break; } if( z[0] == '/' ){ /* values may not contain "../" or "<" */ if( strstr(z,"../")!=NULL || strstr(z,"<")!=NULL ){ continue; } } else if( z[0] != 0 ) continue; assert( nSubmenu < count(aSubmenu) ); if(fossil_islower(zV[0]) && z[0]=='/'){ aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */ }else{ /* prepend a label with an unobtrusive symbol that "sorts-last"; ** this clearly distincts it from the built-in elements */ static const char *mark = "✧"; char *z = mprintf("%s%s",mark,zV); aSubmenu[nSubmenu].zLabel = z; /* also prettify the first segment */ z += strlen(mark); z[0] = fossil_toupper(z[0]); for(; z[0]!=0; z++ ){ if( z[0]=='_' ) z[0] = ' '; else if( z[0] == '/' ){ /* show just the first segment */ z[0] = 0; break; } } } if( zQS[0] ){ aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS); }else{ aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV); } nSubmenu++; } } } /* ** Disable or enable the submenu */ void style_submenu_enable(int onOff){ submenuEnable = onOff; } |
︙ | ︙ | |||
942 943 944 945 946 947 948 | @ <div class="submenu"> if( nSubmenu>0 ){ qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare); for(i=0; i<nSubmenu; i++){ struct Submenu *p = &aSubmenu[i]; /* switching away from the %h formatting below might be dangerous ** because some places use %s to compose zLabel and zLink; | | | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | @ <div class="submenu"> if( nSubmenu>0 ){ qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare); for(i=0; i<nSubmenu; i++){ struct Submenu *p = &aSubmenu[i]; /* switching away from the %h formatting below might be dangerous ** because some places use %s to compose zLabel and zLink; ** e.g. /rptview page and the style_submenu_parametic() function */ if( p->zLink==0 ){ @ <span class="label">%h(p->zLabel)</span> }else{ @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a> } } |
︙ | ︙ |
Changes to src/wiki.c.
︙ | ︙ | |||
591 592 593 594 595 596 597 598 599 600 601 602 603 604 | ){ style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName); }else if( rid && g.perm.ApndWiki ){ style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName); } if( g.perm.Hyperlink ){ style_submenu_element("History", "%R/whistory?name=%T", zPageName); } } if( !isPopup ){ style_set_current_page("%T?name=%T", g.zPath, zPageName); wiki_page_header(WIKITYPE_UNKNOWN, zPageName, ""); if( !noSubmenu ){ wiki_standard_submenu(submenuFlags); | > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | ){ style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName); }else if( rid && g.perm.ApndWiki ){ style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName); } if( g.perm.Hyperlink ){ style_submenu_element("History", "%R/whistory?name=%T", zPageName); style_submenu_parametric("wiki"); } } if( !isPopup ){ style_set_current_page("%T?name=%T", g.zPath, zPageName); wiki_page_header(WIKITYPE_UNKNOWN, zPageName, ""); if( !noSubmenu ){ wiki_standard_submenu(submenuFlags); |
︙ | ︙ |
Changes to www/changes.wiki.
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * Print total payload bytes on a [/help?cmd=sync|fossil sync] when using the --verbose option. * Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and </tt>unhide</tt> subcommands to [/help?cmd=branch|the branch command]. * The [/mdrules|Markdown formatter] now interprets the content of block HTML markup (such as <table>) in most cases. Only content of <pre> and <script> is passed through verbatim. <a name='v2_16'></a> <h2>Changes for Version 2.16 (2021-07-02)</h2> * <b>Security:</b> Fix the client-side TLS so that it verifies that the server hostname matches its certificate. * The default "ssh" command on Windows is changed to "ssh" instead of the legacy "plink", as ssh is now generally available on Windows systems. | > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * Print total payload bytes on a [/help?cmd=sync|fossil sync] when using the --verbose option. * Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and </tt>unhide</tt> subcommands to [/help?cmd=branch|the branch command]. * The [/mdrules|Markdown formatter] now interprets the content of block HTML markup (such as <table>) in most cases. Only content of <pre> and <script> is passed through verbatim. * Submenu of the [/help?cmd=/rptview|/rptview] and [/help?cmd=/wiki|/wiki] pages may be [branch/rptview-submenu-paralink|extended with auxiliary hyperlinks]. <a name='v2_16'></a> <h2>Changes for Version 2.16 (2021-07-02)</h2> * <b>Security:</b> Fix the client-side TLS so that it verifies that the server hostname matches its certificate. * The default "ssh" command on Windows is changed to "ssh" instead of the legacy "plink", as ssh is now generally available on Windows systems. |
︙ | ︙ |