diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-10-02 19:17:10 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-10-02 19:22:24 +0200 |
commit | 8ede779516df565619052f42c87b54cc055021bd (patch) | |
tree | 1e76b1ebebde2f1f53cb7214bfbf0ec8d45d2bc1 | |
parent | 206630d7141f32594e9110081f6710446f5aebd3 (diff) |
treewide: rework handling of memory allocation failures
Instead of propagating failures to the caller, print a generic error
message and terminate program execution through abort().
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | ast.c | 101 | ||||
-rw-r--r-- | ast.h | 132 | ||||
-rw-r--r-- | eval.c | 104 | ||||
-rw-r--r-- | lexer.c | 14 | ||||
-rw-r--r-- | lib.c | 284 | ||||
-rw-r--r-- | main.c | 27 | ||||
-rw-r--r-- | parser.y | 2 |
7 files changed, 291 insertions, 373 deletions
@@ -52,7 +52,7 @@ ut_get_child(struct ut_state *s, uint32_t off, int n) uint32_t ut_new_op(struct ut_state *s, int type, struct json_object *val, ...) { - struct ut_op *newop, *pool; + struct ut_op *newop; uint32_t child; int n_op = 0; va_list ap; @@ -62,14 +62,9 @@ ut_new_op(struct ut_state *s, int type, struct json_object *val, ...) exit(127); } - pool = realloc(s->pool, (s->poolsize + 1) * sizeof(*newop)); + s->pool = xrealloc(s->pool, (s->poolsize + 1) * sizeof(*newop)); - if (!pool) { - fprintf(stderr, "Out of memory\n"); - exit(127); - } - - newop = &pool[s->poolsize]; + newop = &s->pool[s->poolsize]; memset(newop, 0, sizeof(*newop)); newop->is_first = !s->poolsize; @@ -85,7 +80,6 @@ ut_new_op(struct ut_state *s, int type, struct json_object *val, ...) va_end(ap); - s->pool = pool; s->poolsize++; return s->poolsize; @@ -145,6 +139,11 @@ ut_new_double(double v) { struct json_object *d = json_object_new_double(v); + if (!d) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + json_object_set_serializer(d, double_rounded_to_string, NULL, NULL); return d; @@ -161,6 +160,11 @@ ut_new_null(void) { struct json_object *d = json_object_new_boolean(false); + if (!d) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + json_object_set_serializer(d, null_obj_to_string, NULL, NULL); return d; @@ -177,19 +181,8 @@ obj_free(struct json_object *v, void *ud) struct json_object * ut_new_object(struct json_object *proto) { - struct json_object *val = json_object_new_object(); - struct ut_op *op; - - if (!val) - return NULL; - - op = calloc(1, sizeof(*op)); - - if (!op) { - json_object_put(val); - - return NULL; - } + struct json_object *val = xjs_new_object(); + struct ut_op *op = xalloc(sizeof(*op)); op->val = val; op->type = T_LBRACE; @@ -220,20 +213,13 @@ re_to_string(struct json_object *v, struct printbuf *pb, int level, int flags) sprintbuf(pb, "%s/", strict ? "\"" : ""); - s = json_object_new_string((char *)op + sizeof(*op) + sizeof(regex_t)); + s = xjs_new_string((char *)op + sizeof(*op) + sizeof(regex_t)); - if (s) { - if (strict) { - for (p = json_object_to_json_string(s) + 1, len = strlen(p) - 1; len > 0; len--, p++) - sprintbuf(pb, "%c", *p); - } - else { - sprintbuf(pb, "%s", json_object_get_string(s)); - } - } - else { - sprintbuf(pb, "..."); - } + if (strict) + for (p = json_object_to_json_string(s) + 1, len = strlen(p) - 1; len > 0; len--, p++) + sprintbuf(pb, "%c", *p); + else + sprintbuf(pb, "%s", json_object_get_string(s)); json_object_put(s); @@ -251,11 +237,7 @@ ut_new_regexp(const char *source, bool icase, bool newline, bool global, char ** regex_t *re; size_t len; - op = calloc(1, sizeof(*op) + sizeof(*re) + strlen(source) + 1); - - if (!op) - return NULL; - + op = xalloc(sizeof(*op) + sizeof(*re) + strlen(source) + 1); re = (regex_t *)((char *)op + sizeof(*op)); strcpy((char *)op + sizeof(*op) + sizeof(*re), source); @@ -275,18 +257,15 @@ ut_new_regexp(const char *source, bool icase, bool newline, bool global, char ** if (res != 0) { len = regerror(res, re, NULL, 0); - *err = calloc(1, len); - - if (*err) - regerror(res, re, *err, len); + *err = xalloc(len); + regerror(res, re, *err, len); free(op); return NULL; } - //op->val = json_object_new_string(source); - op->val = json_object_new_object(); + op->val = xjs_new_object(); if (!op->val) { free(op); @@ -332,19 +311,8 @@ func_to_string(struct json_object *v, struct printbuf *pb, int level, int flags) struct json_object * ut_new_func(struct ut_op *decl) { - struct json_object *val = json_object_new_object(); - struct ut_op *op; - - if (!val) - return NULL; - - op = calloc(1, sizeof(*op)); - - if (!op) { - json_object_put(val); - - return NULL; - } + struct json_object *val = xjs_new_object(); + struct ut_op *op = xalloc(sizeof(*op)); op->val = val; op->type = T_FUNC; @@ -451,14 +419,7 @@ out: bool ut_register_extended_type(const char *name, struct json_object *proto, void (*freefn)(void *)) { - struct ut_extended_type *tmp; - - tmp = realloc(ut_ext_types, (ut_ext_types_count + 1) * sizeof(*tmp)); - - if (!tmp) - return false; - - ut_ext_types = tmp; + ut_ext_types = xrealloc(ut_ext_types, (ut_ext_types_count + 1) * sizeof(*ut_ext_types)); ut_ext_types[ut_ext_types_count].name = name; ut_ext_types[ut_ext_types_count].free = freefn; ut_ext_types[ut_ext_types_count].proto = proto; @@ -520,11 +481,7 @@ ut_set_extended_type(struct json_object *v, const char *name, void *data) if (!et) return NULL; - op = calloc(1, sizeof(*op)); - - if (!op) - return NULL; - + op = xalloc(sizeof(*op)); op->val = v; op->type = T_RESSOURCE; op->tag.proto = json_object_get(et->proto); @@ -19,7 +19,10 @@ #include <stddef.h> #include <stdint.h> +#include <stdlib.h> +#include <stdio.h> #include <stdbool.h> +#include <stdarg.h> #ifdef JSONC #include <json.h> @@ -29,8 +32,6 @@ #define JSON_C_TO_STRING_STRICT (1<<31) -#define UT_ERRMSG_OOM "Runtime error: Memory allocation failure" - enum ut_error_type { UT_ERROR_NO_ERROR, UT_ERROR_OUT_OF_MEMORY, @@ -159,4 +160,131 @@ static inline uint32_t getrefcnt(struct json_object *v) { return spy ? spy->_ref_count : 0; } +static inline void *xalloc(size_t size) { + void *ptr = calloc(1, size); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline void *xrealloc(void *ptr, size_t size) { + ptr = realloc(ptr, size); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_object(void) { + struct json_object *ptr = json_object_new_object(); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_array(void) { + struct json_object *ptr = json_object_new_array(); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_int64(int64_t n) { + struct json_object *ptr = json_object_new_int64(n); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_string(const char *s) { + struct json_object *ptr = json_object_new_string(s); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_string_len(const char *s, size_t len) { + struct json_object *ptr = json_object_new_string_len(s, len); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_object *xjs_new_boolean(bool v) { + struct json_object *ptr = json_object_new_boolean(v); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + + +static inline struct json_tokener *xjs_new_tokener(void) { + struct json_tokener *tok = json_tokener_new(); + + if (!tok) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return tok; +} + +static inline int xasprintf(char **strp, const char *fmt, ...) { + va_list ap; + int len; + + va_start(ap, fmt); + len = vasprintf(strp, fmt, ap); + va_end(ap); + + if (len == -1) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return len; +} + +static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { + int len = vasprintf(strp, fmt, ap); + + if (len == -1) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return len; +} + #endif /* __AST_H_ */ @@ -38,16 +38,11 @@ ut_exception(struct ut_state *state, uint32_t off, const char *fmt, ...) int len; va_start(ap, fmt); - len = vasprintf(&s, fmt, ap); + len = xvasprintf(&s, fmt, ap); va_end(ap); - if (len < 0) { - msg = json_object_new_string(UT_ERRMSG_OOM); - } - else { - msg = json_object_new_string_len(s, len); - free(s); - } + msg = xjs_new_string_len(s, len); + free(s); exception_tag->type = T_EXCEPTION; exception_tag->tree.operand[0] = off; @@ -179,26 +174,17 @@ ut_getscope(struct ut_state *state, uint8_t depth) static struct json_object * ut_addscope(struct ut_state *state, uint32_t decl) { - struct json_object *scope, **tmp; + struct json_object *scope; if (state->stack.off >= 255) return ut_exception(state, decl, "Runtime error: Too much recursion"); if (state->stack.off >= state->stack.size) { - tmp = realloc(state->stack.scope, (state->stack.size + 1) * sizeof(*state->stack.scope)); - - if (!tmp) - return ut_exception(state, decl, UT_ERRMSG_OOM); - - state->stack.scope = tmp; + state->stack.scope = xrealloc(state->stack.scope, (state->stack.size + 1) * sizeof(*state->stack.scope)); state->stack.size++; } scope = ut_new_object(NULL); - - if (!scope) - return ut_exception(state, decl, UT_ERRMSG_OOM); - state->stack.scope[state->stack.off++] = scope; return scope; @@ -618,7 +604,7 @@ ut_execute_for(struct ut_state *state, uint32_t off) } else if (json_object_is_type(val, json_type_object)) { json_object_object_foreach(val, key, item) { - ut_setval(scope, ivar->val, json_object_new_string(key)); + ut_setval(scope, ivar->val, xjs_new_string(key)); ut_putval(rv); rv = ut_execute_op_sequence(state, ut_get_off(state, body)); @@ -858,7 +844,7 @@ ut_execute_rel(struct ut_state *state, uint32_t off) ut_get_operands(state, op, v); - rv = json_object_new_boolean(ut_cmp(op->type, v[0], v[1])); + rv = xjs_new_boolean(ut_cmp(op->type, v[0], v[1])); ut_putval(v[0]); ut_putval(v[1]); @@ -917,7 +903,7 @@ ut_execute_equality(struct ut_state *state, uint32_t off) ut_get_operands(state, op, v); equal = ut_eq(v[0], v[1]); - rv = json_object_new_boolean((op->type == T_EQS) ? equal : !equal); + rv = xjs_new_boolean((op->type == T_EQS) ? equal : !equal); ut_putval(v[0]); ut_putval(v[1]); @@ -955,7 +941,7 @@ ut_execute_in(struct ut_state *state, uint32_t off) ut_putval(v[0]); ut_putval(v[1]); - return json_object_new_boolean(found); + return xjs_new_boolean(found); } static struct json_object * @@ -980,7 +966,7 @@ ut_execute_inc_dec(struct ut_state *state, uint32_t off) if (ut_cast_number(val, &n, &d) == json_type_double) nval = ut_new_double(d + (op->type == T_INC ? 1.0 : -1.0)); else - nval = json_object_new_int64(n + (op->type == T_INC ? 1 : -1)); + nval = xjs_new_int64(n + (op->type == T_INC ? 1 : -1)); ut_putval(ut_setval(scope, key, nval)); @@ -997,10 +983,7 @@ static struct json_object * ut_execute_list(struct ut_state *state, uint32_t off) { struct ut_op *op = ut_get_op(state, off); - struct json_object *val, *arr = json_object_new_array(); - - if (!arr) - return ut_exception(state, off, UT_ERRMSG_OOM); + struct json_object *val, *arr = xjs_new_array(); while (op) { val = ut_execute_op(state, ut_get_off(state, op)); @@ -1024,9 +1007,6 @@ ut_execute_object(struct ut_state *state, uint32_t off) struct json_object *v, *obj = ut_new_object(NULL); struct ut_op *key, *val; - if (!obj) - return ut_exception(state, off, UT_ERRMSG_OOM); - for (key = ut_get_child(state, off, 0), val = ut_get_op(state, key ? key->tree.next : 0); key != NULL && val != NULL; key = ut_get_op(state, val->tree.next), val = ut_get_op(state, key ? key->tree.next : 0)) { @@ -1139,12 +1119,9 @@ ut_execute_call(struct ut_state *state, uint32_t off) } else { if (v[1] == NULL) - v[1] = json_object_new_array(); + v[1] = xjs_new_array(); - if (v[1] == NULL) - rv = ut_exception(state, off, UT_ERRMSG_OOM); - else - rv = ut_invoke(state, off, NULL, v[0], v[1]); + rv = ut_invoke(state, off, NULL, v[0], v[1]); } ut_putval(v[0]); @@ -1225,9 +1202,9 @@ ut_execute_unary_plus_minus(struct ut_state *state, uint32_t off) switch (t) { case json_type_int: if (op1->is_overflow) - return json_object_new_int64(((n >= 0) == (op->type == T_SUB)) ? INT64_MIN : INT64_MAX); + return xjs_new_int64(((n >= 0) == (op->type == T_SUB)) ? INT64_MIN : INT64_MAX); - return json_object_new_int64((op->type == T_SUB) ? -n : n); + return xjs_new_int64((op->type == T_SUB) ? -n : n); default: return ut_new_double((op->type == T_SUB) ? -d : d); @@ -1258,18 +1235,11 @@ ut_execute_arith(struct ut_state *state, uint32_t off) s2 = v[1] ? json_object_get_string(v[1]) : "null"; len1 = strlen(s1); len2 = strlen(s2); - s = calloc(1, len1 + len2 + 1); - - if (!s) { - ut_putval(v[0]); - ut_putval(v[1]); - - return NULL; - } + s = xalloc(len1 + len2 + 1); snprintf(s, len1 + len2 + 1, "%s%s", s1, s2); - rv = json_object_new_string(s); + rv = xjs_new_string(s); ut_putval(v[0]); ut_putval(v[1]); @@ -1315,22 +1285,22 @@ ut_execute_arith(struct ut_state *state, uint32_t off) switch (op->type) { case T_ADD: - return json_object_new_int64(n1 + n2); + return xjs_new_int64(n1 + n2); case T_SUB: - return json_object_new_int64(n1 - n2); + return xjs_new_int64(n1 - n2); case T_MUL: - return json_object_new_int64(n1 * n2); + return xjs_new_int64(n1 * n2); case T_DIV: if (n2 == 0) return ut_new_double(INFINITY); - return json_object_new_int64(n1 / n2); + return xjs_new_int64(n1 / n2); case T_MOD: - return json_object_new_int64(n1 % n2); + return xjs_new_int64(n1 % n2); } return ut_new_double(NAN); @@ -1357,19 +1327,19 @@ ut_execute_bitop(struct ut_state *state, uint32_t off) switch (op->type) { case T_LSHIFT: - return json_object_new_int64(n1 << n2); + return xjs_new_int64(n1 << n2); case T_RSHIFT: - return json_object_new_int64(n1 >> n2); + return xjs_new_int64(n1 >> n2); case T_BAND: - return json_object_new_int64(n1 & n2); + return xjs_new_int64(n1 & n2); case T_BXOR: - return json_object_new_int64(n1 ^ n2); + return xjs_new_int64(n1 ^ n2); case T_BOR: - return json_object_new_int64(n1 | n2); + return xjs_new_int64(n1 | n2); default: return NULL; @@ -1381,7 +1351,7 @@ ut_execute_not(struct ut_state *state, uint32_t off) { struct ut_op *op = ut_get_op(state, off); - return json_object_new_boolean(!ut_test_condition(state, op ? op->tree.operand[0] : 0)); + return xjs_new_boolean(!ut_test_condition(state, op ? op->tree.operand[0] : 0)); } static struct json_object * @@ -1399,7 +1369,7 @@ ut_execute_compl(struct ut_state *state, uint32_t off) ut_putval(v[0]); - return json_object_new_int64(~n); + return xjs_new_int64(~n); } static struct json_object * @@ -1422,7 +1392,7 @@ static struct json_object * ut_execute_break_cont(struct ut_state *state, uint32_t off) { struct ut_op *op = ut_get_op(state, off); - struct json_object *rv = json_object_new_int64(0); + struct json_object *rv = xjs_new_int64(0); json_object_set_userdata(rv, op, NULL); @@ -1435,9 +1405,6 @@ ut_execute_function(struct ut_state *state, uint32_t off) struct ut_op *op = ut_get_op(state, off); struct json_object *obj = ut_new_func(op); - if (!obj) - return ut_exception(state, off, UT_ERRMSG_OOM); - return obj; } @@ -1458,7 +1425,7 @@ ut_execute_try_catch(struct ut_state *state, uint32_t off) if (ut_is_type(rv, T_EXCEPTION)) { if (op->tree.operand[1]) ut_putval(ut_setval(ut_getscope(state, 0), ut_get_child(state, off, 1)->val, - json_object_new_string(json_object_get_string(rv)))); + xjs_new_string(json_object_get_string(rv)))); memset(&state->error, 0, sizeof(state->error)); @@ -1739,15 +1706,12 @@ ut_execute_op_sequence(struct ut_state *state, uint32_t off) static void ut_globals_init(struct ut_state *state, struct json_object *scope) { - struct json_object *arr = json_object_new_array(); + struct json_object *arr = xjs_new_array(); const char *p, *last; - if (!arr) - return; - for (p = last = LIB_SEARCH_PATH;; p++) { if (*p == ':' || *p == '\0') { - json_object_array_add(arr, json_object_new_string_len(last, p - last)); + json_object_array_add(arr, xjs_new_string_len(last, p - last)); if (!*p) break; @@ -1809,7 +1773,7 @@ ut_run(struct ut_state *state, struct json_object *env, struct json_object *modu ut_globals_init(state, scope); ut_lib_init(state, scope); - args = json_object_new_array(); + args = xjs_new_array(); if (modules) { for (i = 0; i < json_object_array_length(modules); i++) { @@ -579,7 +579,7 @@ next: /* terminating quote */ if (*in == q) { - op->val = json_object_new_string_len(str, sizeof(str) - 1 - rem); + op->val = xjs_new_string_len(str, sizeof(str) - 1 - rem); return (in - buf) + 2; } @@ -715,7 +715,7 @@ parse_label(const char *buf, struct ut_op *op, struct ut_state *s) } } - op->val = json_object_new_string(str); + op->val = xjs_new_string(str); return (in - buf); } @@ -767,7 +767,7 @@ parse_number(const char *buf, struct ut_op *op, struct ut_state *s) op->type = T_NUMBER; - op->val = json_object_new_int64(n); + op->val = xjs_new_int64(n); op->is_overflow = (errno == ERANGE); return (e - buf); @@ -787,12 +787,12 @@ static int parse_bool(const char *buf, struct ut_op *op, struct ut_state *s) { if (!strncmp(buf, "false", 5)) { - op->val = json_object_new_boolean(false); + op->val = xjs_new_boolean(false); return 5; } else if (!strncmp(buf, "true", 4)) { - op->val = json_object_new_boolean(true); + op->val = xjs_new_boolean(true); return 4; } @@ -860,7 +860,7 @@ ut_get_token(struct ut_state *s, const char *input, int *mlen) if (p == o) return 0; - return ut_new_op(s, T_TEXT, json_object_new_string_len(o, p - o), UINT32_MAX); + return ut_new_op(s, T_TEXT, xjs_new_string_len(o, p - o), UINT32_MAX); } } else if (s->blocktype == UT_BLOCK_COMMENT) { @@ -1010,7 +1010,7 @@ ut_get_token(struct ut_state *s, const char *input, int *mlen) *mlen = p - input; s->off += *mlen; - return ut_new_op(s, T_TEXT, json_object_new_string_len(o, p - o), UINT32_MAX); + return ut_new_op(s, T_TEXT, xjs_new_string_len(o, p - o), UINT32_MAX); } return 0; @@ -36,7 +36,7 @@ #include <sys/types.h> -static bool +static void snprintf_append(char **dptr, size_t *dlen, const char *fmt, ssize_t sz, ...) { va_list ap; @@ -47,15 +47,10 @@ snprintf_append(char **dptr, size_t *dlen, const char *fmt, ssize_t sz, ...) n = vsnprintf(NULL, 0, fmt, ap); va_end(ap); - if (n < 0) - return false; - else if (sz >= 0 && n > sz) + if (sz >= 0 && n > sz) n = sz; - tmp = realloc(*dptr, *dlen + n + 1); - - if (!tmp) - return false; + tmp = xrealloc(*dptr, *dlen + n + 1); va_start(ap, sz); vsnprintf(tmp + *dlen, n + 1, fmt, ap); @@ -63,8 +58,6 @@ snprintf_append(char **dptr, size_t *dlen, const char *fmt, ssize_t sz, ...) *dptr = tmp; *dlen += n; - - return true; } #define sprintf_append(dptr, dlen, fmt, ...) \ @@ -293,19 +286,8 @@ ut_c_fn_free(struct json_object *v, void *ud) static bool ut_register_function(struct json_object *scope, const char *name, ut_c_fn *fn) { - struct json_object *val = json_object_new_object(); - struct ut_op *op; - - if (!val) - return NULL; - - op = calloc(1, sizeof(*op)); - - if (!op) { - json_object_put(val); - - return NULL; - } + struct json_object *val = xjs_new_object(); + struct ut_op *op = xalloc(sizeof(*op)); op->val = val; op->type = T_CFUNC; @@ -342,7 +324,7 @@ ut_print(struct ut_state *s, uint32_t off, struct json_object *args) reslen += fwrite(p, 1, len, stdout); } - return json_object_new_int64(reslen); + return xjs_new_int64(reslen); } static struct json_object * @@ -352,10 +334,10 @@ ut_length(struct ut_state *s, uint32_t off, struct json_object *args) switch (json_object_get_type(arg)) { case json_type_array: - return json_object_new_int64(json_object_array_length(arg)); + return xjs_new_int64(json_object_array_length(arg)); case json_type_string: - return json_object_new_int64(json_object_get_string_len(arg)); + return xjs_new_int64(json_object_get_string_len(arg)); default: return NULL; @@ -381,7 +363,7 @@ ut_index(struct ut_state *s, uint32_t off, struct json_object *args, bool right) } } - return json_object_new_int64(ret); + return xjs_new_int64(ret); case json_type_string: sstr = json_object_get_string(stack); @@ -397,7 +379,7 @@ ut_index(struct ut_state *s, uint32_t off, struct json_object *args, bool right) } } - return json_object_new_int64(ret); + return xjs_new_int64(ret); default: return NULL; @@ -517,12 +499,9 @@ ut_chr(struct ut_state *s, uint32_t off, struct json_object *args) char *str; if (!len) - return json_object_new_string_len("", 0); - - str = calloc(1, len); + return xjs_new_string_len("", 0); - if (!str) - return ut_exception(s, off, UT_ERRMSG_OOM); + str = xalloc(len); for (idx = 0; idx < len; idx++) { n = ut_cast_int64(json_object_array_get_idx(args, idx)); @@ -535,7 +514,7 @@ ut_chr(struct ut_state *s, uint32_t off, struct json_object *args) str[idx] = (char)n; } - return json_object_new_string_len(str, len); + return xjs_new_string_len(str, len); } static struct json_object * @@ -578,7 +557,7 @@ ut_exists(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(obj, json_type_object)) return false; - return json_object_new_boolean(json_object_object_get_ex(obj, key ? key : "null", NULL)); + return xjs_new_boolean(json_object_object_get_ex(obj, key ? key : "null", NULL)); } __attribute__((noreturn)) static struct json_object * @@ -595,7 +574,7 @@ ut_getenv(struct ut_state *s, uint32_t off, struct json_object *args) const char *key = json_object_get_string(json_object_array_get_idx(args, 0)); char *val = key ? getenv(key) : NULL; - return val ? json_object_new_string(val) : NULL; + return val ? xjs_new_string(val) : NULL; } static struct json_object * @@ -609,21 +588,14 @@ ut_filter(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(obj, json_type_array)) return NULL; - arr = json_object_new_array(); - cmpargs = json_object_new_array(); - - if (!arr || !cmpargs) { - ut_putval(arr); - ut_putval(cmpargs); - - return ut_exception(s, off, UT_ERRMSG_OOM); - } + arr = xjs_new_array(); + cmpargs = xjs_new_array(); json_object_array_put_idx(cmpargs, 2, json_object_get(obj)); for (arrlen = json_object_array_length(obj), arridx = 0; arridx < arrlen; arridx++) { json_object_array_put_idx(cmpargs, 0, json_object_get(json_object_array_get_idx(obj, arridx))); - json_object_array_put_idx(cmpargs, 1, json_object_new_int64(arridx)); + json_object_array_put_idx(cmpargs, 1, xjs_new_int64(arridx)); rv = ut_invoke(s, off, NULL, func, cmpargs); @@ -653,7 +625,7 @@ ut_hex(struct ut_state *s, uint32_t off, struct json_object *args) if (e == val || *e) return ut_new_double(NAN); - return json_object_new_int64(n); + return xjs_new_int64(n); } static struct json_object * @@ -664,7 +636,7 @@ ut_int(struct ut_state *s, uint32_t off, struct json_object *args) if (errno == EINVAL || errno == EOVERFLOW) return ut_new_double(NAN); - return json_object_new_int64(n); + return xjs_new_int64(n); } static struct json_object * @@ -689,10 +661,7 @@ ut_join(struct ut_state *s, uint32_t off, struct json_object *args) len += item ? strlen(item) : 0; } - p = res = calloc(1, len); - - if (!res) - return ut_exception(s, off, UT_ERRMSG_OOM); + p = res = xalloc(len); for (arrlen = json_object_array_length(arr), arridx = 0; arridx < arrlen; arridx++) { if (arridx > 0) { @@ -718,7 +687,7 @@ ut_join(struct ut_state *s, uint32_t off, struct json_object *args) } } - rv = json_object_new_string(res); + rv = xjs_new_string(res); out: free(res); @@ -735,13 +704,10 @@ ut_keys(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(obj, json_type_object)) return NULL; - arr = json_object_new_array(); - - if (!arr) - return ut_exception(s, off, UT_ERRMSG_OOM); + arr = xjs_new_array(); json_object_object_foreach(obj, key, val) - json_object_array_add(arr, json_object_new_string(key)); + json_object_array_add(arr, xjs_new_string(key)); return arr; } @@ -757,10 +723,7 @@ ut_lc(struct ut_state *s, uint32_t off, struct json_object *args) if (!str) return NULL; - res = p = calloc(1, len); - - if (!res) - return ut_exception(s, off, UT_ERRMSG_OOM); + res = p = xalloc(len); while (*str) if (*str >= 'A' && *str <= 'Z') @@ -768,7 +731,7 @@ ut_lc(struct ut_state *s, uint32_t off, struct json_object *args) else *p++ = *str++; - rv = json_object_new_string_len(res, len); + rv = xjs_new_string_len(res, len); free(res); return rv; @@ -785,21 +748,14 @@ ut_map(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(obj, json_type_array)) return NULL; - arr = json_object_new_array(); - cmpargs = json_object_new_array(); - - if (!arr || !cmpargs) { - ut_putval(arr); - ut_putval(cmpargs); - - return ut_exception(s, off, UT_ERRMSG_OOM); - } + arr = xjs_new_array(); + cmpargs = xjs_new_array(); json_object_array_put_idx(cmpargs, 2, json_object_get(obj)); for (arrlen = json_object_array_length(obj), arridx = 0; arridx < arrlen; arridx++) { json_object_array_put_idx(cmpargs, 0, json_object_get(json_object_array_get_idx(obj, arridx))); - json_object_array_put_idx(cmpargs, 1, json_object_new_int64(arridx)); + json_object_array_put_idx(cmpargs, 1, xjs_new_int64(arridx)); json_object_array_add(arr, ut_invoke(s, off, NULL, func, cmpargs)); } @@ -823,7 +779,7 @@ ut_ord(struct ut_state *s, uint32_t off, struct json_object *args) if (!str[0]) return NULL; - return json_object_new_int64((int64_t)str[0]); + return xjs_new_int64((int64_t)str[0]); } static struct json_object * @@ -834,30 +790,30 @@ ut_type(struct ut_state *s, uint32_t off, struct json_object *args) switch (tag ? tag->type : 0) { case T_FUNC: - return json_object_new_string("function"); + return xjs_new_string("function"); case T_RESSOURCE: - return json_object_new_string("ressource"); + return xjs_new_string("ressource"); default: switch (json_object_get_type(v)) { case json_type_object: - return json_object_new_string("object"); + return xjs_new_string("object"); case json_type_array: - return json_object_new_string("array"); + return xjs_new_string("array"); case json_type_double: - return json_object_new_string("double"); + return xjs_new_string("double"); case json_type_int: - return json_object_new_string("int"); + return xjs_new_string("int"); case json_type_boolean: - return json_object_new_string("bool"); + return xjs_new_string("bool"); case json_type_string: - return json_object_new_string("string"); + return xjs_new_string("string"); default: return NULL; @@ -875,10 +831,7 @@ ut_reverse(struct ut_state *s, uint32_t off, struct json_object *args) char *dup, *p; if (json_object_is_type(obj, json_type_array)) { - rv = json_object_new_array(); - - if (!rv) - return ut_exception(s, off, UT_ERRMSG_OOM); + rv = xjs_new_array(); for (arridx = json_object_array_length(obj); arridx > 0; arridx--) json_object_array_add(rv, json_object_get(json_object_array_get_idx(obj, arridx - 1))); @@ -886,15 +839,12 @@ ut_reverse(struct ut_state *s, uint32_t off, struct json_object *args) else if (json_object_is_type(obj, json_type_string)) { len = json_object_get_string_len(obj); str = json_object_get_string(obj); - p = dup = calloc(1, len + 1); - - if (!dup) - return ut_exception(s, off, UT_ERRMSG_OOM); + p = dup = xalloc(len + 1); while (len > 0) *p++ = str[--len]; - rv = json_object_new_string(dup); + rv = xjs_new_string(dup); free(dup); } @@ -945,10 +895,7 @@ ut_sort(struct ut_state *s, uint32_t off, struct json_object *args) sort_ctx.s = s; sort_ctx.off = off; sort_ctx.fn = fn; - sort_ctx.args = json_object_new_array(); - - if (!sort_ctx.args) - return ut_exception(s, off, UT_ERRMSG_OOM); + sort_ctx.args = xjs_new_array(); } json_object_array_sort(arr, sort_fn); @@ -1045,12 +992,9 @@ ut_split(struct ut_state *s, uint32_t off, struct json_object *args) if (!sep || !json_object_is_type(str, json_type_string)) return NULL; - arr = json_object_new_array(); + arr = xjs_new_array(); splitstr = json_object_get_string(str); - if (!arr) - return ut_exception(s, off, UT_ERRMSG_OOM); - if (ut_is_type(sep, T_REGEXP)) { tag = json_object_get_userdata(sep); @@ -1060,13 +1004,13 @@ ut_split(struct ut_state *s, uint32_t off, struct json_object *args) if (res == REG_NOMATCH) break; - json_object_array_add(arr, json_object_new_string_len(splitstr, pmatch.rm_so)); + json_object_array_add(arr, xjs_new_string_len(splitstr, pmatch.rm_so)); splitstr += pmatch.rm_eo; eflags |= REG_NOTBOL; } - json_object_array_add(arr, json_object_new_string(splitstr)); + json_object_array_add(arr, xjs_new_string(splitstr)); } else if (json_object_is_type(sep, json_type_string)) { sepstr = json_object_get_string(sep); @@ -1074,7 +1018,7 @@ ut_split(struct ut_state *s, uint32_t off, struct json_object *args) for (p = splitstr + (*sepstr ? 1 : 0), seplen = strlen(sepstr); *p; p++) { if (!strncmp(p, sepstr, seplen)) { if (*sepstr || p > splitstr) - json_object_array_add(arr, json_object_new_string_len(splitstr, p - splitstr)); + json_object_array_add(arr, xjs_new_string_len(splitstr, p - splitstr)); splitstr = p + seplen; p = splitstr - (*sepstr ? 1 : 0); @@ -1082,7 +1026,7 @@ ut_split(struct ut_state *s, uint32_t off, struct json_object *args) } if (*splitstr) - json_object_array_add(arr, json_object_new_string_len(splitstr, p - splitstr)); + json_object_array_add(arr, xjs_new_string_len(splitstr, p - splitstr)); } else { json_object_put(arr); @@ -1154,7 +1098,7 @@ ut_substr(struct ut_state *s, uint32_t off, struct json_object *args) break; } - return json_object_new_string_len(p + ofs, sublen); + return xjs_new_string_len(p + ofs, sublen); } static struct json_object * @@ -1162,7 +1106,7 @@ ut_time(struct ut_state *s, uint32_t off, struct json_object *args) { time_t t = time(NULL); - return json_object_new_int64((int64_t)t); + return xjs_new_int64((int64_t)t); } static struct json_object * @@ -1176,10 +1120,7 @@ ut_uc(struct ut_state *s, uint32_t off, struct json_object *args) if (!str) return NULL; - res = p = calloc(1, len); - - if (!res) - return ut_exception(s, off, UT_ERRMSG_OOM); + res = p = xalloc(len); while (*str) if (*str >= 'a' && *str <= 'z') @@ -1187,7 +1128,7 @@ ut_uc(struct ut_state *s, uint32_t off, struct json_object *args) else *p++ = *str++; - rv = json_object_new_string_len(res, len); + rv = xjs_new_string_len(res, len); free(res); return rv; @@ -1217,10 +1158,7 @@ ut_uchr(struct ut_state *s, uint32_t off, struct json_object *args) ulen += 4; } - str = calloc(1, ulen); - - if (!str) - return ut_exception(s, off, UT_ERRMSG_OOM); + str = xalloc(ulen); for (idx = 0, p = str, rem = ulen; idx < len; idx++) { n = ut_cast_int64(json_object_array_get_idx(args, idx)); @@ -1232,7 +1170,7 @@ ut_uchr(struct ut_state *s, uint32_t off, struct json_object *args) break; } - return json_object_new_string_len(str, ulen); + return xjs_new_string_len(str, ulen); } static struct json_object * @@ -1244,10 +1182,7 @@ ut_values(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(obj, json_type_object)) return NULL; - arr = json_object_new_array(); - - if (!arr) - return ut_exception(s, off, UT_ERRMSG_OOM); + arr = xjs_new_array(); json_object_object_foreach(obj, key, val) { (void)key; @@ -1294,7 +1229,7 @@ ut_trim_common(struct ut_state *s, uint32_t off, struct json_object *args, bool } } - return json_object_new_string_len(p, len); + return xjs_new_string_len(p, len); } static struct json_object * @@ -1324,7 +1259,6 @@ ut_printf_common(struct ut_state *s, uint32_t off, struct json_object *args, cha size_t len = 0, arglen, argidx; const char *fstr, *last, *p; enum json_type t; - bool ok; *res = NULL; @@ -1338,8 +1272,7 @@ ut_printf_common(struct ut_state *s, uint32_t off, struct json_object *args, cha for (last = p = fstr; *p; p++) { if (*p == '%') { - if (!snprintf_append(res, &len, "%s", p - last, last)) - goto err; + snprintf_append(res, &len, "%s", p - last, last); last = p++; @@ -1487,15 +1420,12 @@ ut_printf_common(struct ut_state *s, uint32_t off, struct json_object *args, cha *fp = 0; switch (t) { - case json_type_int: ok = sprintf_append(res, &len, sfmt, arg.n); break; - case json_type_double: ok = sprintf_append(res, &len, sfmt, arg.d); break; - case json_type_string: ok = sprintf_append(res, &len, sfmt, arg.s); break; - default: ok = sprintf_append(res, &len, sfmt); break; + case json_type_int: sprintf_append(res, &len, sfmt, arg.n); break; + case json_type_double: sprintf_append(res, &len, sfmt, arg.d); break; + case json_type_string: sprintf_append(res, &len, sfmt, arg.s); break; + default: sprintf_append(res, &len, sfmt); break; } - if (!ok) - goto err; - last = p + 1; next: @@ -1503,16 +1433,9 @@ next: } } - if (!snprintf_append(res, &len, "%s", p - last, last)) - goto err; + snprintf_append(res, &len, "%s", p - last, last); return len; - -err: - free(*res); - *res = NULL; - - return 0; } static struct json_object * @@ -1523,10 +1446,7 @@ ut_sprintf(struct ut_state *s, uint32_t off, struct json_object *args) len = ut_printf_common(s, off, args, &str); - if (!str) - return ut_exception(s, off, UT_ERRMSG_OOM); - - return json_object_new_string_len(str, len); + return xjs_new_string_len(str, len); } static struct json_object * @@ -1536,13 +1456,9 @@ ut_printf(struct ut_state *s, uint32_t off, struct json_object *args) size_t len; len = ut_printf_common(s, off, args, &str); - - if (!str) - return ut_exception(s, off, UT_ERRMSG_OOM); - len = fwrite(str, 1, len, stdout); - return json_object_new_int64(len); + return xjs_new_int64(len); } static struct json_object * @@ -1567,10 +1483,7 @@ ut_require_so(struct ut_state *s, uint32_t off, const char *path) if (!init) return ut_exception(s, off, "Module %s provides no 'ut_module_init' function", path); - scope = json_object_new_object(); - - if (!scope) - return ut_exception(s, off, UT_ERRMSG_OOM); + scope = xjs_new_object(); init(&ut, s, scope); @@ -1593,13 +1506,7 @@ ut_require_utpl(struct ut_state *s, uint32_t off, const char *path, struct json_ if (!sfile) return ut_exception(s, off, "Unable to open file %s: %s", path, strerror(errno)); - source = calloc(1, st.st_size + 1); - - if (!source) { - fclose(sfile); - - return ut_exception(s, off, UT_ERRMSG_OOM); - } + source = xalloc(st.st_size + 1); fread(source, 1, st.st_size, sfile); fclose(sfile); @@ -1616,20 +1523,10 @@ ut_require_utpl(struct ut_state *s, uint32_t off, const char *path, struct json_ free(source); - sc = scope ? scope : json_object_new_object(); - - if (!sc) - return ut_exception(s, off, UT_ERRMSG_OOM); + sc = scope ? scope : xjs_new_object(); entry = ut_new_func(ut_get_op(s, s->main)); - if (!entry) { - if (sc != scope) - json_object_put(sc); - - return ut_exception(s, off, UT_ERRMSG_OOM); - } - rv = ut_invoke(s, off, sc, entry, NULL); json_object_put(entry); @@ -1734,26 +1631,20 @@ ut_iptoarr(struct ut_state *s, uint32_t off, struct json_object *args) return NULL; if (inet_pton(AF_INET6, json_object_get_string(ip), &a)) { - res = json_object_new_array(); - - if (!res) - return NULL; + res = xjs_new_array(); for (i = 0; i < 16; i++) - json_object_array_add(res, json_object_new_int64(a.in6.s6_addr[i])); + json_object_array_add(res, xjs_new_int64(a.in6.s6_addr[i])); return res; } else if (inet_pton(AF_INET, json_object_get_string(ip), &a)) { - res = json_object_new_array(); - - if (!res) - return NULL; + res = xjs_new_array(); - json_object_array_add(res, json_object_new_int64(a.u8[0])); - json_object_array_add(res, json_object_new_int64(a.u8[1])); - json_object_array_add(res, json_object_new_int64(a.u8[2])); - json_object_array_add(res, json_object_new_int64(a.u8[3])); + json_object_array_add(res, xjs_new_int64(a.u8[0])); + json_object_array_add(res, xjs_new_int64(a.u8[1])); + json_object_array_add(res, xjs_new_int64(a.u8[2])); + json_object_array_add(res, xjs_new_int64(a.u8[3])); return res; } @@ -1804,7 +1695,7 @@ ut_arrtoip(struct ut_state *s, uint32_t off, struct json_object *args) inet_ntop(AF_INET, &a, buf, sizeof(buf)); - return json_object_new_string(buf); + return xjs_new_string(buf); case 16: for (i = 0; i < 16; i++) { @@ -1818,7 +1709,7 @@ ut_arrtoip(struct ut_state *s, uint32_t off, struct json_object *args) inet_ntop(AF_INET6, &a, buf, sizeof(buf)); - return json_object_new_string(buf); + return xjs_new_string(buf); default: return NULL; @@ -1847,17 +1738,17 @@ ut_match(struct ut_state *s, uint32_t off, struct json_object *args) if (res == REG_NOMATCH) break; - m = json_object_new_array(); + m = xjs_new_array(); for (i = 0; i < ARRAY_SIZE(pmatch) && pmatch[i].rm_so != -1; i++) { json_object_array_add(m, - json_object_new_string_len(p + pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so)); + xjs_new_string_len(p + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so)); } if (tag->is_reg_global) { if (!rv) - rv = json_object_new_array(); + rv = xjs_new_array(); json_object_array_add(rv, m); @@ -1878,17 +1769,14 @@ ut_replace_cb(struct ut_state *s, uint32_t off, struct json_object *func, const char *subject, regmatch_t *pmatch, size_t plen, char **sp, size_t *sl) { - struct json_object *cbargs = json_object_new_array(); + struct json_object *cbargs = xjs_new_array(); struct json_object *rv; size_t i; - if (!cbargs) - return NULL; - for (i = 0; i < plen && pmatch[i].rm_so != -1; i++) { json_object_array_add(cbargs, - json_object_new_string_len(subject + pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so)); + xjs_new_string_len(subject + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so)); } rv = ut_invoke(s, off, NULL, func, cbargs); @@ -2053,7 +1941,7 @@ ut_replace(struct ut_state *s, uint32_t off, struct json_object *args) sprintf_append(&sp, &sl, "%s", l); } - rv = json_object_new_string_len(sp, sl); + rv = xjs_new_string_len(sp, sl); free(sp); return rv; @@ -2071,11 +1959,7 @@ ut_json(struct ut_state *s, uint32_t off, struct json_object *args) if (!json_object_is_type(src, json_type_string)) return ut_exception(s, off, "Passed value is not a string"); - tok = json_tokener_new(); - - if (!tok) - return ut_exception(s, off, UT_ERRMSG_OOM); - + tok = xjs_new_tokener(); str = json_object_get_string(src); len = json_object_get_string_len(src); @@ -190,7 +190,7 @@ static bool stdin_used = false; static char * read_file(const char *path) { - char buf[64], *s = NULL, *tmp; + char buf[64], *s = NULL; size_t rlen, tlen = 0; FILE *fp = NULL; @@ -218,16 +218,7 @@ read_file(const char *path) { if (rlen == 0) break; - tmp = realloc(s, tlen + rlen + 1); - - if (!tmp) { - fprintf(stderr, "Out or memory\n"); - free(s); - s = NULL; - goto out; - } - - s = tmp; + s = xrealloc(s, tlen + rlen + 1); memcpy(s + tlen, buf, rlen); s[tlen + rlen] = 0; tlen += rlen; @@ -255,13 +246,7 @@ main(int argc, char **argv) goto out; } - state = calloc(1, sizeof(*state)); - - if (!state) { - rv = UT_ERROR_OUT_OF_MEMORY; - goto out; - } - + state = xalloc(sizeof(*state)); state->lstrip_blocks = 1; state->trim_blocks = 1; @@ -331,7 +316,7 @@ main(int argc, char **argv) goto out; } - env = env ? env : json_object_new_object(); + env = env ? env : xjs_new_object(); json_object_object_foreach(o, key, val) json_object_object_add(env, key, json_object_get(val)); @@ -341,9 +326,9 @@ main(int argc, char **argv) break; case 'm': - modules = modules ? modules : json_object_new_array(); + modules = modules ? modules : xjs_new_array(); - json_object_array_add(modules, json_object_new_string(optarg)); + json_object_array_add(modules, xjs_new_string(optarg)); break; } @@ -95,7 +95,7 @@ ut_no_empty_obj(struct ut_state *s, uint32_t off) input ::= chunks(A). { s->main = new_op(T_FUNC, NULL, 0, 0, A); } -input ::= . { s->main = new_op(T_TEXT, json_object_new_string("")); s->main = new_op(T_FUNC, NULL, 0, 0, s->main); } +input ::= . { s->main = new_op(T_TEXT, xjs_new_string("")); s->main = new_op(T_FUNC, NULL, 0, 0, s->main); } chunks(A) ::= chunks(B) T_TEXT(C). { A = B ? append_op(B, C) : C; } chunks(A) ::= chunks(B) tplexp(C). { A = B ? append_op(B, C) : C; } |