summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2011-12-08 21:58:26 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2011-12-08 21:58:26 +0000
commit4e4cf305cb856d772b5a85ac7bca2284e4ee0677 (patch)
treed889b2e51e49997ee250b70673f4bb7464da0f2e /content
parent4f4e7927bbd8c47da73b43d1ebce883be2eecffd (diff)
downloadnetsurf-4e4cf305cb856d772b5a85ac7bca2284e4ee0677.tar.gz
netsurf-4e4cf305cb856d772b5a85ac7bca2284e4ee0677.tar.bz2
Fix bug #3454606: prevent double free of retrieval context when downloading
svn path=/trunk/netsurf/; revision=13260
Diffstat (limited to 'content')
-rw-r--r--content/hlcache.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/content/hlcache.c b/content/hlcache.c
index 07f07a6a8..c7a803dee 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -52,6 +52,8 @@ struct hlcache_retrieval_ctx {
content_type accepted_types; /**< Accepted types */
hlcache_child_context child; /**< Child context */
+
+ bool migrate_target; /**< Whether this context is the migration target */
};
/** High-level cache handle */
@@ -291,7 +293,8 @@ nserror hlcache_handle_release(hlcache_handle *handle)
RING_ITERATE_START(struct hlcache_retrieval_ctx,
hlcache->retrieval_ctx_ring,
ictx) {
- if (ictx->handle == handle) {
+ if (ictx->handle == handle &&
+ ictx->migrate_target == false) {
/* This is the nascent context for us,
* so abort the fetch */
llcache_handle_abort(ictx->llcache);
@@ -342,7 +345,8 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
RING_ITERATE_START(struct hlcache_retrieval_ctx,
hlcache->retrieval_ctx_ring,
ictx) {
- if (ictx->handle == handle) {
+ if (ictx->handle == handle &&
+ ictx->migrate_target == false) {
/* This is the nascent context for us,
* so abort the fetch */
llcache_handle_abort(ictx->llcache);
@@ -607,21 +611,25 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
content_type type = CONTENT_NONE;
nserror error = NSERROR_OK;
+ ctx->migrate_target = true;
+
if (effective_type != NULL &&
hlcache_type_is_acceptable(effective_type,
ctx->accepted_types, &type)) {
error = hlcache_find_content(ctx, effective_type);
if (error != NSERROR_OK && error != NSERROR_NEED_DATA) {
- hlcache_event hlevent;
+ if (ctx->handle->cb != NULL) {
+ hlcache_event hlevent;
- hlevent.type = CONTENT_MSG_ERROR;
- hlevent.data.error = messages_get("MiscError");
+ hlevent.type = CONTENT_MSG_ERROR;
+ hlevent.data.error = messages_get("MiscError");
- ctx->handle->cb(ctx->handle, &hlevent,
- ctx->handle->pw);
+ ctx->handle->cb(ctx->handle, &hlevent,
+ ctx->handle->pw);
+ }
- /* ctx cleaned up by client releasing handle */
- return error;
+ llcache_handle_abort(ctx->llcache);
+ llcache_handle_release(ctx->llcache);
}
} else if (type == CONTENT_NONE &&
(ctx->flags & HLCACHE_RETRIEVE_MAY_DOWNLOAD)) {
@@ -652,10 +660,12 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
ctx->handle->pw);
}
- /* ctx cleaned up by client releasing handle */
- return NSERROR_OK;
+ llcache_handle_abort(ctx->llcache);
+ llcache_handle_release(ctx->llcache);
}
+ ctx->migrate_target = false;
+
/* No longer require retrieval context */
RING_REMOVE(hlcache->retrieval_ctx_ring, ctx);
free((char *) ctx->child.charset);