X-Git-Url: http://git.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=delta.c;h=d8bd3a6ccae8d0a6330c9660b3b5ee294cda1a3c;hp=357f5c79126064b9d857e612d110680ce91f16c9;hb=HEAD;hpb=3c7f3556b0039a19ddd3e263286085f6896da0eb diff --git a/delta.c b/delta.c index 357f5c7..5437fc1 100644 --- a/delta.c +++ b/delta.c @@ -100,7 +100,7 @@ int uci_set_savedir(struct uci_context *ctx, const char *dir) { char *sdir; struct uci_element *e, *tmp; - bool exists = false; + volatile bool exists = false; UCI_HANDLE_ERR(ctx); UCI_ASSERT(ctx, dir != NULL); @@ -114,9 +114,8 @@ int uci_set_savedir(struct uci_context *ctx, const char *dir) } } if (!exists) - UCI_INTERNAL(uci_add_delta_path, ctx, dir); - else - uci_list_add(&ctx->delta_path, &e->list); + e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element)); + uci_list_add(&ctx->delta_path, &e->list); sdir = uci_strdup(ctx, dir); if (ctx->savedir != uci_savedir) @@ -164,6 +163,9 @@ static inline int uci_parse_delta_tuple(struct uci_context *ctx, struct uci_ptr int c; UCI_INTERNAL(uci_parse_argument, ctx, ctx->pctx->file, &str, &arg); + if (str && *str) { + goto error; + } for (c = 0; c <= __UCI_CMD_LAST; c++) { if (uci_command_char[c] == *arg) break; @@ -180,6 +182,9 @@ static inline int uci_parse_delta_tuple(struct uci_context *ctx, struct uci_ptr goto error; if (ptr->flags & UCI_LOOKUP_EXTENDED) goto error; + if (c != UCI_CMD_REMOVE && !ptr->value) { + goto error; + } switch(c) { case UCI_CMD_REORDER: @@ -193,6 +198,7 @@ static inline int uci_parse_delta_tuple(struct uci_context *ctx, struct uci_ptr case UCI_CMD_LIST_ADD: if (!ptr->option) goto error; + /* fall through */ case UCI_CMD_LIST_DEL: if (!ptr->option) goto error; @@ -207,7 +213,6 @@ error: static void uci_parse_delta_line(struct uci_context *ctx, struct uci_package *p) { - struct uci_element *e = NULL; struct uci_ptr ptr; int cmd; @@ -238,11 +243,14 @@ static void uci_parse_delta_line(struct uci_context *ctx, struct uci_package *p) UCI_INTERNAL(uci_del_list, ctx, &ptr); break; case UCI_CMD_ADD: + UCI_INTERNAL(uci_set, ctx, &ptr); + if (!ptr.option && ptr.s) + ptr.s->anonymous = true; + break; case UCI_CMD_CHANGE: UCI_INTERNAL(uci_set, ctx, &ptr); - e = ptr.last; - if (!ptr.option && e && (cmd == UCI_CMD_ADD)) - uci_to_section(e)->anonymous = true; + break; + default: break; } return; @@ -254,7 +262,7 @@ error: static int uci_parse_delta(struct uci_context *ctx, FILE *stream, struct uci_package *p) { struct uci_parse_context *pctx; - int changes = 0; + volatile int changes = 0; /* make sure no memory from previous parse attempts is leaked */ uci_cleanup(ctx); @@ -287,20 +295,22 @@ error: } /* returns the number of changes that were successfully parsed */ -static int uci_load_delta_file(struct uci_context *ctx, struct uci_package *p, char *filename, FILE **f, bool flush) +static int uci_load_delta_file(struct uci_context *ctx, struct uci_package *p, char *filename, FILE *volatile *f, bool flush) { - FILE *stream = NULL; - int changes = 0; + FILE *volatile stream = NULL; + volatile int changes = 0; UCI_TRAP_SAVE(ctx, done); stream = uci_open_stream(ctx, filename, NULL, SEEK_SET, flush, false); + UCI_TRAP_RESTORE(ctx); + if (p) changes = uci_parse_delta(ctx, stream, p); - UCI_TRAP_RESTORE(ctx); + done: if (f) *f = stream; - else if (stream) + else uci_close_stream(stream); return changes; } @@ -310,8 +320,8 @@ __private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, boo { struct uci_element *e; char *filename = NULL; - FILE *f = NULL; - int changes = 0; + FILE *volatile f = NULL; + volatile int changes = 0; if (!p->has_delta) return 0; @@ -326,9 +336,7 @@ __private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, boo if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename) UCI_THROW(ctx, UCI_ERR_MEM); - UCI_TRAP_SAVE(ctx, done); - f = uci_open_stream(ctx, filename, NULL, SEEK_SET, flush, false); - UCI_TRAP_RESTORE(ctx); + uci_load_delta_file(ctx, NULL, filename, &f, flush); if (flush && f && (changes > 0)) { if (ftruncate(fileno(f), 0) < 0) { @@ -338,7 +346,6 @@ __private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, boo } } -done: free(filename); uci_close_stream(f); ctx->err = 0; @@ -384,7 +391,7 @@ static void uci_filter_delta(struct uci_context *ctx, const char *name, const ch match = false; } - if (!match) { + if (!match && ptr.section) { uci_add_delta(ctx, &list, c, ptr.section, ptr.option, ptr.value); } @@ -412,9 +419,9 @@ done: int uci_revert(struct uci_context *ctx, struct uci_ptr *ptr) { - char *package = NULL; - char *section = NULL; - char *option = NULL; + char *volatile package = NULL; + char *volatile section = NULL; + char *volatile option = NULL; UCI_HANDLE_ERR(ctx); uci_expand_ptr(ctx, ptr, false); @@ -456,7 +463,7 @@ error: int uci_save(struct uci_context *ctx, struct uci_package *p) { - FILE *f = NULL; + FILE *volatile f = NULL; char *filename = NULL; struct uci_element *e, *tmp; struct stat statbuf;