Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}