diff options
author | wtchang%redhat.com <devnull@localhost> | 2005-03-15 00:53:05 +0000 |
---|---|---|
committer | wtchang%redhat.com <devnull@localhost> | 2005-03-15 00:53:05 +0000 |
commit | 5d6a1fe5a6f69512e56da0a6e96a9efad9b7536f (patch) | |
tree | f4a96af4413df224a60cfa2af7c9ec93712961fc | |
parent | 9d7ea5d4a7808ccb55a820f12c48b5006a9b76e6 (diff) | |
download | nspr-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.c | 33 |
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; } |