| ︙ | | | ︙ | |
104
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
|
/*
** 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
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
104
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
|
/*
** 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.jsHref
** and g.perm.Hyperlink variables.
**
** g.perm.Hyperlink g.jsHref Returned anchor format
** ---------------- -------- ------------------------
** 0 0 (empty string)
** 0 1 (empty string)
** 1 0 <a href="URL">
** 1 1 <a data-href="URL">
**
** No anchor tag is generated if g.perm.Hyperlink is false.
** The href="URL" form is used if g.jsHref is false.
** If g.jsHref is true then the data-href="URL" and
** href="/honeypot" is generated and javascript is added to the footer
** to cause data-href values to be inserted into href
** after the page has loaded. The use of the data-href="URL" 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.jsHref 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.jsHref
** ------------ -------------- ---------------- ---------------------
** 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 data-href="URL">
** 1 1 <a href="URL">
**
** 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
|
| ︙ | | | ︙ | |
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);
|
|
|
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
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.jsHref ){
char *zHUrl;
if( zExtra ){
zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
}else{
zHUrl = mprintf("<a href=\"%h\">", zUrl);
}
fossil_free(zUrl);
|
| ︙ | | | ︙ | |
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
|
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;
|
|
|
|
|
|
|
|
|
|
|
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
|
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.jsHref ){
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.jsHref ){
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.jsHref.
**
** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
** ------------ -------------- ---------------- --------
** 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;
|
| ︙ | | | ︙ | |
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
|
/*
** Generate code to load all required javascript files.
*/
static void style_load_all_js_files(void){
if( needHrefJs && g.perm.Hyperlink ){
int nDelay = db_get_int("auto-hyperlink-delay",0);
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
@ <script id='href-data' type='application/json'>\
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
}
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
@ function debugMsg(msg){
@ var n = document.getElementById("debugMsg");
@ if(n){n.textContent=msg;}
|
|
>
|
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
|
/*
** Generate code to load all required javascript files.
*/
static void style_load_all_js_files(void){
if( needHrefJs && g.perm.Hyperlink ){
int nDelay = db_get_int("auto-hyperlink-delay",0);
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
&& sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
@ <script id='href-data' type='application/json'>\
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
}
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
@ function debugMsg(msg){
@ var n = document.getElementById("debugMsg");
@ if(n){n.textContent=msg;}
|
| ︙ | | | ︙ | |
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
|
** /forumXYZ CSS into one file, all /setupXYZ into another, etc. As
** of this writing, doing so would only shave a few kb from
** default.css. */
fossil_free(zFile);
}
/*
** WEBPAGE: style.css
**
** Return the style sheet. The style sheet is assemblied from
** multiple sources, in order:
**
** (1) The built-in "default.css" style sheet containing basic defaults.
**
** (2) The page-specific style sheet taken from the built-in
|
|
|
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
|
** /forumXYZ CSS into one file, all /setupXYZ into another, etc. As
** of this writing, doing so would only shave a few kb from
** default.css. */
fossil_free(zFile);
}
/*
** WEBPAGE: style.css loadavg-exempt
**
** Return the style sheet. The style sheet is assemblied from
** multiple sources, in order:
**
** (1) The built-in "default.css" style sheet containing basic defaults.
**
** (2) The page-specific style sheet taken from the built-in
|
| ︙ | | | ︙ | |
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
|
}
/*
** WEBPAGE: honeypot
** This page is a honeypot for spiders and bots.
*/
void honeypot_page(void){
cgi_set_status(403, "Forbidden");
@ <p>Please enable javascript or log in to see this content</p>
}
/*
** Webpages that encounter an error due to missing or incorrect
** query parameters can jump to this routine to render an error
** message screen.
**
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|
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
|
}
/*
** WEBPAGE: honeypot
** This page is a honeypot for spiders and bots.
*/
void honeypot_page(void){
style_header("I think you are a robot");
@ <p>You seem like a robot.</p>
@
@ <p>Is this wrong? Are you really a human? If so, please prove it
@ by <a href="%R/login">logging in</a>.
if( g.anon.Hyperlink ){
@ You can <a href="%R/login?anon=1">log in anonymously</a> if you
@ prefer.
}
@ <p>Sorry for the inconvenience. The point of this is to prevent
@ robots from following the countless of hyperlinks in this site and
@ soaking up all the available CPU time and network bandwidth.
style_finish_page();
}
/*
** Webpages that encounter an error due to missing or incorrect
** query parameters can jump to this routine to render an error
** message screen.
**
|
| ︙ | | | ︙ | |
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
|
@ g.zBaseURL = %h(g.zBaseURL)<br />
@ g.zHttpsURL = %h(g.zHttpsURL)<br />
@ g.zTop = %h(g.zTop)<br />
@ g.zPath = %h(g.zPath)<br />
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ g.isHuman = %d(g.isHuman)<br />
if( g.nRequest ){
@ g.nRequest = %d(g.nRequest)<br />
}
if( g.nPendingRequest>1 ){
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
}
@ capabilities = %s(find_capabilities(zCap))<br />
|
>
|
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
|
@ g.zBaseURL = %h(g.zBaseURL)<br />
@ g.zHttpsURL = %h(g.zHttpsURL)<br />
@ g.zTop = %h(g.zTop)<br />
@ g.zPath = %h(g.zPath)<br />
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ g.isHuman = %d(g.isHuman)<br />
@ g.jsHref = %d(g.jsHref)<br />
if( g.nRequest ){
@ g.nRequest = %d(g.nRequest)<br />
}
if( g.nPendingRequest>1 ){
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
}
@ capabilities = %s(find_capabilities(zCap))<br />
|
| ︙ | | | ︙ | |