Fossil SCM

json: added a few assertions and changed a few chars to ints to avoid potential signedness problems on ARM.

stephan 2016-02-09 14:12 trunk
Commit 5c0dc2d3528a85ea74463ec801f7d5f22e608c0d
2 files changed +1 +15 -8
+1
--- src/cgi.c
+++ src/cgi.c
@@ -796,10 +796,11 @@
796796
cson_value * jv = NULL;
797797
int rc;
798798
CgiPostReadState state;
799799
cson_parse_opt popt = cson_parse_opt_empty;
800800
cson_parse_info pinfo = cson_parse_info_empty;
801
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
801802
popt.maxDepth = 15;
802803
state.fh = zIn;
803804
state.len = contentLen;
804805
state.pos = 0;
805806
rc = cson_parse( &jv,
806807
--- src/cgi.c
+++ src/cgi.c
@@ -796,10 +796,11 @@
796 cson_value * jv = NULL;
797 int rc;
798 CgiPostReadState state;
799 cson_parse_opt popt = cson_parse_opt_empty;
800 cson_parse_info pinfo = cson_parse_info_empty;
 
801 popt.maxDepth = 15;
802 state.fh = zIn;
803 state.len = contentLen;
804 state.pos = 0;
805 rc = cson_parse( &jv,
806
--- src/cgi.c
+++ src/cgi.c
@@ -796,10 +796,11 @@
796 cson_value * jv = NULL;
797 int rc;
798 CgiPostReadState state;
799 cson_parse_opt popt = cson_parse_opt_empty;
800 cson_parse_info pinfo = cson_parse_info_empty;
801 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
802 popt.maxDepth = 15;
803 state.fh = zIn;
804 state.len = contentLen;
805 state.pos = 0;
806 rc = cson_parse( &jv,
807
+15 -8
--- src/json.c
+++ src/json.c
@@ -222,10 +222,11 @@
222222
** allocation error (more likely than not) or a serious internal error
223223
** such as numeric overflow).
224224
*/
225225
void json_gc_add( char const * key, cson_value * v ){
226226
int const rc = cson_array_append( g.json.gc.a, v );
227
+
227228
assert( NULL != g.json.gc.a );
228229
if( 0 != rc ){
229230
cson_value_free( v );
230231
}
231232
assert( (0==rc) && "Adding item to GC failed." );
@@ -478,11 +479,11 @@
478479
** If the option is not found, dftl is returned.
479480
*/
480481
int json_find_option_bool(char const * zKey,
481482
char const * zCLILong,
482483
char const * zCLIShort,
483
- char dflt ){
484
+ int dflt ){
484485
int rc = -1;
485486
if(!g.isHTTP){
486487
if(NULL != find_option(zCLILong ? zCLILong : zKey,
487488
zCLIShort, 0)){
488489
rc = 1;
@@ -631,11 +632,12 @@
631632
** results).
632633
**
633634
** The result of this call are cached for future calls.
634635
*/
635636
cson_value * json_auth_token(){
636
- if( !g.json.authToken ){
637
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
638
+ if( !g.json.authToken ){
637639
/* Try to get an authorization token from GET parameter, POSTed
638640
JSON, or fossil cookie (in that order). */
639641
g.json.authToken = json_getenv(FossilJsonKeys.authToken);
640642
if(g.json.authToken
641643
&& cson_value_is_string(g.json.authToken)
@@ -704,11 +706,13 @@
704706
which need a long lifetime but don't have a logical parent to put
705707
them in.
706708
*/
707709
v = cson_value_new_array();
708710
g.json.gc.v = v;
711
+ assert(0 != g.json.gc.v);
709712
g.json.gc.a = cson_value_get_array(v);
713
+ assert(0 != g.json.gc.a);
710714
cson_value_add_reference(v)
711715
/* Needed to allow us to include this value in other JSON
712716
containers without transferring ownership to those containers.
713717
All other persistent g.json.XXX.v values get appended to
714718
g.json.gc.a, and therefore already have a live reference
@@ -755,10 +759,11 @@
755759
void json_warn( int code, char const * fmt, ... ){
756760
cson_object * obj = NULL;
757761
assert( (code>FSL_JSON_W_START)
758762
&& (code<FSL_JSON_W_END)
759763
&& "Invalid warning code.");
764
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
760765
if(!g.json.warnings){
761766
g.json.warnings = cson_new_array();
762767
assert((NULL != g.json.warnings) && "Alloc error.");
763768
json_gc_add("$WARNINGS",cson_array_value(g.json.warnings));
764769
}
@@ -801,11 +806,11 @@
801806
** Achtung: empty elements will be skipped, meaning consecutive empty
802807
** elements are collapsed.
803808
*/
804809
int json_string_split( char const * zStr,
805810
char separator,
806
- char doDeHttp,
811
+ int doDeHttp,
807812
cson_array * target ){
808813
char const * p = zStr /* current byte */;
809814
char const * head /* current start-of-token */;
810815
unsigned int len = 0 /* current token's length */;
811816
int rc = 0 /* return code (number of added elements)*/;
@@ -876,11 +881,11 @@
876881
** The returned value is owned by the caller. If not NULL then it
877882
** _will_ have a JSON type of Array.
878883
*/
879884
cson_value * json_string_split2( char const * zStr,
880885
char separator,
881
- char doDeHttp ){
886
+ int doDeHttp ){
882887
cson_array * a = cson_new_array();
883888
int rc = json_string_split( zStr, separator, doDeHttp, a );
884889
if( 0>=rc ){
885890
cson_free_array(a);
886891
a = NULL;
@@ -904,10 +909,11 @@
904909
** This must only be called once, or an assertion may be triggered.
905910
*/
906911
static void json_mode_bootstrap(){
907912
static char once = 0 /* guard against multiple runs */;
908913
char const * zPath = P("PATH_INFO");
914
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
909915
assert( (0==once) && "json_mode_bootstrap() called too many times!");
910916
if( once ){
911917
return;
912918
}else{
913919
once = 1;
@@ -1082,11 +1088,11 @@
10821088
**
10831089
** Note that CLI options are not included in the command path. Use
10841090
** find_option() to get those.
10851091
**
10861092
*/
1087
-char const * json_command_arg(unsigned char ndx){
1093
+char const * json_command_arg(unsigned short ndx){
10881094
cson_array * ar = g.json.cmd.a;
10891095
assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?");
10901096
assert((g.argc>1) && "Internal error - we never should have gotten this far.");
10911097
if( g.json.cmd.offset < 0 ){
10921098
/* first-time setup. */
@@ -1497,11 +1503,11 @@
14971503
**
14981504
** For generating the resultText property: if msg is not NULL then it
14991505
** is used as-is. If it is NULL then g.zErrMsg is checked, and if that
15001506
** is NULL then json_err_cstr(code) is used.
15011507
*/
1502
-void json_err( int code, char const * msg, char alsoOutput ){
1508
+void json_err( int code, char const * msg, int alsoOutput ){
15031509
int rc = code ? code : (g.json.resultCode
15041510
? g.json.resultCode
15051511
: FSL_JSON_E_UNKNOWN);
15061512
cson_value * resp = NULL;
15071513
rc = json_dumbdown_rc(rc);
@@ -1662,11 +1668,11 @@
16621668
**
16631669
** FIXME: change this to take a (char const *) instead of a blob,
16641670
** to simplify the trivial use-cases (which don't need a Blob).
16651671
*/
16661672
cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1667
- char resetBlob){
1673
+ int resetBlob){
16681674
Stmt q = empty_Stmt;
16691675
cson_value * pay = NULL;
16701676
assert( blob_size(pSql) > 0 );
16711677
db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
16721678
if(resetBlob){
@@ -1687,11 +1693,11 @@
16871693
** wrapper for that function).
16881694
**
16891695
** If there are no tags then this function returns NULL, not an empty
16901696
** Array.
16911697
*/
1692
-cson_value * json_tags_for_checkin_rid(int rid, char propagatingOnly){
1698
+cson_value * json_tags_for_checkin_rid(int rid, int propagatingOnly){
16931699
cson_value * v = NULL;
16941700
char * tags = info_tags_of_checkin(rid, propagatingOnly);
16951701
if(tags){
16961702
if(*tags){
16971703
v = json_string_split2(tags,',',0);
@@ -2221,10 +2227,11 @@
22212227
** This function dispatches them, and is the HTTP equivalent of
22222228
** json_cmd_top().
22232229
*/
22242230
void json_page_top(void){
22252231
char const * zCommand;
2232
+ assert(g.json.gc.a && "json_main_bootstrap() was not called!");
22262233
json_mode_bootstrap();
22272234
zCommand = json_command_arg(1);
22282235
if(!zCommand || !*zCommand){
22292236
json_dispatch_missing_args_err( JsonPageDefs,
22302237
"No command (sub-path) specified."
22312238
--- src/json.c
+++ src/json.c
@@ -222,10 +222,11 @@
222 ** allocation error (more likely than not) or a serious internal error
223 ** such as numeric overflow).
224 */
225 void json_gc_add( char const * key, cson_value * v ){
226 int const rc = cson_array_append( g.json.gc.a, v );
 
227 assert( NULL != g.json.gc.a );
228 if( 0 != rc ){
229 cson_value_free( v );
230 }
231 assert( (0==rc) && "Adding item to GC failed." );
@@ -478,11 +479,11 @@
478 ** If the option is not found, dftl is returned.
479 */
480 int json_find_option_bool(char const * zKey,
481 char const * zCLILong,
482 char const * zCLIShort,
483 char dflt ){
484 int rc = -1;
485 if(!g.isHTTP){
486 if(NULL != find_option(zCLILong ? zCLILong : zKey,
487 zCLIShort, 0)){
488 rc = 1;
@@ -631,11 +632,12 @@
631 ** results).
632 **
633 ** The result of this call are cached for future calls.
634 */
635 cson_value * json_auth_token(){
636 if( !g.json.authToken ){
 
637 /* Try to get an authorization token from GET parameter, POSTed
638 JSON, or fossil cookie (in that order). */
639 g.json.authToken = json_getenv(FossilJsonKeys.authToken);
640 if(g.json.authToken
641 && cson_value_is_string(g.json.authToken)
@@ -704,11 +706,13 @@
704 which need a long lifetime but don't have a logical parent to put
705 them in.
706 */
707 v = cson_value_new_array();
708 g.json.gc.v = v;
 
709 g.json.gc.a = cson_value_get_array(v);
 
710 cson_value_add_reference(v)
711 /* Needed to allow us to include this value in other JSON
712 containers without transferring ownership to those containers.
713 All other persistent g.json.XXX.v values get appended to
714 g.json.gc.a, and therefore already have a live reference
@@ -755,10 +759,11 @@
755 void json_warn( int code, char const * fmt, ... ){
756 cson_object * obj = NULL;
757 assert( (code>FSL_JSON_W_START)
758 && (code<FSL_JSON_W_END)
759 && "Invalid warning code.");
 
760 if(!g.json.warnings){
761 g.json.warnings = cson_new_array();
762 assert((NULL != g.json.warnings) && "Alloc error.");
763 json_gc_add("$WARNINGS",cson_array_value(g.json.warnings));
764 }
@@ -801,11 +806,11 @@
801 ** Achtung: empty elements will be skipped, meaning consecutive empty
802 ** elements are collapsed.
803 */
804 int json_string_split( char const * zStr,
805 char separator,
806 char doDeHttp,
807 cson_array * target ){
808 char const * p = zStr /* current byte */;
809 char const * head /* current start-of-token */;
810 unsigned int len = 0 /* current token's length */;
811 int rc = 0 /* return code (number of added elements)*/;
@@ -876,11 +881,11 @@
876 ** The returned value is owned by the caller. If not NULL then it
877 ** _will_ have a JSON type of Array.
878 */
879 cson_value * json_string_split2( char const * zStr,
880 char separator,
881 char doDeHttp ){
882 cson_array * a = cson_new_array();
883 int rc = json_string_split( zStr, separator, doDeHttp, a );
884 if( 0>=rc ){
885 cson_free_array(a);
886 a = NULL;
@@ -904,10 +909,11 @@
904 ** This must only be called once, or an assertion may be triggered.
905 */
906 static void json_mode_bootstrap(){
907 static char once = 0 /* guard against multiple runs */;
908 char const * zPath = P("PATH_INFO");
 
909 assert( (0==once) && "json_mode_bootstrap() called too many times!");
910 if( once ){
911 return;
912 }else{
913 once = 1;
@@ -1082,11 +1088,11 @@
1082 **
1083 ** Note that CLI options are not included in the command path. Use
1084 ** find_option() to get those.
1085 **
1086 */
1087 char const * json_command_arg(unsigned char ndx){
1088 cson_array * ar = g.json.cmd.a;
1089 assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?");
1090 assert((g.argc>1) && "Internal error - we never should have gotten this far.");
1091 if( g.json.cmd.offset < 0 ){
1092 /* first-time setup. */
@@ -1497,11 +1503,11 @@
1497 **
1498 ** For generating the resultText property: if msg is not NULL then it
1499 ** is used as-is. If it is NULL then g.zErrMsg is checked, and if that
1500 ** is NULL then json_err_cstr(code) is used.
1501 */
1502 void json_err( int code, char const * msg, char alsoOutput ){
1503 int rc = code ? code : (g.json.resultCode
1504 ? g.json.resultCode
1505 : FSL_JSON_E_UNKNOWN);
1506 cson_value * resp = NULL;
1507 rc = json_dumbdown_rc(rc);
@@ -1662,11 +1668,11 @@
1662 **
1663 ** FIXME: change this to take a (char const *) instead of a blob,
1664 ** to simplify the trivial use-cases (which don't need a Blob).
1665 */
1666 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1667 char resetBlob){
1668 Stmt q = empty_Stmt;
1669 cson_value * pay = NULL;
1670 assert( blob_size(pSql) > 0 );
1671 db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
1672 if(resetBlob){
@@ -1687,11 +1693,11 @@
1687 ** wrapper for that function).
1688 **
1689 ** If there are no tags then this function returns NULL, not an empty
1690 ** Array.
1691 */
1692 cson_value * json_tags_for_checkin_rid(int rid, char propagatingOnly){
1693 cson_value * v = NULL;
1694 char * tags = info_tags_of_checkin(rid, propagatingOnly);
1695 if(tags){
1696 if(*tags){
1697 v = json_string_split2(tags,',',0);
@@ -2221,10 +2227,11 @@
2221 ** This function dispatches them, and is the HTTP equivalent of
2222 ** json_cmd_top().
2223 */
2224 void json_page_top(void){
2225 char const * zCommand;
 
2226 json_mode_bootstrap();
2227 zCommand = json_command_arg(1);
2228 if(!zCommand || !*zCommand){
2229 json_dispatch_missing_args_err( JsonPageDefs,
2230 "No command (sub-path) specified."
2231
--- src/json.c
+++ src/json.c
@@ -222,10 +222,11 @@
222 ** allocation error (more likely than not) or a serious internal error
223 ** such as numeric overflow).
224 */
225 void json_gc_add( char const * key, cson_value * v ){
226 int const rc = cson_array_append( g.json.gc.a, v );
227
228 assert( NULL != g.json.gc.a );
229 if( 0 != rc ){
230 cson_value_free( v );
231 }
232 assert( (0==rc) && "Adding item to GC failed." );
@@ -478,11 +479,11 @@
479 ** If the option is not found, dftl is returned.
480 */
481 int json_find_option_bool(char const * zKey,
482 char const * zCLILong,
483 char const * zCLIShort,
484 int dflt ){
485 int rc = -1;
486 if(!g.isHTTP){
487 if(NULL != find_option(zCLILong ? zCLILong : zKey,
488 zCLIShort, 0)){
489 rc = 1;
@@ -631,11 +632,12 @@
632 ** results).
633 **
634 ** The result of this call are cached for future calls.
635 */
636 cson_value * json_auth_token(){
637 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
638 if( !g.json.authToken ){
639 /* Try to get an authorization token from GET parameter, POSTed
640 JSON, or fossil cookie (in that order). */
641 g.json.authToken = json_getenv(FossilJsonKeys.authToken);
642 if(g.json.authToken
643 && cson_value_is_string(g.json.authToken)
@@ -704,11 +706,13 @@
706 which need a long lifetime but don't have a logical parent to put
707 them in.
708 */
709 v = cson_value_new_array();
710 g.json.gc.v = v;
711 assert(0 != g.json.gc.v);
712 g.json.gc.a = cson_value_get_array(v);
713 assert(0 != g.json.gc.a);
714 cson_value_add_reference(v)
715 /* Needed to allow us to include this value in other JSON
716 containers without transferring ownership to those containers.
717 All other persistent g.json.XXX.v values get appended to
718 g.json.gc.a, and therefore already have a live reference
@@ -755,10 +759,11 @@
759 void json_warn( int code, char const * fmt, ... ){
760 cson_object * obj = NULL;
761 assert( (code>FSL_JSON_W_START)
762 && (code<FSL_JSON_W_END)
763 && "Invalid warning code.");
764 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
765 if(!g.json.warnings){
766 g.json.warnings = cson_new_array();
767 assert((NULL != g.json.warnings) && "Alloc error.");
768 json_gc_add("$WARNINGS",cson_array_value(g.json.warnings));
769 }
@@ -801,11 +806,11 @@
806 ** Achtung: empty elements will be skipped, meaning consecutive empty
807 ** elements are collapsed.
808 */
809 int json_string_split( char const * zStr,
810 char separator,
811 int doDeHttp,
812 cson_array * target ){
813 char const * p = zStr /* current byte */;
814 char const * head /* current start-of-token */;
815 unsigned int len = 0 /* current token's length */;
816 int rc = 0 /* return code (number of added elements)*/;
@@ -876,11 +881,11 @@
881 ** The returned value is owned by the caller. If not NULL then it
882 ** _will_ have a JSON type of Array.
883 */
884 cson_value * json_string_split2( char const * zStr,
885 char separator,
886 int doDeHttp ){
887 cson_array * a = cson_new_array();
888 int rc = json_string_split( zStr, separator, doDeHttp, a );
889 if( 0>=rc ){
890 cson_free_array(a);
891 a = NULL;
@@ -904,10 +909,11 @@
909 ** This must only be called once, or an assertion may be triggered.
910 */
911 static void json_mode_bootstrap(){
912 static char once = 0 /* guard against multiple runs */;
913 char const * zPath = P("PATH_INFO");
914 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
915 assert( (0==once) && "json_mode_bootstrap() called too many times!");
916 if( once ){
917 return;
918 }else{
919 once = 1;
@@ -1082,11 +1088,11 @@
1088 **
1089 ** Note that CLI options are not included in the command path. Use
1090 ** find_option() to get those.
1091 **
1092 */
1093 char const * json_command_arg(unsigned short ndx){
1094 cson_array * ar = g.json.cmd.a;
1095 assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?");
1096 assert((g.argc>1) && "Internal error - we never should have gotten this far.");
1097 if( g.json.cmd.offset < 0 ){
1098 /* first-time setup. */
@@ -1497,11 +1503,11 @@
1503 **
1504 ** For generating the resultText property: if msg is not NULL then it
1505 ** is used as-is. If it is NULL then g.zErrMsg is checked, and if that
1506 ** is NULL then json_err_cstr(code) is used.
1507 */
1508 void json_err( int code, char const * msg, int alsoOutput ){
1509 int rc = code ? code : (g.json.resultCode
1510 ? g.json.resultCode
1511 : FSL_JSON_E_UNKNOWN);
1512 cson_value * resp = NULL;
1513 rc = json_dumbdown_rc(rc);
@@ -1662,11 +1668,11 @@
1668 **
1669 ** FIXME: change this to take a (char const *) instead of a blob,
1670 ** to simplify the trivial use-cases (which don't need a Blob).
1671 */
1672 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1673 int resetBlob){
1674 Stmt q = empty_Stmt;
1675 cson_value * pay = NULL;
1676 assert( blob_size(pSql) > 0 );
1677 db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
1678 if(resetBlob){
@@ -1687,11 +1693,11 @@
1693 ** wrapper for that function).
1694 **
1695 ** If there are no tags then this function returns NULL, not an empty
1696 ** Array.
1697 */
1698 cson_value * json_tags_for_checkin_rid(int rid, int propagatingOnly){
1699 cson_value * v = NULL;
1700 char * tags = info_tags_of_checkin(rid, propagatingOnly);
1701 if(tags){
1702 if(*tags){
1703 v = json_string_split2(tags,',',0);
@@ -2221,10 +2227,11 @@
2227 ** This function dispatches them, and is the HTTP equivalent of
2228 ** json_cmd_top().
2229 */
2230 void json_page_top(void){
2231 char const * zCommand;
2232 assert(g.json.gc.a && "json_main_bootstrap() was not called!");
2233 json_mode_bootstrap();
2234 zCommand = json_command_arg(1);
2235 if(!zCommand || !*zCommand){
2236 json_dispatch_missing_args_err( JsonPageDefs,
2237 "No command (sub-path) specified."
2238

Keyboard Shortcuts

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