diff --git a/ChangeLog b/ChangeLog index d38300185..090b2978a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,14 @@ +2004-04-09 Richard Frith-Macdonald + + * Source/NSUnarchiver.m: Retain objects while they are being + decoded. Fixes problem reported by Willem Rein Oudshoorn where + an object used by more than one object being decoded could be + released by one object before being used by the other. + 2004-04-09 Willem Rein Oudshoorn - * Source/NSTask.m ([NSConcreteWindowsTask -launch]): Set stdin/stdout/stderr - file to values provided by the user (Fix #8417) + * Source/NSTask.m ([NSConcreteWindowsTask -launch]): Set + stdin/stdout/stderr file to values provided by the user (Fix #8417) 2004-04-08 Adam Fedor diff --git a/Source/NSUnarchiver.m b/Source/NSUnarchiver.m index b1f7feb0a..8c64519d9 100644 --- a/Source/NSUnarchiver.m +++ b/Source/NSUnarchiver.m @@ -395,8 +395,14 @@ static Class NSDataMallocClass; if (clsMap) { NSZone *z = clsMap->zone; + unsigned i; GSIArrayClear(clsMap); + i = GSIArrayCount(objMap); + while (i-- > 0) + { + RELEASE(GSIArrayItemAtIndex(objMap, i).obj); + } GSIArrayClear(objMap); GSIArrayClear(ptrMap); NSZoneFree(z, (void*)clsMap); @@ -594,19 +600,25 @@ static Class NSDataMallocClass; format: @"decoded nil class"]; } obj = [c allocWithZone: zone]; + /* + * The objMap array does not retain its contents directly, + * so we perform explicit retain/release as we add objects + * to and remove objects from the array. + */ + RETAIN(obj); GSIArrayAddItem(objMap, (GSIArrayItem)obj); rep = [obj initWithCoder: self]; if (rep != obj) { - obj = rep; + ASSIGN(obj, rep); GSIArraySetItemAtIndex(objMap, (GSIArrayItem)obj, xref); } rep = [obj awakeAfterUsingCoder: self]; if (rep != obj) { - obj = rep; + ASSIGN(obj, rep); GSIArraySetItemAtIndex(objMap, (GSIArrayItem)obj, xref); } } @@ -1161,11 +1173,16 @@ static Class NSDataMallocClass; if (replacement == anObject) return; - for (i = GSIArrayCount(objMap) - 1; i > 0; i--) + i = GSIArrayCount(objMap); + while (i-- > 0) { - if (GSIArrayItemAtIndex(objMap, i).obj == anObject) + id old = GSIArrayItemAtIndex(objMap, i).obj; + + if (old == anObject) { GSIArraySetItemAtIndex(objMap, (GSIArrayItem)replacement, i); + RETAIN(replacement); + RELEASE(old); return; } } @@ -1255,7 +1272,7 @@ static Class NSDataMallocClass; objMap = &clsMap[1]; GSIArrayInitWithZoneAndCapacity(objMap, zone, sizeO); - GSIArrayAddItem(objMap, (GSIArrayItem)(void*)0); + GSIArrayAddItem(objMap, (GSIArrayItem)(void*)nil); ptrMap = &clsMap[2]; GSIArrayInitWithZoneAndCapacity(ptrMap, zone, sizeP);