Changes On Branch not-allowed.
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch not-allowed. Excluding Merge-Ins

This is equivalent to a diff from 81ab30272e to 9690fc39dc

2021-06-14
05:48
Squished a few minor errors on www/javascript.md check-in: 641a02c8f3 user: wyoung tags: trunk
2021-06-12
18:43
Add support for [/wiki?name=branch/rptview-submenu-paralink&p|submenu parametric hyperlinks] for [/help?cmd=/rptview|/rptview] and [/help?cmd=/wiki|/wiki] pages. Closed-Leaf check-in: 9690fc39dc user: george tags: not-allowed.
17:28
Add a note to the Changelog. No code changes. check-in: 528d628947 user: george tags: rptview-submenu-paralink
14:59
Move the test for forum post ahead of the plink test in the /info page, because things other than check-ins can now appear in the plink table. [forum:/forumpost/52587290b9493eab|Forum post 52587290b9493eab]. check-in: 81ab30272e user: drh tags: trunk
2021-06-11
18:28
Up the version number to 2.16, as we are getting close to wanting to do a release. check-in: a01df78c31 user: drh tags: trunk

Changes to src/report.c.

970
971
972
973
974
975
976
977
978
979
980








981
982
983
984
985
986
987
  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.








*/
void rptview_page(void){
  int count = 0;
  int rn, rc;
  char *zSql;
  char *zTitle;
  char *zOwner;







|
|


>
>
>
>
>
>
>
>







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
  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){
  int count = 0;
  int rn, rc;
  char *zSql;
  char *zTitle;
  char *zOwner;
1043
1044
1045
1046
1047
1048
1049


1050
1051
1052
1053
1054
1055
1056
    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);
    }







>
>







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
    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 */
327
328
329
330
331
332
333






























































































334
335
336
337
338
339
340
    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;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
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
    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] != 0 && z[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;
}
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
    @ <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
        */
        if( p->zLink==0 ){
          @ <span class="label">%h(p->zLabel)</span>
        }else{
          @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
        }
      }







|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
    @ <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.

18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
     timeline if the repository has forum posts.
  *  Tags may now be propagated for forum posts, wiki pages, and technotes.
     The [/help?cmd=tag|tag command] can now manipulate and list such tags.
  *  [./caps/login-groups.md|Login-Groups] are now show on the repository
     list of the "[/help?cmd=all|fossil all ui]" command.
  *  Administrators can configure [./alerts|email alerts] to expire
     a specific number of days (ex: 365) after the last user contact with
     the Fossil server  This can prevents alert emails being sent to 
     abandoned email accounts forever.




<a name='v2_15'></a>
<h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
  *  <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server.  <b>Upgrading to
     the patch is recommended.</b><p>
  *  The [./defcsp.md|default CSP] has been relaxed slightly to allow
     images to be loaded from any URL.  All other resources are still







|

>
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
     timeline if the repository has forum posts.
  *  Tags may now be propagated for forum posts, wiki pages, and technotes.
     The [/help?cmd=tag|tag command] can now manipulate and list such tags.
  *  [./caps/login-groups.md|Login-Groups] are now show on the repository
     list of the "[/help?cmd=all|fossil all ui]" command.
  *  Administrators can configure [./alerts|email alerts] to expire
     a specific number of days (ex: 365) after the last user contact with
     the Fossil server.  This prevents alert emails being sent to
     abandoned email accounts forever.
  *  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_15'></a>
<h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
  *  <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server.  <b>Upgrading to
     the patch is recommended.</b><p>
  *  The [./defcsp.md|default CSP] has been relaxed slightly to allow
     images to be loaded from any URL.  All other resources are still