Fossil SCM

The variadic function builtin_fossil_js_bundle_or() was using 0 as a sentinel to detect end-of-list, but that isn't equivalent to NULL in a list of pointed-to objects in all C compilers, on all systems. Using a GCC/Clang function attribute to force a warning when 0 is passed instead of NULL, then fixed all resulting warnings. This fixes the SEGV reported in https://www.fossil-scm.org/forum/forumpost/5feca9c36a on Mac OS X 10.11 with Clang from Xcode 7. Later versions of Clang on macOS don't have this problem, but it's still UB, so fixing it may solve some pain for us later on.

wyoung 2020-12-04 18:35 trunk
Commit 815b4fc493c433a0e4f8aebe79f4f6b34e1104c33035cc3f8d0c8f43844ba20e
+3 -3
--- src/builtin.c
+++ src/builtin.c
@@ -843,18 +843,18 @@
843843
** builtin_request_js()) with any other app-/page-specific JS it may
844844
** need.
845845
**
846846
** Example usage:
847847
**
848
-** builtin_fossil_js_bundle_or("dom", "fetch", 0);
848
+** builtin_fossil_js_bundle_or("dom", "fetch", NULL);
849849
**
850850
** In bundled mode, that will (the first time it is called) emit all
851851
** builtin fossil JS APIs and "fulfill" the queue immediately. In
852852
** non-bundled mode it will queue up the "dom" and "fetch" APIs to be
853853
** emitted the next time builtin_fulfill_js_requests() is called.
854854
*/
855
-void builtin_fossil_js_bundle_or( const char * zApi, ... ) {
855
+NULL_SENTINEL void builtin_fossil_js_bundle_or( const char * zApi, ... ) {
856856
static int bundled = 0;
857857
const char *zArg;
858858
va_list vargs;
859859
860860
if(JS_BUNDLED == builtin_get_js_delivery_mode()){
@@ -864,12 +864,12 @@
864864
builtin_fulfill_js_requests();
865865
}
866866
return;
867867
}
868868
va_start(vargs,zApi);
869
- for( zArg = zApi; zArg!=0; (zArg = va_arg (vargs, const char *))){
869
+ for( zArg = zApi; zArg!=NULL; (zArg = va_arg (vargs, const char *))){
870870
if(0==builtin_emit_fossil_js_once(zArg)){
871871
fossil_fatal("Unknown fossil JS module: %s\n", zArg);
872872
}
873873
}
874874
va_end(vargs);
875875
}
876876
--- src/builtin.c
+++ src/builtin.c
@@ -843,18 +843,18 @@
843 ** builtin_request_js()) with any other app-/page-specific JS it may
844 ** need.
845 **
846 ** Example usage:
847 **
848 ** builtin_fossil_js_bundle_or("dom", "fetch", 0);
849 **
850 ** In bundled mode, that will (the first time it is called) emit all
851 ** builtin fossil JS APIs and "fulfill" the queue immediately. In
852 ** non-bundled mode it will queue up the "dom" and "fetch" APIs to be
853 ** emitted the next time builtin_fulfill_js_requests() is called.
854 */
855 void builtin_fossil_js_bundle_or( const char * zApi, ... ) {
856 static int bundled = 0;
857 const char *zArg;
858 va_list vargs;
859
860 if(JS_BUNDLED == builtin_get_js_delivery_mode()){
@@ -864,12 +864,12 @@
864 builtin_fulfill_js_requests();
865 }
866 return;
867 }
868 va_start(vargs,zApi);
869 for( zArg = zApi; zArg!=0; (zArg = va_arg (vargs, const char *))){
870 if(0==builtin_emit_fossil_js_once(zArg)){
871 fossil_fatal("Unknown fossil JS module: %s\n", zArg);
872 }
873 }
874 va_end(vargs);
875 }
876
--- src/builtin.c
+++ src/builtin.c
@@ -843,18 +843,18 @@
843 ** builtin_request_js()) with any other app-/page-specific JS it may
844 ** need.
845 **
846 ** Example usage:
847 **
848 ** builtin_fossil_js_bundle_or("dom", "fetch", NULL);
849 **
850 ** In bundled mode, that will (the first time it is called) emit all
851 ** builtin fossil JS APIs and "fulfill" the queue immediately. In
852 ** non-bundled mode it will queue up the "dom" and "fetch" APIs to be
853 ** emitted the next time builtin_fulfill_js_requests() is called.
854 */
855 NULL_SENTINEL void builtin_fossil_js_bundle_or( const char * zApi, ... ) {
856 static int bundled = 0;
857 const char *zArg;
858 va_list vargs;
859
860 if(JS_BUNDLED == builtin_get_js_delivery_mode()){
@@ -864,12 +864,12 @@
864 builtin_fulfill_js_requests();
865 }
866 return;
867 }
868 va_start(vargs,zApi);
869 for( zArg = zApi; zArg!=NULL; (zArg = va_arg (vargs, const char *))){
870 if(0==builtin_emit_fossil_js_once(zArg)){
871 fossil_fatal("Unknown fossil JS module: %s\n", zArg);
872 }
873 }
874 va_end(vargs);
875 }
876
--- src/config.h
+++ src/config.h
@@ -245,14 +245,17 @@
245245
/*
246246
** A marker for functions that never return.
247247
*/
248248
#if defined(__GNUC__) || defined(__clang__)
249249
# define NORETURN __attribute__((__noreturn__))
250
+# define NULL_SENTINEL __attribute__((sentinel))
250251
#elif defined(_MSC_VER) && (_MSC_VER >= 1310)
251252
# define NORETURN __declspec(noreturn)
253
+# define NULL_SENTINEL
252254
#else
253255
# define NORETURN
256
+# define NULL_SENTINEL
254257
#endif
255258
256259
/*
257260
** Number of elements in an array
258261
*/
259262
--- src/config.h
+++ src/config.h
@@ -245,14 +245,17 @@
245 /*
246 ** A marker for functions that never return.
247 */
248 #if defined(__GNUC__) || defined(__clang__)
249 # define NORETURN __attribute__((__noreturn__))
 
250 #elif defined(_MSC_VER) && (_MSC_VER >= 1310)
251 # define NORETURN __declspec(noreturn)
 
252 #else
253 # define NORETURN
 
254 #endif
255
256 /*
257 ** Number of elements in an array
258 */
259
--- src/config.h
+++ src/config.h
@@ -245,14 +245,17 @@
245 /*
246 ** A marker for functions that never return.
247 */
248 #if defined(__GNUC__) || defined(__clang__)
249 # define NORETURN __attribute__((__noreturn__))
250 # define NULL_SENTINEL __attribute__((sentinel))
251 #elif defined(_MSC_VER) && (_MSC_VER >= 1310)
252 # define NORETURN __declspec(noreturn)
253 # define NULL_SENTINEL
254 #else
255 # define NORETURN
256 # define NULL_SENTINEL
257 #endif
258
259 /*
260 ** Number of elements in an array
261 */
262
+1 -1
--- src/doc.c
+++ src/doc.c
@@ -408,11 +408,11 @@
408408
** no-ops.
409409
*/
410410
void document_emit_js(void){
411411
static int once = 0;
412412
if(0==once++){
413
- builtin_fossil_js_bundle_or("pikchr", 0);
413
+ builtin_fossil_js_bundle_or("pikchr", NULL);
414414
style_script_begin(__FILE__,__LINE__);
415415
CX("window.addEventListener('load', "
416416
"()=>window.fossil.pikchr.addSrcView(), "
417417
"false);\n");
418418
style_script_end();
419419
--- src/doc.c
+++ src/doc.c
@@ -408,11 +408,11 @@
408 ** no-ops.
409 */
410 void document_emit_js(void){
411 static int once = 0;
412 if(0==once++){
413 builtin_fossil_js_bundle_or("pikchr", 0);
414 style_script_begin(__FILE__,__LINE__);
415 CX("window.addEventListener('load', "
416 "()=>window.fossil.pikchr.addSrcView(), "
417 "false);\n");
418 style_script_end();
419
--- src/doc.c
+++ src/doc.c
@@ -408,11 +408,11 @@
408 ** no-ops.
409 */
410 void document_emit_js(void){
411 static int once = 0;
412 if(0==once++){
413 builtin_fossil_js_bundle_or("pikchr", NULL);
414 style_script_begin(__FILE__,__LINE__);
415 CX("window.addEventListener('load', "
416 "()=>window.fossil.pikchr.addSrcView(), "
417 "false);\n");
418 style_script_end();
419
+1 -1
--- src/fileedit.c
+++ src/fileedit.c
@@ -1989,11 +1989,11 @@
19891989
}
19901990
CX("</div>"/*#fileedit-tab-help*/);
19911991
19921992
builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
19931993
"storage", "popupwidget", "copybutton",
1994
- "pikchr", 0);
1994
+ "pikchr", NULL);
19951995
/*
19961996
** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
19971997
** used for dynamically toggling certain UI components on and off.
19981998
** Must come after window.fossil has been intialized and before
19991999
** fossil.page.fileedit.js. Potential TODO: move this into the
20002000
--- src/fileedit.c
+++ src/fileedit.c
@@ -1989,11 +1989,11 @@
1989 }
1990 CX("</div>"/*#fileedit-tab-help*/);
1991
1992 builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
1993 "storage", "popupwidget", "copybutton",
1994 "pikchr", 0);
1995 /*
1996 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1997 ** used for dynamically toggling certain UI components on and off.
1998 ** Must come after window.fossil has been intialized and before
1999 ** fossil.page.fileedit.js. Potential TODO: move this into the
2000
--- src/fileedit.c
+++ src/fileedit.c
@@ -1989,11 +1989,11 @@
1989 }
1990 CX("</div>"/*#fileedit-tab-help*/);
1991
1992 builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
1993 "storage", "popupwidget", "copybutton",
1994 "pikchr", NULL);
1995 /*
1996 ** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
1997 ** used for dynamically toggling certain UI components on and off.
1998 ** Must come after window.fossil has been intialized and before
1999 ** fossil.page.fileedit.js. Potential TODO: move this into the
2000
+1 -1
--- src/forum.c
+++ src/forum.c
@@ -743,11 +743,11 @@
743743
** Emit Forum Javascript which applies (or optionally can apply)
744744
** to all forum-related pages. It does not include page-specific
745745
** code (e.g. "forum.js").
746746
*/
747747
static void forum_emit_js(void){
748
- builtin_fossil_js_bundle_or("copybutton", "pikchr", 0);
748
+ builtin_fossil_js_bundle_or("copybutton", "pikchr", NULL);
749749
builtin_request_js("fossil.page.forumpost.js");
750750
}
751751
752752
/*
753753
** WEBPAGE: forumpost
754754
--- src/forum.c
+++ src/forum.c
@@ -743,11 +743,11 @@
743 ** Emit Forum Javascript which applies (or optionally can apply)
744 ** to all forum-related pages. It does not include page-specific
745 ** code (e.g. "forum.js").
746 */
747 static void forum_emit_js(void){
748 builtin_fossil_js_bundle_or("copybutton", "pikchr", 0);
749 builtin_request_js("fossil.page.forumpost.js");
750 }
751
752 /*
753 ** WEBPAGE: forumpost
754
--- src/forum.c
+++ src/forum.c
@@ -743,11 +743,11 @@
743 ** Emit Forum Javascript which applies (or optionally can apply)
744 ** to all forum-related pages. It does not include page-specific
745 ** code (e.g. "forum.js").
746 */
747 static void forum_emit_js(void){
748 builtin_fossil_js_bundle_or("copybutton", "pikchr", NULL);
749 builtin_request_js("fossil.page.forumpost.js");
750 }
751
752 /*
753 ** WEBPAGE: forumpost
754
+1 -1
--- src/info.c
+++ src/info.c
@@ -2136,11 +2136,11 @@
21362136
if(includeJS && !emittedJS){
21372137
emittedJS = 1;
21382138
if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
21392139
builtin_request_js("scroll.js");
21402140
}
2141
- builtin_fossil_js_bundle_or("numbered-lines", 0);
2141
+ builtin_fossil_js_bundle_or("numbered-lines", NULL);
21422142
}
21432143
}
21442144
21452145
/*
21462146
** COMMAND: test-line-numbers
21472147
--- src/info.c
+++ src/info.c
@@ -2136,11 +2136,11 @@
2136 if(includeJS && !emittedJS){
2137 emittedJS = 1;
2138 if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
2139 builtin_request_js("scroll.js");
2140 }
2141 builtin_fossil_js_bundle_or("numbered-lines", 0);
2142 }
2143 }
2144
2145 /*
2146 ** COMMAND: test-line-numbers
2147
--- src/info.c
+++ src/info.c
@@ -2136,11 +2136,11 @@
2136 if(includeJS && !emittedJS){
2137 emittedJS = 1;
2138 if( db_int(0, "SELECT EXISTS(SELECT 1 FROM lnos)") ){
2139 builtin_request_js("scroll.js");
2140 }
2141 builtin_fossil_js_bundle_or("numbered-lines", NULL);
2142 }
2143 }
2144
2145 /*
2146 ** COMMAND: test-line-numbers
2147
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -371,11 +371,11 @@
371371
blob_reset(&out);
372372
} CX("</div>"/*#pikchrshow-output*/);
373373
} CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
374374
} CX("</div>"/*sbs-wrapper*/);
375375
builtin_fossil_js_bundle_or("fetch", "copybutton", "popupwidget",
376
- "storage", "pikchr", 0);
376
+ "storage", "pikchr", NULL);
377377
builtin_request_js("fossil.page.pikchrshow.js");
378378
builtin_fulfill_js_requests();
379379
style_finish_page("pikchrshow");
380380
}
381381
382382
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -371,11 +371,11 @@
371 blob_reset(&out);
372 } CX("</div>"/*#pikchrshow-output*/);
373 } CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
374 } CX("</div>"/*sbs-wrapper*/);
375 builtin_fossil_js_bundle_or("fetch", "copybutton", "popupwidget",
376 "storage", "pikchr", 0);
377 builtin_request_js("fossil.page.pikchrshow.js");
378 builtin_fulfill_js_requests();
379 style_finish_page("pikchrshow");
380 }
381
382
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -371,11 +371,11 @@
371 blob_reset(&out);
372 } CX("</div>"/*#pikchrshow-output*/);
373 } CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
374 } CX("</div>"/*sbs-wrapper*/);
375 builtin_fossil_js_bundle_or("fetch", "copybutton", "popupwidget",
376 "storage", "pikchr", NULL);
377 builtin_request_js("fossil.page.pikchrshow.js");
378 builtin_fulfill_js_requests();
379 style_finish_page("pikchrshow");
380 }
381
382
+1 -1
--- src/wiki.c
+++ src/wiki.c
@@ -1299,11 +1299,11 @@
12991299
well_formed_wiki_name_rules();
13001300
CX("</div>"/*#wikiedit-tab-save*/);
13011301
}
13021302
builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
13031303
"storage", "popupwidget", "copybutton",
1304
- "pikchr", 0);
1304
+ "pikchr", NULL);
13051305
builtin_request_js("sbsdiff.js");
13061306
builtin_request_js("fossil.page.wikiedit.js");
13071307
builtin_fulfill_js_requests();
13081308
/* Dynamically populate the editor... */
13091309
style_script_begin(__FILE__,__LINE__);
13101310
--- src/wiki.c
+++ src/wiki.c
@@ -1299,11 +1299,11 @@
1299 well_formed_wiki_name_rules();
1300 CX("</div>"/*#wikiedit-tab-save*/);
1301 }
1302 builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
1303 "storage", "popupwidget", "copybutton",
1304 "pikchr", 0);
1305 builtin_request_js("sbsdiff.js");
1306 builtin_request_js("fossil.page.wikiedit.js");
1307 builtin_fulfill_js_requests();
1308 /* Dynamically populate the editor... */
1309 style_script_begin(__FILE__,__LINE__);
1310
--- src/wiki.c
+++ src/wiki.c
@@ -1299,11 +1299,11 @@
1299 well_formed_wiki_name_rules();
1300 CX("</div>"/*#wikiedit-tab-save*/);
1301 }
1302 builtin_fossil_js_bundle_or("fetch", "dom", "tabs", "confirmer",
1303 "storage", "popupwidget", "copybutton",
1304 "pikchr", NULL);
1305 builtin_request_js("sbsdiff.js");
1306 builtin_request_js("fossil.page.wikiedit.js");
1307 builtin_fulfill_js_requests();
1308 /* Dynamically populate the editor... */
1309 style_script_begin(__FILE__,__LINE__);
1310

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button