From 9bfab35522301794483f8f9ed60820bdec9be59e Mon Sep 17 00:00:00 2001 From: Richard Russon Date: Thu, 5 Jul 2018 13:32:17 +0100 Subject: [PATCH] sanitise cache paths Co-authored-by: JerikoOne --- newsrc.c | 13 ++++++++++++- pop.c | 29 +++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/newsrc.c b/newsrc.c index a0f2c39de..c9dfdba23 100644 --- a/newsrc.c +++ b/newsrc.c @@ -715,7 +715,18 @@ int nntp_active_save_cache(struct NntpServer *nserv) */ static int nntp_hcache_namer(const char *path, char *dest, size_t destlen) { - return snprintf(dest, destlen, "%s.hcache", path); + int count = snprintf(dest, destlen, "%s.hcache", path); + + /* Strip out any directories in the path */ + char *first = strchr(dest, '/'); + char *last = strrchr(dest, '/'); + if (first && last && (last > first)) + { + memmove(first, last, strlen(last) + 1); + count -= (last - first); + } + + return count; } /** diff --git a/pop.c b/pop.c index 1da297252..4f3a592a8 100644 --- a/pop.c +++ b/pop.c @@ -63,6 +63,23 @@ #define HC_FEXT "hcache" /* extension for hcache as POP lacks paths */ #endif +/** + * cache_id - Make a message-cache-compatible id + * @param id POP message id + * @retval ptr Sanitised string + * + * The POP message id may contain '/' and other awkward characters. + * + * @note This function returns a pointer to a static buffer. + */ +static const char *cache_id(const char *id) +{ + static char clean[SHORT_STRING]; + mutt_str_strfcpy(clean, id, sizeof(clean)); + mutt_file_sanitize_filename(clean, true); + return clean; +} + /** * fetch_message - write line to file * @param line String to write @@ -242,7 +259,7 @@ static int msg_cache_check(const char *id, struct BodyCache *bcache, void *data) /* message not found in context -> remove it from cache * return the result of bcache, so we stop upon its first error */ - return mutt_bcache_del(bcache, id); + return mutt_bcache_del(bcache, cache_id(id)); } #ifdef USE_HCACHE @@ -407,7 +424,7 @@ static int pop_fetch_headers(struct Context *ctx) * - if we don't have a body: new */ const bool bcached = - (mutt_bcache_exists(pop_data->bcache, ctx->hdrs[i]->data) == 0); + (mutt_bcache_exists(pop_data->bcache, cache_id(ctx->hdrs[i]->data)) == 0); ctx->hdrs[i]->old = false; ctx->hdrs[i]->read = false; if (hcached) @@ -597,7 +614,7 @@ static int pop_fetch_message(struct Context *ctx, struct Message *msg, int msgno unsigned short bcache = 1; /* see if we already have the message in body cache */ - msg->fp = mutt_bcache_get(pop_data->bcache, h->data); + msg->fp = mutt_bcache_get(pop_data->bcache, cache_id(h->data)); if (msg->fp) return 0; @@ -644,7 +661,7 @@ static int pop_fetch_message(struct Context *ctx, struct Message *msg, int msgno NetInc, h->content->length + h->content->offset - 1); /* see if we can put in body cache; use our cache as fallback */ - msg->fp = mutt_bcache_put(pop_data->bcache, h->data); + msg->fp = mutt_bcache_put(pop_data->bcache, cache_id(h->data)); if (!msg->fp) { /* no */ @@ -689,7 +706,7 @@ static int pop_fetch_message(struct Context *ctx, struct Message *msg, int msgno * portion of the headers, those required for the main display. */ if (bcache) - mutt_bcache_commit(pop_data->bcache, h->data); + mutt_bcache_commit(pop_data->bcache, cache_id(h->data)); else { cache->index = h->index; @@ -783,7 +800,7 @@ static int pop_sync_mailbox(struct Context *ctx, int *index_hint) ret = pop_query(pop_data, buf, sizeof(buf)); if (ret == 0) { - mutt_bcache_del(pop_data->bcache, ctx->hdrs[i]->data); + mutt_bcache_del(pop_data->bcache, cache_id(ctx->hdrs[i]->data)); #ifdef USE_HCACHE mutt_hcache_delete(hc, ctx->hdrs[i]->data, strlen(ctx->hdrs[i]->data)); #endif -- 2.40.0