diff options
Diffstat (limited to 'src/templating/mustach-wrap.c')
-rw-r--r-- | src/templating/mustach-wrap.c | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/src/templating/mustach-wrap.c b/src/templating/mustach-wrap.c index 75cc9d1f6..2cd00db12 100644 --- a/src/templating/mustach-wrap.c +++ b/src/templating/mustach-wrap.c @@ -6,7 +6,9 @@ SPDX-License-Identifier: ISC */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <stdlib.h> #include <stdio.h> @@ -18,6 +20,18 @@ #include "mustach.h" #include "mustach-wrap.h" +/* +* It was stated that allowing to include files +* through template is not safe when the mustache +* template is open to any value because it could +* create leaks (example: {{>/etc/passwd}}). +*/ +#if MUSTACH_SAFE +# undef MUSTACH_LOAD_TEMPLATE +#elif !defined(MUSTACH_LOAD_TEMPLATE) +# define MUSTACH_LOAD_TEMPLATE 1 +#endif + #if !defined(INCLUDE_PARTIAL_EXTENSION) # define INCLUDE_PARTIAL_EXTENSION ".mustache" #endif @@ -227,20 +241,20 @@ static enum sel sel(struct wrap *w, const char *name) return result; } -static int start(void *closure) +static int start_callback(void *closure) { struct wrap *w = closure; return w->itf->start ? w->itf->start(w->closure) : MUSTACH_OK; } -static void stop(void *closure, int status) +static void stop_callback(void *closure, int status) { struct wrap *w = closure; if (w->itf->stop) w->itf->stop(w->closure, status); } -static int write(struct wrap *w, const char *buffer, size_t size, FILE *file) +static int emit(struct wrap *w, const char *buffer, size_t size, FILE *file) { int r; @@ -251,7 +265,7 @@ static int write(struct wrap *w, const char *buffer, size_t size, FILE *file) return r; } -static int emit(void *closure, const char *buffer, size_t size, int escape, FILE *file) +static int emit_callback(void *closure, const char *buffer, size_t size, int escape, FILE *file) { struct wrap *w = closure; int r; @@ -261,7 +275,7 @@ static int emit(void *closure, const char *buffer, size_t size, int escape, FILE if (w->emitcb) r = w->emitcb(file, buffer, size, escape); else if (!escape) - r = write(w, buffer, size, file); + r = emit(w, buffer, size, file); else { i = 0; r = MUSTACH_OK; @@ -270,13 +284,13 @@ static int emit(void *closure, const char *buffer, size_t size, int escape, FILE while (i < size && (car = buffer[i]) != '<' && car != '>' && car != '&' && car != '"') i++; if (i != s) - r = write(w, &buffer[s], i - s, file); + r = emit(w, &buffer[s], i - s, file); if (i < size && r == MUSTACH_OK) { switch(car) { - case '<': r = write(w, "<", 4, file); break; - case '>': r = write(w, ">", 4, file); break; - case '&': r = write(w, "&", 5, file); break; - case '"': r = write(w, """, 6, file); break; + case '<': r = emit(w, "<", 4, file); break; + case '>': r = emit(w, ">", 4, file); break; + case '&': r = emit(w, "&", 5, file); break; + case '"': r = emit(w, """, 6, file); break; } i++; } @@ -285,20 +299,20 @@ static int emit(void *closure, const char *buffer, size_t size, int escape, FILE return r; } -static int enter(void *closure, const char *name) +static int enter_callback(void *closure, const char *name) { struct wrap *w = closure; enum sel s = sel(w, name); return s == S_none ? 0 : w->itf->enter(w->closure, s & S_objiter); } -static int next(void *closure) +static int next_callback(void *closure) { struct wrap *w = closure; return w->itf->next(w->closure); } -static int leave(void *closure) +static int leave_callback(void *closure) { struct wrap *w = closure; return w->itf->leave(w->closure); @@ -312,7 +326,7 @@ static int getoptional(struct wrap *w, const char *name, struct mustach_sbuf *sb return w->itf->get(w->closure, sbuf, s & S_objiter); } -static int get(void *closure, const char *name, struct mustach_sbuf *sbuf) +static int get_callback(void *closure, const char *name, struct mustach_sbuf *sbuf) { struct wrap *w = closure; if (getoptional(w, name, sbuf) <= 0) { @@ -323,6 +337,7 @@ static int get(void *closure, const char *name, struct mustach_sbuf *sbuf) return MUSTACH_OK; } +#if MUSTACH_LOAD_TEMPLATE static int get_partial_from_file(const char *name, struct mustach_sbuf *sbuf) { static char extension[] = INCLUDE_PARTIAL_EXTENSION; @@ -373,14 +388,22 @@ static int get_partial_from_file(const char *name, struct mustach_sbuf *sbuf) fclose(file); return MUSTACH_ERROR_SYSTEM; } +#endif -static int partial(void *closure, const char *name, struct mustach_sbuf *sbuf) +static int partial_callback(void *closure, const char *name, struct mustach_sbuf *sbuf) { struct wrap *w = closure; int rc; - if (mustach_wrap_get_partial != NULL) + if (mustach_wrap_get_partial != NULL) { rc = mustach_wrap_get_partial(name, sbuf); - else if (w->flags & Mustach_With_PartialDataFirst) { + if (rc != MUSTACH_ERROR_PARTIAL_NOT_FOUND) { + if (rc != MUSTACH_OK) + sbuf->value = ""; + return rc; + } + } +#if MUSTACH_LOAD_TEMPLATE + if (w->flags & Mustach_With_PartialDataFirst) { if (getoptional(w, name, sbuf) > 0) rc = MUSTACH_OK; else @@ -391,21 +414,24 @@ static int partial(void *closure, const char *name, struct mustach_sbuf *sbuf) if (rc != MUSTACH_OK && getoptional(w, name, sbuf) > 0) rc = MUSTACH_OK; } +#else + rc = getoptional(w, name, sbuf) > 0 ? MUSTACH_OK : MUSTACH_ERROR_PARTIAL_NOT_FOUND; +#endif if (rc != MUSTACH_OK) sbuf->value = ""; return MUSTACH_OK; } const struct mustach_itf mustach_wrap_itf = { - .start = start, + .start = start_callback, .put = NULL, - .enter = enter, - .next = next, - .leave = leave, - .partial = partial, - .get = get, - .emit = emit, - .stop = stop + .enter = enter_callback, + .next = next_callback, + .leave = leave_callback, + .partial = partial_callback, + .get = get_callback, + .emit = emit_callback, + .stop = stop_callback }; static void wrap_init(struct wrap *wrap, const struct mustach_wrap_itf *itf, void *closure, int flags, mustach_emit_cb_t *emitcb, mustach_write_cb_t *writecb) |