*/
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;
}
/**
#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
/* 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
* - 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)
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;
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 */
* 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;
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