Mercurial > blahgd > fmt4
view tag.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 | 99688032e2e9 |
children | 3c363a43965a 4f4615ebed2b |
line wrap: on
line source
/* * Copyright (c) 2011-2017 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 <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <stdbool.h> #include <jeffpc/array.h> #include <jeffpc/error.h> #include <jeffpc/types.h> #include <jeffpc/sexpr.h> #include "config.h" #include "render.h" #include "req.h" #include "utils.h" #include "sidebar.h" #include "post.h" /* * Wordpress uses category numbers. We need to map them to the string based * category names we use and generate a redirect. * * The list of number to string mappings is in the config file and we stuff * them into these variables on startup. See init_wordpress_categories(). */ static struct str **wordpress_cats; static void __store_title(struct vars *vars, struct str *title) { char twittertitle[1024]; snprintf(twittertitle, sizeof(twittertitle), "%s ยป %s", "Blahg", str_cstr(title)); vars_set_str(vars, "title", title); vars_set_str(vars, "twittertitle", STR_DUP(twittertitle)); } static void __store_tag(struct vars *vars, struct str *tag) { vars_set_str(vars, "tagid", tag); } static void __store_pages(struct vars *vars, int page) { vars_set_int(vars, "prevpage", page + 1); vars_set_int(vars, "curpage", page); vars_set_int(vars, "nextpage", page - 1); } int __tagcat(struct req *req, struct str *tag, int page, char *tmpl, bool istag) { const unsigned int posts_per_page = req->opts.index_stories; struct post *posts[posts_per_page]; int nposts; if (IS_ERR(tag)) return R404(req, NULL); req_head(req, "Content-Type", "text/html"); __store_title(&req->vars, str_getref(tag)); __store_pages(&req->vars, page); __store_tag(&req->vars, str_getref(tag)); sidebar(req); vars_scope_push(&req->vars); nposts = index_get_posts(posts, tag, istag, NULL, NULL, page * posts_per_page, posts_per_page); load_posts(req, posts, nposts, nposts == posts_per_page); str_putref(tag); req->scgi->response.body = render_page(req, tmpl); return 0; } int blahg_tag(struct req *req, int page) { return __tagcat(req, nvl_lookup_str(req->scgi->request.query, "tag"), page, "{tagindex}", true); } int blahg_category(struct req *req, int page) { struct str *cat; uint32_t catn; cat = nvl_lookup_str(req->scgi->request.query, "cat"); if (IS_ERR(cat)) goto out; /* * If we fail to parse the category number or it refers to a * non-mapped category, we just use it as is. */ if (wordpress_cats && !str2u32(str_cstr(cat), &catn)) { char url[256]; if (catn >= array_size(wordpress_cats)) goto out; if (!wordpress_cats[catn]) goto out; str_putref(cat); snprintf(url, sizeof(url), "%s/?cat=%s", str_cstr(config.base_url), str_cstr(wordpress_cats[catn])); return R301(req, url); } out: return __tagcat(req, cat, page, "{catindex}", false); } /* * Each entry should be of the form: (int . str) */ static int store_wordpress_category(struct val *cur) { struct val *idx, *name; int ret; if (cur->type != VT_CONS) { val_putref(cur); return -EINVAL; } idx = sexpr_car(val_getref(cur)); name = sexpr_cdr(cur); if ((idx->type != VT_INT) || (name->type != VT_STR)) { cmn_err(CE_ERROR, "wordpress category entry type error - " "expecting: (int . string)"); ret = -EINVAL; goto out; } if (idx->i >= array_size(wordpress_cats)) { ret = array_truncate(&wordpress_cats, idx->i + 1); if (ret) goto out; } wordpress_cats[idx->i] = val_getref_str(name); ret = 0; out: val_putref(idx); val_putref(name); return ret; } int init_wordpress_categories(void) { struct val *cur, *tmp; int ret = 0; wordpress_cats = array_alloc(sizeof(struct str *), 0); sexpr_for_each_noref(cur, tmp, config.wordpress_categories) { ret = store_wordpress_category(val_getref(cur)); if (ret) break; } /* if there is nothing, free it */ if (!array_size(wordpress_cats)) { array_free(wordpress_cats); wordpress_cats = NULL; } return ret; }