Fossil

Check-in [8dd7542892]
Login

Check-in [8dd7542892]

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

Overview
Comment:Improved comments on anchor-generation routines like href(). Simplify the logic. Fix a bug in the generation of form elements for the /register page.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8dd75428928cb4a5383d27f160758e9c6aa3036906845af5ee1d85271d467807
User & Date: drh 2021-07-19 13:27:20.834
Context
2021-07-19
18:20
Start the list of changes for version 2.17. ... (check-in: 482c1c9ee8 user: drh tags: trunk)
13:27
Improved comments on anchor-generation routines like href(). Simplify the logic. Fix a bug in the generation of form elements for the /register page. ... (check-in: 8dd7542892 user: drh tags: trunk)
2021-07-18
12:47
/wikiedit: show the list of attachments for the current page and list URLs suitable for pasting them into the page, e.g. for use in IMG tags. ... (check-in: ce15e35e47 user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/login.c.
1776
1777
1778
1779
1780
1781
1782

1783
1784
1785
1786
1787
1788
1789
    uSeed = captcha_seed();
  }
  zDecoded = captcha_decode(uSeed);
  zCaptcha = captcha_render(zDecoded);

  style_header("Register");
  /* Print out the registration form. */

  form_begin(0, "%R/register");
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))" />
  }
  @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" />
  @ <table class="login_out">
  @ <tr>







>







1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
    uSeed = captcha_seed();
  }
  zDecoded = captcha_decode(uSeed);
  zCaptcha = captcha_render(zDecoded);

  style_header("Register");
  /* Print out the registration form. */
  g.perm.Hyperlink = 1;  /* Artificially enable hyperlinks */
  form_begin(0, "%R/register");
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))" />
  }
  @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" />
  @ <table class="login_out">
  @ <tr>
Changes to src/style.c.
105
106
107
108
109
110
111










112
113
114
115
116
117
118
119
120
121
122
123
124
125












126


127
128
129
130
131
132
133
134
135
/*
** Generate and return a anchor tag like this:
**
**        <a href="URL">
**  or    <a id="ID">
**
** The form of the anchor tag is determined by the g.javascriptHyperlink










** variable.  The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the
** id="ID" form is used and javascript is generated in the footer to cause
** href values to be inserted after the page has loaded.  If
** g.perm.History is false, then the <a id="ID"> form is still
** generated but the javascript is not generated so the links never
** activate.
**
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
** g.javascriptHyperlink is set to 1.  The g.javascriptHyperlink defaults
** to 0 and only changes to one if the user lacks the Hyperlink (h) property
** and the "auto-hyperlink" setting is enabled.
**












** Filling in the href="URL" using javascript is a defense against bots.


**
** The name of this routine is deliberately kept short so that can be
** easily used within @-lines.  Example:
**
**      @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
**
** Note %z format.  The string returned by this function is always
** obtained from fossil_malloc() so rendering it with %z will reclaim
** that memory space.







>
>
>
>
>
>
>
>
>
>
|
|
|
|
<
<
|



|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
|
>
>

|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
** Generate and return a anchor tag like this:
**
**        <a href="URL">
**  or    <a id="ID">
**
** The form of the anchor tag is determined by the g.javascriptHyperlink
** and g.perm.Hyperlink variables.
**
**   g.perm.Hyperlink  g.javascriptHyperlink        Returned anchor format
**   ----------------  ---------------------        ------------------------
**          0                    0                  (empty string)
**          0                    1                  (empty string)
**          1                    0                  <a href="URL">
**          1                    1                  <a id="ID">
**
** No anchor tag is generated if g.perm.Hyperlink is false.
** The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the id="ID" form is used and
** javascript is generated in the footer to cause href values to be
** inserted after the page has loaded. The use of the id="ID" form


** instead of href="URL" is a defense against bots.
**
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
** g.javascriptHyperlink is set to 1 by login_check_credentials().  Thus
** the g.perm.Hyperlink property will be true even if the user does not
** have the "h" privilege if the "auto-hyperlink" setting is true.
**
**  User has "h"  auto-hyperlink      g.perm.Hyperlink  g.javascriptHyperlink
**  ------------  --------------      ----------------  ---------------------
**        0             0                    0                    0
**        1             0                    1                    0
**        0             1                    1                    1
**        1             1                    1                    0
**
** So, in other words, tracing input configuration to final actions we have:
**
**  User has "h"  auto-hyperlink      Returned anchor format
**  ------------  --------------      ----------------------
**        0             0             (empty string)
**        1             0             <a href="URL">
**        0             1             <a id="ID">
**        1             1             (can't happen)
**
** The name of these routines are deliberately kept short so that can be
** easily used within @-lines.  Example:
**
**      @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
**
** Note %z format.  The string returned by this function is always
** obtained from fossil_malloc() so rendering it with %z will reclaim
** that memory space.
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
char *xhref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl;
    if( zExtra ){
      zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
    }else{
      zHUrl = mprintf("<a href=\"%h\">", zUrl);
    }
    fossil_free(zUrl);







|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
char *xhref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( !g.javascriptHyperlink ){
    char *zHUrl;
    if( zExtra ){
      zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
    }else{
      zHUrl = mprintf("<a href=\"%h\">", zUrl);
    }
    fossil_free(zUrl);
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

















209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
char *chref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  needHrefJs = 1;
  return mprintf("<a class='%s' data-href='%z' href='%R/honeypot'>",
                 zExtra, zUrl);
}
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  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;
  }
  needHrefJs = 1;
  return mprintf("<a data-href='%s' href='%R/honeypot'>",
                  zUrl);
}

/*
** Generate <form method="post" action=ARG>.  The ARG value is inserted
** by javascript.

















*/
void form_begin(const char *zOtherArgs, const char *zAction, ...){
  char *zLink;
  va_list ap;
  if( zOtherArgs==0 ) zOtherArgs = "";
  va_start(ap, zAction);
  zLink = vmprintf(zAction, ap);
  va_end(ap);
  if( fossil_strcmp(zLink,"/register")==0
   || (g.perm.Hyperlink && !g.javascriptHyperlink)
  ){
    @ <form method="POST" action="%z(zLink)" %s(zOtherArgs)>
  }else{
    needHrefJs = 1;
    @ <form method="POST" data-action='%s(zLink)' action='%R/login' \
    @ %s(zOtherArgs)>
  }
}







|















|










|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<
|
<







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

256

257
258
259
260
261
262
263
char *chref(const char *zExtra, const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  needHrefJs = 1;
  return mprintf("<a class='%s' data-href='%z' href='%R/honeypot'>",
                 zExtra, zUrl);
}
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  if( !g.perm.Hyperlink ) return fossil_strdup("");
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  needHrefJs = 1;
  return mprintf("<a data-href='%s' href='%R/honeypot'>",
                  zUrl);
}

/*
** Generate <form method="post" action=ARG>.  The ARG value is determined
** by the arguments.
**
** As a defense against robots, the action=ARG might instead by data-action=ARG
** and javascript (href.js) added to the page so that the data-action= is
** changed into action= after the page loads.  Whether or not this happens
** depends on if the user has the "h" privilege and whether or not the
** auto-hyperlink setting is on.  These setings determine the values of
** variables g.perm.Hyperlink and g.javascriptHyperlink.
**
**    User has "h"  auto-hyperlink      g.perm.Hyperlink  g.javascriptHyperlink
**    ------------  --------------      ----------------  ---------------------
**  1:      0             0                    0                    0
**  2:      1             0                    1                    0
**  3:      0             1                    1                    1
**  4:      1             1                    1                    0
**
** The data-action=ARG form is used for cases 1 and 3.  In case 1, the href.js
** javascript is omitted and so the form is effectively disabled.
*/
void form_begin(const char *zOtherArgs, const char *zAction, ...){
  char *zLink;
  va_list ap;
  if( zOtherArgs==0 ) zOtherArgs = "";
  va_start(ap, zAction);
  zLink = vmprintf(zAction, ap);
  va_end(ap);

  if( g.perm.Hyperlink ){

    @ <form method="POST" action="%z(zLink)" %s(zOtherArgs)>
  }else{
    needHrefJs = 1;
    @ <form method="POST" data-action='%s(zLink)' action='%R/login' \
    @ %s(zOtherArgs)>
  }
}