Fossil

Check-in [d5c46845]
Login

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

Overview
Comment:Escape all characters in the href attributes of <a> elements that have special meaning to HTML. Ticket [5ff2043c96682049].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d5c46845080ed03fbcf73746a49493cb13ce0014
User & Date: drh 2012-11-08 13:46:58
Context
2012-11-08
14:42
Add a test script that runs one thousand web page queries using valgrind, looking for memory issues. Fix one use-after-free issue found using this script. check-in: 9e0da274 user: drh tags: trunk
13:46
Escape all characters in the href attributes of <a> elements that have special meaning to HTML. Ticket [5ff2043c96682049]. check-in: d5c46845 user: drh tags: trunk
13:44
Always HTML-encode the href attribute of <a> elements. This check-in simplifies and fixes double-frees in the previous. Ticket [5ff2043c9668] Closed-Leaf check-in: 35bfedef user: drh tags: ticket-5ff2043c96
09:20
a few more minor html5 violations check-in: 1858d202 user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/style.c.

88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
...
104
105
106
107
108
109
110
111


112
113
114
115
116
117
118
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
char *xhref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    return mprintf("<a %s href=\"%z\">", zExtra, zUrl);


  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a %s id=%d>", zExtra, nHref);
................................................................................
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    return mprintf("<a href=\"%z\">", zUrl);


  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a id=%d>", nHref);
................................................................................
    @ <div class="submenu">
    qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
    for(i=0; i<nSubmenu; i++){
      struct Submenu *p = &aSubmenu[i];
      if( p->zLink==0 ){
        @ <span class="label">%h(p->zLabel)</span>
      }else{
        @ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a>
      }
    }
    @ </div>
  }
  style_ad_unit();
  @ <div class="content">
  cgi_destination(CGI_BODY);







|
>
>







 







|
>
>







 







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
char *xhref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a %s id=%d>", zExtra, nHref);
................................................................................
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a id=%d>", nHref);
................................................................................
    @ <div class="submenu">
    qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
    for(i=0; i<nSubmenu; i++){
      struct Submenu *p = &aSubmenu[i];
      if( p->zLink==0 ){
        @ <span class="label">%h(p->zLabel)</span>
      }else{
        @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
      }
    }
    @ </div>
  }
  style_ad_unit();
  @ <div class="content">
  cgi_destination(CGI_BODY);

Changes to src/timeline.c.

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;
    if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){
      char *zLink = mprintf("%R/timeline?u=%h&amp;c=%t&amp;nd", zUser, zDate);
      @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051")
    }else{
      @ (user: %h(zUser)%s(zTagList?",":"\051")
    }

    /* Generate a "detail" link for tags. */
    if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){
................................................................................
        Blob links;
        blob_zero(&links);
        while( z && z[0] ){
          for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
          if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
            blob_appendf(&links,
                  "%z%#h</a>%.2s",
                  href("%R/timeline?r=%#t&amp;nd&amp;c=%t",i,z,zDate), i,z, &z[i]
            );
          }else{
            blob_appendf(&links, "%#h", i+2, z);
          }
          if( z[i]==0 ) break;
          z += i+2;
        }







|







 







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;
    if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){
      char *zLink = mprintf("%R/timeline?u=%h&c=%t&amp;nd", zUser, zDate);
      @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051")
    }else{
      @ (user: %h(zUser)%s(zTagList?",":"\051")
    }

    /* Generate a "detail" link for tags. */
    if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){
................................................................................
        Blob links;
        blob_zero(&links);
        while( z && z[0] ){
          for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
          if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
            blob_appendf(&links,
                  "%z%#h</a>%.2s",
                  href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i]
            );
          }else{
            blob_appendf(&links, "%#h", i+2, z);
          }
          if( z[i]==0 ) break;
          z += i+2;
        }

Changes to src/url.c.

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    if( zName2 && fossil_strcmp(zName2,p->azName[i])==0 ){
      zName2 = 0;
      z = zValue2;
      if( z==0 ) continue;
    }
    blob_appendf(&p->url, "%s%s", zSep, p->azName[i]);
    if( z && z[0] ) blob_appendf(&p->url, "=%T", z);
    zSep = "&amp;";
  }
  if( zName1 && zValue1 ){
    blob_appendf(&p->url, "%s%s", zSep, zName1);
    if( zValue1[0] ) blob_appendf(&p->url, "=%T", zValue1);
  }
  if( zName2 && zValue2 ){
    blob_appendf(&p->url, "%s%s", zSep, zName2);







|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    if( zName2 && fossil_strcmp(zName2,p->azName[i])==0 ){
      zName2 = 0;
      z = zValue2;
      if( z==0 ) continue;
    }
    blob_appendf(&p->url, "%s%s", zSep, p->azName[i]);
    if( z && z[0] ) blob_appendf(&p->url, "=%T", z);
    zSep = "&";
  }
  if( zName1 && zValue1 ){
    blob_appendf(&p->url, "%s%s", zSep, zName1);
    if( zValue1[0] ) blob_appendf(&p->url, "=%T", zValue1);
  }
  if( zName2 && zValue2 ){
    blob_appendf(&p->url, "%s%s", zSep, zName2);