Fossil SCM
json: added a few assertions and changed a few chars to ints to avoid potential signedness problems on ARM.
Commit
5c0dc2d3528a85ea74463ec801f7d5f22e608c0d
Parent
7cadfc973630281…
2 files changed
+1
+15
-8
+1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -796,10 +796,11 @@ | ||
| 796 | 796 | cson_value * jv = NULL; |
| 797 | 797 | int rc; |
| 798 | 798 | CgiPostReadState state; |
| 799 | 799 | cson_parse_opt popt = cson_parse_opt_empty; |
| 800 | 800 | cson_parse_info pinfo = cson_parse_info_empty; |
| 801 | + assert(g.json.gc.a && "json_main_bootstrap() was not called!"); | |
| 801 | 802 | popt.maxDepth = 15; |
| 802 | 803 | state.fh = zIn; |
| 803 | 804 | state.len = contentLen; |
| 804 | 805 | state.pos = 0; |
| 805 | 806 | rc = cson_parse( &jv, |
| 806 | 807 |
| --- 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 @@ | ||
| 222 | 222 | ** allocation error (more likely than not) or a serious internal error |
| 223 | 223 | ** such as numeric overflow). |
| 224 | 224 | */ |
| 225 | 225 | void json_gc_add( char const * key, cson_value * v ){ |
| 226 | 226 | int const rc = cson_array_append( g.json.gc.a, v ); |
| 227 | + | |
| 227 | 228 | assert( NULL != g.json.gc.a ); |
| 228 | 229 | if( 0 != rc ){ |
| 229 | 230 | cson_value_free( v ); |
| 230 | 231 | } |
| 231 | 232 | assert( (0==rc) && "Adding item to GC failed." ); |
| @@ -478,11 +479,11 @@ | ||
| 478 | 479 | ** If the option is not found, dftl is returned. |
| 479 | 480 | */ |
| 480 | 481 | int json_find_option_bool(char const * zKey, |
| 481 | 482 | char const * zCLILong, |
| 482 | 483 | char const * zCLIShort, |
| 483 | - char dflt ){ | |
| 484 | + int dflt ){ | |
| 484 | 485 | int rc = -1; |
| 485 | 486 | if(!g.isHTTP){ |
| 486 | 487 | if(NULL != find_option(zCLILong ? zCLILong : zKey, |
| 487 | 488 | zCLIShort, 0)){ |
| 488 | 489 | rc = 1; |
| @@ -631,11 +632,12 @@ | ||
| 631 | 632 | ** results). |
| 632 | 633 | ** |
| 633 | 634 | ** The result of this call are cached for future calls. |
| 634 | 635 | */ |
| 635 | 636 | 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 ){ | |
| 637 | 639 | /* Try to get an authorization token from GET parameter, POSTed |
| 638 | 640 | JSON, or fossil cookie (in that order). */ |
| 639 | 641 | g.json.authToken = json_getenv(FossilJsonKeys.authToken); |
| 640 | 642 | if(g.json.authToken |
| 641 | 643 | && cson_value_is_string(g.json.authToken) |
| @@ -704,11 +706,13 @@ | ||
| 704 | 706 | which need a long lifetime but don't have a logical parent to put |
| 705 | 707 | them in. |
| 706 | 708 | */ |
| 707 | 709 | v = cson_value_new_array(); |
| 708 | 710 | g.json.gc.v = v; |
| 711 | + assert(0 != g.json.gc.v); | |
| 709 | 712 | g.json.gc.a = cson_value_get_array(v); |
| 713 | + assert(0 != g.json.gc.a); | |
| 710 | 714 | cson_value_add_reference(v) |
| 711 | 715 | /* Needed to allow us to include this value in other JSON |
| 712 | 716 | containers without transferring ownership to those containers. |
| 713 | 717 | All other persistent g.json.XXX.v values get appended to |
| 714 | 718 | g.json.gc.a, and therefore already have a live reference |
| @@ -755,10 +759,11 @@ | ||
| 755 | 759 | void json_warn( int code, char const * fmt, ... ){ |
| 756 | 760 | cson_object * obj = NULL; |
| 757 | 761 | assert( (code>FSL_JSON_W_START) |
| 758 | 762 | && (code<FSL_JSON_W_END) |
| 759 | 763 | && "Invalid warning code."); |
| 764 | + assert(g.json.gc.a && "json_main_bootstrap() was not called!"); | |
| 760 | 765 | if(!g.json.warnings){ |
| 761 | 766 | g.json.warnings = cson_new_array(); |
| 762 | 767 | assert((NULL != g.json.warnings) && "Alloc error."); |
| 763 | 768 | json_gc_add("$WARNINGS",cson_array_value(g.json.warnings)); |
| 764 | 769 | } |
| @@ -801,11 +806,11 @@ | ||
| 801 | 806 | ** Achtung: empty elements will be skipped, meaning consecutive empty |
| 802 | 807 | ** elements are collapsed. |
| 803 | 808 | */ |
| 804 | 809 | int json_string_split( char const * zStr, |
| 805 | 810 | char separator, |
| 806 | - char doDeHttp, | |
| 811 | + int doDeHttp, | |
| 807 | 812 | cson_array * target ){ |
| 808 | 813 | char const * p = zStr /* current byte */; |
| 809 | 814 | char const * head /* current start-of-token */; |
| 810 | 815 | unsigned int len = 0 /* current token's length */; |
| 811 | 816 | int rc = 0 /* return code (number of added elements)*/; |
| @@ -876,11 +881,11 @@ | ||
| 876 | 881 | ** The returned value is owned by the caller. If not NULL then it |
| 877 | 882 | ** _will_ have a JSON type of Array. |
| 878 | 883 | */ |
| 879 | 884 | cson_value * json_string_split2( char const * zStr, |
| 880 | 885 | char separator, |
| 881 | - char doDeHttp ){ | |
| 886 | + int doDeHttp ){ | |
| 882 | 887 | cson_array * a = cson_new_array(); |
| 883 | 888 | int rc = json_string_split( zStr, separator, doDeHttp, a ); |
| 884 | 889 | if( 0>=rc ){ |
| 885 | 890 | cson_free_array(a); |
| 886 | 891 | a = NULL; |
| @@ -904,10 +909,11 @@ | ||
| 904 | 909 | ** This must only be called once, or an assertion may be triggered. |
| 905 | 910 | */ |
| 906 | 911 | static void json_mode_bootstrap(){ |
| 907 | 912 | static char once = 0 /* guard against multiple runs */; |
| 908 | 913 | char const * zPath = P("PATH_INFO"); |
| 914 | + assert(g.json.gc.a && "json_main_bootstrap() was not called!"); | |
| 909 | 915 | assert( (0==once) && "json_mode_bootstrap() called too many times!"); |
| 910 | 916 | if( once ){ |
| 911 | 917 | return; |
| 912 | 918 | }else{ |
| 913 | 919 | once = 1; |
| @@ -1082,11 +1088,11 @@ | ||
| 1082 | 1088 | ** |
| 1083 | 1089 | ** Note that CLI options are not included in the command path. Use |
| 1084 | 1090 | ** find_option() to get those. |
| 1085 | 1091 | ** |
| 1086 | 1092 | */ |
| 1087 | -char const * json_command_arg(unsigned char ndx){ | |
| 1093 | +char const * json_command_arg(unsigned short ndx){ | |
| 1088 | 1094 | cson_array * ar = g.json.cmd.a; |
| 1089 | 1095 | assert((NULL!=ar) && "Internal error. Was json_mode_bootstrap() called?"); |
| 1090 | 1096 | assert((g.argc>1) && "Internal error - we never should have gotten this far."); |
| 1091 | 1097 | if( g.json.cmd.offset < 0 ){ |
| 1092 | 1098 | /* first-time setup. */ |
| @@ -1497,11 +1503,11 @@ | ||
| 1497 | 1503 | ** |
| 1498 | 1504 | ** For generating the resultText property: if msg is not NULL then it |
| 1499 | 1505 | ** is used as-is. If it is NULL then g.zErrMsg is checked, and if that |
| 1500 | 1506 | ** is NULL then json_err_cstr(code) is used. |
| 1501 | 1507 | */ |
| 1502 | -void json_err( int code, char const * msg, char alsoOutput ){ | |
| 1508 | +void json_err( int code, char const * msg, int alsoOutput ){ | |
| 1503 | 1509 | int rc = code ? code : (g.json.resultCode |
| 1504 | 1510 | ? g.json.resultCode |
| 1505 | 1511 | : FSL_JSON_E_UNKNOWN); |
| 1506 | 1512 | cson_value * resp = NULL; |
| 1507 | 1513 | rc = json_dumbdown_rc(rc); |
| @@ -1662,11 +1668,11 @@ | ||
| 1662 | 1668 | ** |
| 1663 | 1669 | ** FIXME: change this to take a (char const *) instead of a blob, |
| 1664 | 1670 | ** to simplify the trivial use-cases (which don't need a Blob). |
| 1665 | 1671 | */ |
| 1666 | 1672 | cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt, |
| 1667 | - char resetBlob){ | |
| 1673 | + int resetBlob){ | |
| 1668 | 1674 | Stmt q = empty_Stmt; |
| 1669 | 1675 | cson_value * pay = NULL; |
| 1670 | 1676 | assert( blob_size(pSql) > 0 ); |
| 1671 | 1677 | db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/); |
| 1672 | 1678 | if(resetBlob){ |
| @@ -1687,11 +1693,11 @@ | ||
| 1687 | 1693 | ** wrapper for that function). |
| 1688 | 1694 | ** |
| 1689 | 1695 | ** If there are no tags then this function returns NULL, not an empty |
| 1690 | 1696 | ** Array. |
| 1691 | 1697 | */ |
| 1692 | -cson_value * json_tags_for_checkin_rid(int rid, char propagatingOnly){ | |
| 1698 | +cson_value * json_tags_for_checkin_rid(int rid, int propagatingOnly){ | |
| 1693 | 1699 | cson_value * v = NULL; |
| 1694 | 1700 | char * tags = info_tags_of_checkin(rid, propagatingOnly); |
| 1695 | 1701 | if(tags){ |
| 1696 | 1702 | if(*tags){ |
| 1697 | 1703 | v = json_string_split2(tags,',',0); |
| @@ -2221,10 +2227,11 @@ | ||
| 2221 | 2227 | ** This function dispatches them, and is the HTTP equivalent of |
| 2222 | 2228 | ** json_cmd_top(). |
| 2223 | 2229 | */ |
| 2224 | 2230 | void json_page_top(void){ |
| 2225 | 2231 | char const * zCommand; |
| 2232 | + assert(g.json.gc.a && "json_main_bootstrap() was not called!"); | |
| 2226 | 2233 | json_mode_bootstrap(); |
| 2227 | 2234 | zCommand = json_command_arg(1); |
| 2228 | 2235 | if(!zCommand || !*zCommand){ |
| 2229 | 2236 | json_dispatch_missing_args_err( JsonPageDefs, |
| 2230 | 2237 | "No command (sub-path) specified." |
| 2231 | 2238 |
| --- 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 |