summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtchang%redhat.com <devnull@localhost>2005-03-15 00:53:05 +0000
committerwtchang%redhat.com <devnull@localhost>2005-03-15 00:53:05 +0000
commit5d6a1fe5a6f69512e56da0a6e96a9efad9b7536f (patch)
treef4a96af4413df224a60cfa2af7c9ec93712961fc
parent9d7ea5d4a7808ccb55a820f12c48b5006a9b76e6 (diff)
downloadnspr-hg-5d6a1fe5a6f69512e56da0a6e96a9efad9b7536f.tar.gz
Bugzilla Bug 238563: carried the fixes from the trunk (revisions 3.15 and
3.16) to the NSPRPUB_PRE_4_2_CLIENT_BRANCH.
-rw-r--r--pr/src/malloc/prmem.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/pr/src/malloc/prmem.c b/pr/src/malloc/prmem.c
index e88207a4..1ef3d2f7 100644
--- a/pr/src/malloc/prmem.c
+++ b/pr/src/malloc/prmem.c
@@ -334,7 +334,6 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
if (!oldptr)
return pr_ZoneMalloc(bytes);
mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb));
- PR_ASSERT(mb->s.magic == ZONE_MAGIC);
if (mb->s.magic != ZONE_MAGIC) {
/* Maybe this just came from ordinary malloc */
#ifdef DEBUG
@@ -342,11 +341,24 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
"Warning: reallocing memory block %p from ordinary malloc\n",
oldptr);
#endif
+ /*
+ * We are going to realloc oldptr. If realloc succeeds, the
+ * original value of oldptr will point to freed memory. So this
+ * function must not fail after a successfull realloc call. We
+ * must perform any operation that may fail before the realloc
+ * call.
+ */
+ rv = pr_ZoneMalloc(bytes); /* this may fail */
+ if (!rv) {
+ return rv;
+ }
+
/* We don't know how big it is. But we can fix that. */
oldptr = realloc(oldptr, bytes);
if (!oldptr) {
if (bytes) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ pr_ZoneFree(rv);
return oldptr;
}
}
@@ -367,17 +379,18 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
return oldptr;
}
ours = 1;
+ rv = pr_ZoneMalloc(bytes);
+ if (!rv) {
+ return rv;
+ }
}
- rv = pr_ZoneMalloc(bytes);
- if (rv) {
- if (oldptr && mb->s.requestedSize)
- memcpy(rv, oldptr, mb->s.requestedSize);
- if (ours)
- pr_ZoneFree(oldptr);
- else if (oldptr)
- free(oldptr);
- }
+ if (oldptr && mb->s.requestedSize)
+ memcpy(rv, oldptr, mb->s.requestedSize);
+ if (ours)
+ pr_ZoneFree(oldptr);
+ else if (oldptr)
+ free(oldptr);
return rv;
}