bool sj_conf_parse(const struct mg_str json, const char *acl, const struct sj_conf_entry *schema, void *cfg) { struct parse_ctx ctx = { .schema = schema, .acl = acl, .cfg = cfg, .result = true}; return (json_walk(json.p, json.len, sj_conf_parse_cb, &ctx) >= 0 && ctx.result == true); } struct emit_ctx { const void *cfg; const void *base; bool pretty; struct mbuf *out; sj_conf_emit_cb_t cb; void *cb_param; }; static void sj_emit_indent(struct mbuf *m, int n) { mbuf_append(m, "\n", 1); for (int j = 0; j < n; j++) mbuf_append(m, " ", 1); }
/* * Alternative implementation of JSON.parse(), needed when v7 parser is * disabled */ enum v7_err v7_alt_json_parse(struct v7 *v7, v7_val_t json_string, v7_val_t *res) { struct json_parse_ctx *ctx = (struct json_parse_ctx *) calloc(sizeof(struct json_parse_ctx), 1); size_t len; const char *str = v7_get_string(v7, &json_string, &len); int json_res; enum v7_err rcode = V7_OK; ctx->v7 = v7; ctx->result = V7_UNDEFINED; ctx->frame = NULL; v7_own(v7, &ctx->result); json_res = json_walk(str, len, frozen_cb, ctx); if (json_res >= 0) { /* Expression is parsed successfully */ *res = ctx->result; /* There should be no allocated frames */ assert(ctx->frame == NULL); } else { /* There was an error during parsing */ rcode = v7_throwf(v7, "SyntaxError", "Invalid JSON string"); /* There might be some allocated frames in case of malformed JSON */ while (ctx->frame != NULL) { ctx->frame = free_json_frame(ctx, ctx->frame); } } v7_disown(v7, &ctx->result); free(ctx); return rcode; }
static int tcmp(const struct json_token *tok, const char *str) { struct mg_str s = {.p = tok->ptr, .len = tok->len}; return mg_vcmp(&s, str); } enum mgos_upd_file_action mgos_upd_file_begin( struct mgos_upd_hal_ctx *ctx, const struct mgos_upd_file_info *fi) { struct mg_str part_name = MG_MK_STR(""); enum mgos_upd_file_action ret = MGOS_UPDATER_SKIP_FILE; struct find_part_info find_part_info = {fi->name, &part_name, &ctx->cur_part}; ctx->cur_part.len = part_name.len = 0; json_walk(ctx->parts->ptr, ctx->parts->len, find_part, &find_part_info); if (ctx->cur_part.len == 0) return ret; /* Drop any indexes from part name, we'll add our own. */ while (1) { char c = part_name.p[part_name.len - 1]; if (c != '.' && !(c >= '0' && c <= '9')) break; part_name.len--; } struct json_token type = JSON_INVALID_TOKEN; const char *fname = NULL; uint32_t falloc = 0; json_scanf(ctx->cur_part.ptr, ctx->cur_part.len, "{load_addr:%u, falloc:%u, type: %T}", &ctx->app_load_addr, &falloc, &type); if (falloc == 0) falloc = fi->size; if (tcmp(&type, "app") == 0) { struct boot_cfg cur_cfg; int r = read_boot_cfg(ctx->cur_boot_cfg_idx, &cur_cfg); if (r < 0) { ctx->status_msg = "Could not read current boot cfg"; return MGOS_UPDATER_ABORT; } #if CC3200_SAFE_CODE_UPDATE /* * When safe code update is enabled, we write code to a new file. * Otherwise we write to the same slot we're using currently, which is * unsafe, makes reverting code update not possible, but saves space. */ create_fname( mg_mk_str_n(cur_cfg.app_image_file, strlen(cur_cfg.app_image_file) - 2), ctx->new_boot_cfg_idx, ctx->app_image_file, sizeof(ctx->app_image_file)); #else { strncpy(ctx->app_image_file, cur_cfg.app_image_file, sizeof(ctx->app_image_file)); } #endif if (ctx->app_load_addr >= 0x20000000) { fname = ctx->app_image_file; } else { ctx->status_msg = "Bad/missing app load_addr"; ret = MGOS_UPDATER_ABORT; } } else if (tcmp(&type, "fs") == 0) { json_scanf( ctx->cur_part.ptr, ctx->cur_part.len, "{fs_size: %u, fs_block_size: %u, fs_page_size: %u, fs_erase_size: %u}", &ctx->fs_size, &ctx->fs_block_size, &ctx->fs_page_size, &ctx->fs_erase_size); if (ctx->fs_size > 0 && ctx->fs_block_size > 0 && ctx->fs_page_size > 0 && ctx->fs_erase_size > 0) { char fs_container_prefix[MAX_FS_CONTAINER_PREFIX_LEN]; create_fname(part_name, ctx->new_boot_cfg_idx, fs_container_prefix, sizeof(fs_container_prefix)); /* Delete container 1 (if any) so that 0 is the only one. */ cc32xx_vfs_dev_slfs_container_delete_container(fs_container_prefix, 1); cc32xx_vfs_dev_slfs_container_fname(fs_container_prefix, 0, (_u8 *) ctx->fs_container_file); fname = ctx->fs_container_file; if (fi->size > ctx->fs_size) { /* Assume meta has already been added. */ falloc = fi->size; } else { falloc = FS_CONTAINER_SIZE(fi->size); } } else { ctx->status_msg = "Missing FS parameters"; ret = MGOS_UPDATER_ABORT; } } if (fname != NULL) { int r = prepare_to_write(ctx, fi, fname, falloc, &ctx->cur_part); if (r < 0) { LOG(LL_ERROR, ("err = %d", r)); ret = MGOS_UPDATER_ABORT; } else { ret = (r > 0 ? MGOS_UPDATER_PROCESS_FILE : MGOS_UPDATER_SKIP_FILE); } } if (ret == MGOS_UPDATER_SKIP_FILE) { DBG(("Skipping %s %.*s", fi->name, (int) part_name.len, part_name.p)); } return ret; } int mgos_upd_file_data(struct mgos_upd_hal_ctx *ctx, const struct mgos_upd_file_info *fi, struct mg_str data) { _i32 r = sl_FsWrite(ctx->cur_fh, fi->processed, (_u8 *) data.p, data.len); if (r != data.len) { ctx->status_msg = "Write failed"; r = -1; } return r; }
static const char *test_errors(void) { /* clang-format off */ static const char *invalid_tests[] = { "p", "a:3", "\x01", "{:", " { 1", "{a:\"\n\"}", "{a:1x}", "{a:1e}", "{a:.1}", "{a:0.}", "{a:0.e}", "{a:0.e1}", "{a:0.1e}", "{a:\"\\u\" } ", "{a:\"\\yx\"}", "{a:\"\\u111r\"}", NULL}; static const char *incomplete_tests[] = {"", " \r\n\t", "{", " { a", "{a:", "{a:\"", " { a : \"xx", "{a:12", "{a:\"\\uf", "{a:\"\\uff", "{a:\"\\ufff", "{a:\"\\uffff", "{a:\"\\uffff\"", "{a:\"\\uffff\" ,", "{a:n", "{a:nu", "{a:nul", "{a:null", NULL}; /* clang-format on */ static const struct { const char *str; int expected_len; } success_tests[] = {{"{}", 2}, /* 2, 3, 4 byte utf-8 chars */ {"{a:\"\xd0\xb1\xe3\x81\xaf\xf0\xa2\xb3\x82\"}", 15}, {"{a:\"\\u0006\"}", 12}, {" { } ", 4}, {"{a:1}", 5}, {"{a:1.23}", 8}, {"{a:1e23}", 8}, {"{a:1.23e2}", 10}, {"{a:-123}", 8}, {"{a:-1.3}", 8}, {"{a:-1.3e-2}", 11}, {"{a:\"\"}", 6}, {"{a:\" \\n\\t\\r\"}", 13}, {" {a:[1]} 123456", 8}, {" {a:[]} 123456", 7}, {" {a:[1,2]} 123456", 10}, {"{a:1,b:2} xxxx", 9}, {"{a:1,b:{},c:[{}]} xxxx", 17}, {"{a:true,b:[false,null]} xxxx", 23}, {"[1.23, 3, 5]", 12}, {"[13, {\"a\":\"hi there\"}, 5]", 25}, {NULL, 0}}; const char *s1 = " { a: 1, b: \"hi there\", c: true, d: false, " " e : null, f: [ 1, -2, 3], g: { \"1\": [], h: [ 7 ] } } "; int i; ASSERT(json_walk(NULL, 0, NULL, 0) == JSON_STRING_INVALID); for (i = 0; invalid_tests[i] != NULL; i++) { ASSERT(json_walk(invalid_tests[i], strlen(invalid_tests[i]), NULL, NULL) == JSON_STRING_INVALID); } for (i = 0; incomplete_tests[i] != NULL; i++) { ASSERT(json_walk(incomplete_tests[i], strlen(incomplete_tests[i]), NULL, NULL) == JSON_STRING_INCOMPLETE); } for (i = 0; success_tests[i].str != NULL; i++) { ASSERT(json_walk(success_tests[i].str, strlen(success_tests[i].str), NULL, NULL) == success_tests[i].expected_len); } ASSERT(json_walk("{}", 2, NULL, NULL) == 2); ASSERT(json_walk(s1, strlen(s1), NULL, 0) > 0); return NULL; }