remove internal usage of redundant uci_ptr.last
[project/uci.git] / file.c
diff --git a/file.c b/file.c
index 6486de9c422971e6b886a2b5f2f9ef2fd0200423..6610f531c2f64852b032e9ead2ec30b35d61873a 100644 (file)
--- a/file.c
+++ b/file.c
 /*
  * Fetch a new line from the input stream and resize buffer if necessary
  */
-__private void uci_getln(struct uci_context *ctx, int offset)
+__private void uci_getln(struct uci_context *ctx, size_t offset)
 {
        struct uci_parse_context *pctx = ctx->pctx;
        char *p;
-       int ofs;
+       size_t ofs;
 
        if (pctx->buf == NULL) {
                pctx->buf = uci_malloc(ctx, LINEBUF);
@@ -64,6 +64,7 @@ __private void uci_getln(struct uci_context *ctx, int offset)
                        return;
 
                ofs += strlen(p);
+               pctx->buf_filled = ofs;
                if (pctx->buf[ofs - 1] == '\n') {
                        pctx->line++;
                        return;
@@ -112,7 +113,7 @@ static void skip_whitespace(struct uci_context *ctx)
                pctx->pos += 1;
 }
 
-static inline void addc(struct uci_context *ctx, int *pos_dest, int *pos_src)
+static inline void addc(struct uci_context *ctx, size_t *pos_dest, size_t *pos_src)
 {
        struct uci_parse_context *pctx = ctx->pctx;
 
@@ -121,10 +122,19 @@ static inline void addc(struct uci_context *ctx, int *pos_dest, int *pos_src)
        *pos_src += 1;
 }
 
+static int uci_increase_pos(struct uci_parse_context *pctx, size_t add)
+{
+       if (pctx->pos + add > pctx->buf_filled)
+               return -EINVAL;
+
+       pctx->pos += add;
+       return 0;
+}
+
 /*
  * parse a double quoted string argument from the command line
  */
-static void parse_double_quote(struct uci_context *ctx, int *target)
+static void parse_double_quote(struct uci_context *ctx, size_t *target)
 {
        struct uci_parse_context *pctx = ctx->pctx;
        char c;
@@ -159,7 +169,7 @@ static void parse_double_quote(struct uci_context *ctx, int *target)
 /*
  * parse a single quoted string argument from the command line
  */
-static void parse_single_quote(struct uci_context *ctx, int *target)
+static void parse_single_quote(struct uci_context *ctx, size_t *target)
 {
        struct uci_parse_context *pctx = ctx->pctx;
        char c;
@@ -188,7 +198,7 @@ static void parse_single_quote(struct uci_context *ctx, int *target)
 /*
  * parse a string from the command line and detect the quoting style
  */
-static void parse_str(struct uci_context *ctx, int *target)
+static void parse_str(struct uci_context *ctx, size_t *target)
 {
        struct uci_parse_context *pctx = ctx->pctx;
        bool next = true;
@@ -237,7 +247,7 @@ done:
 static int next_arg(struct uci_context *ctx, bool required, bool name, bool package)
 {
        struct uci_parse_context *pctx = ctx->pctx;
-       int val, ptr;
+       size_t val, ptr;
 
        skip_whitespace(ctx);
        val = ptr = pctx_pos(pctx);
@@ -385,11 +395,12 @@ static void uci_parse_package(struct uci_context *ctx, bool single)
        char *name;
 
        /* command string null-terminated by strtok */
-       pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
+       if (uci_increase_pos(pctx, strlen(pctx_cur_str(pctx)) + 1))
+               uci_parse_error(ctx, "package without name");
 
        ofs_name = next_arg(ctx, true, true, true);
-       name = pctx_str(pctx, ofs_name);
        assert_eol(ctx);
+       name = pctx_str(pctx, ofs_name);
        if (single)
                return;
 
@@ -417,7 +428,8 @@ static void uci_parse_config(struct uci_context *ctx)
        }
 
        /* command string null-terminated by strtok */
-       pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
+       if (uci_increase_pos(pctx, strlen(pctx_cur_str(pctx)) + 1))
+               uci_parse_error(ctx, "config without name");
 
        ofs_type = next_arg(ctx, true, false, false);
        type = pctx_str(pctx, ofs_type);
@@ -447,7 +459,7 @@ static void uci_parse_config(struct uci_context *ctx)
 
                ctx->internal = !pctx->merge;
                UCI_NESTED(uci_set, ctx, &ptr);
-               pctx->section = uci_to_section(ptr.last);
+               pctx->section = ptr.s;
        }
 }
 
@@ -467,7 +479,8 @@ static void uci_parse_option(struct uci_context *ctx, bool list)
                uci_parse_error(ctx, "option/list command found before the first section");
 
        /* command string null-terminated by strtok */
-       pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
+       if (uci_increase_pos(pctx, strlen(pctx_cur_str(pctx)) + 1))
+               uci_parse_error(ctx, "option without name");
 
        ofs_name = next_arg(ctx, true, true, false);
        ofs_value = next_arg(ctx, false, false, false);
@@ -726,7 +739,7 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
        char *filename = NULL;
        struct stat statbuf;
        volatile bool do_rename = false;
-       int fd;
+       int fd, sz;
 
        if (!p->path) {
                if (overwrite)
@@ -735,8 +748,9 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
                        UCI_THROW(ctx, UCI_ERR_INVAL);
        }
 
-       if ((asprintf(&filename, "%s/.%s.uci-XXXXXX", ctx->confdir, p->e.name) < 0) || !filename)
-               UCI_THROW(ctx, UCI_ERR_MEM);
+       sz = snprintf(NULL, 0, "%s/.%s.uci-XXXXXX", ctx->confdir, p->e.name);
+       filename = alloca(sz + 1);
+       snprintf(filename, sz + 1, "%s/.%s.uci-XXXXXX", ctx->confdir, p->e.name);
 
        /* open the config file for writing now, so that it is locked */
        f1 = uci_open_stream(ctx, p->path, NULL, SEEK_SET, true, true);
@@ -808,7 +822,6 @@ done:
                }
                free(path);
        }
-       free(filename);
        if (ctx->err)
                UCI_THROW(ctx, ctx->err);
 }