Mercurial > blahgd > fmt4
view pipeline.c @ 1125:9293874827bf
post: don't leak parsed tag and cat names
Sadly, the recent commit (37044617c35deabfe8337a049d2da635bb14075a) did not
fix all the reference leaks surrounding the tag and category name s-expression
processing.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sat, 09 Jun 2018 20:06:30 -0400 |
parents | d13f51a2d239 |
children | 3c363a43965a |
line wrap: on
line source
/* * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <string.h> #include <stddef.h> #include <stdio.h> #include <ctype.h> #include <jeffpc/error.h> #include <jeffpc/val.h> #include <jeffpc/mem.h> #include "pipeline.h" #include "utils.h" #include "mangle.h" static struct mem_cache *pipestage_cache; static struct mem_cache *pipeline_cache; void init_pipe_subsys(void) { pipestage_cache = mem_cache_create("pipestage-cache", sizeof(struct pipestage), 0); ASSERT(!IS_ERR(pipestage_cache)); pipeline_cache = mem_cache_create("pipeline-cache", sizeof(struct pipeline), 0); ASSERT(!IS_ERR(pipeline_cache)); } static struct val *nop_fxn(struct val *val) { return val; } static char *str_of_int(uint64_t v) { return NULL; } static char *__urlescape_str(const char *in) { static const char hd[16] = "0123456789ABCDEF"; char *out, *tmp; int outlen; const char *s; outlen = strlen(in); for (s = in; *s; s++) { char c = *s; if (isalnum(c)) continue; switch (c) { case ' ': case '-': case '_': case '.': case '~': continue; } /* this char will be escaped */ outlen += 2; } out = malloc(outlen + 1); ASSERT(out); for (s = in, tmp = out; *s; s++, tmp++) { unsigned char c = *s; if (isalnum(c)) { *tmp = c; continue; } switch (c) { case ' ': *tmp = '+'; continue; case '-': case '_': case '.': case '~': *tmp = c; continue; } /* this char will be escaped */ tmp[0] = '%'; tmp[1] = hd[c >> 4]; tmp[2] = hd[c & 0xf]; tmp += 2; } *tmp = '\0'; return out; } static struct val *__escape(struct val *val, char *(*cvt)(const char*)) { char *out; out = NULL; switch (val->type) { case VT_INT: out = str_of_int(val->i); break; case VT_STR: out = cvt(str_cstr(val_cast_to_str(val))); break; case VT_NULL: val_putref(val); return str_cast_to_val(str_empty_string()); case VT_BLOB: case VT_SYM: case VT_CONS: case VT_BOOL: case VT_CHAR: case VT_ARRAY: case VT_NVL: panic("%s called with value type %d", __func__, val->type); } val_putref(val); ASSERT(out); return VAL_ALLOC_STR(out); } static struct val *urlescape_fxn(struct val *val) { return __escape(val, __urlescape_str); } static struct val *escape_fxn(struct val *val) { return __escape(val, mangle_htmlescape); } static struct val *__datetime(struct val *val, const char *fmt) { char buf[64]; struct tm tm; time_t ts; ASSERT3U(val->type, ==, VT_INT); ts = val->i; gmtime_r(&ts, &tm); strftime(buf, sizeof(buf), fmt, &tm); val_putref(val); return VAL_DUP_STR(buf); } static struct val *time_fxn(struct val *val) { return __datetime(val, "%H:%M"); } static struct val *date_fxn(struct val *val) { return __datetime(val, "%B %e, %Y"); } static struct val *zulu_fxn(struct val *val) { return __datetime(val, "%Y-%m-%dT%H:%M:%SZ"); } static struct val *rfc822_fxn(struct val *val) { return __datetime(val, "%a, %d %b %Y %H:%M:%S +0000"); } static const struct pipestageinfo stages[] = { { "urlescape", urlescape_fxn, }, { "escape", escape_fxn, }, { "time", time_fxn, }, { "date", date_fxn, }, { "zulu", zulu_fxn, }, { "rfc822", rfc822_fxn, }, { NULL, }, }; static const struct pipestageinfo nop = { "nop", nop_fxn, }; struct pipestage *pipestage_alloc(char *name) { struct pipestage *pipe; int i; pipe = mem_cache_alloc(pipestage_cache); ASSERT(pipe); pipe->stage = &nop; for (i = 0; stages[i].name; i++) { if (!strcmp(name, stages[i].name)) { pipe->stage = &stages[i]; break; } } return pipe; } struct pipeline *pipestage_to_pipeline(struct pipestage *stage) { struct pipeline *line; line = mem_cache_alloc(pipeline_cache); ASSERT(line); list_create(&line->pipe, sizeof(struct pipestage), offsetof(struct pipestage, pipe)); pipeline_append(line, stage); return line; } void pipeline_append(struct pipeline *line, struct pipestage *stage) { list_insert_tail(&line->pipe, stage); } void pipeline_destroy(struct pipeline *line) { while (!list_is_empty(&line->pipe)) mem_cache_free(pipestage_cache, list_remove_head(&line->pipe)); mem_cache_free(pipeline_cache, line); }