Skip to content

CFPropertyList: fix CFPropertyListCreateDeepCopy of mutable containers#61

Open
DTW-Thalion wants to merge 1 commit into
gnustep:masterfrom
DTW-Thalion:fix/cfpropertylist-deepcopy
Open

CFPropertyList: fix CFPropertyListCreateDeepCopy of mutable containers#61
DTW-Thalion wants to merge 1 commit into
gnustep:masterfrom
DTW-Thalion:fix/cfpropertylist-deepcopy

Conversation

@DTW-Thalion

Copy link
Copy Markdown
Contributor

Summary

CFPropertyListCreateDeepCopy could not deep-copy a mutable array or
dictionary, for two reasons:

  1. Type IDs never initialised on this path. CFPropertyListInitTypeIDs
    (which lazily fills _kCFArrayTypeID, _kCFDictionaryTypeID, …) was only
    called from the validation code. On a standalone CFPropertyListCreateDeepCopy
    call, every CFGetTypeID(...) == _kCF*TypeID comparison saw 0, no branch
    matched, and the function returned NULL.

  2. Copy applied over the empty destination. Once the type IDs are
    initialised, the mutable array and dictionary branches applied their copy
    function over the freshly-created (empty) destination container instead of
    the source plist:

    array = CFArrayCreateMutable (alloc, cnt, ...);   /* empty */
    CFArrayApplyFunction (array, range, CFArrayCopyFunction, &ctx);  /* <- wrong */

    so the result came back empty (and iterating the empty array over
    range (0, cnt) was itself out of range).

Fix

Call CFPropertyListInitTypeIDs() at the top, and apply the copy functions
over the source plist.

Test

Tests/CFPropertyList/deepcopy.m: deep-copying a mutable array and a mutable
dictionary preserves their elements.

Two bugs prevented CFPropertyListCreateDeepCopy from copying a mutable
array or dictionary:

* The type-ID table was never initialised on this path
  (CFPropertyListInitTypeIDs was only called from the validation code),
  so every CFGetTypeID comparison failed and the function returned NULL
  unless some other property-list call had already run.
* The mutable array and dictionary branches applied their copy function
  over the freshly-created (empty) destination container instead of the
  source plist, so even with the type IDs initialised the result was
  empty.

Call CFPropertyListInitTypeIDs at the top, and apply the copy functions
over the source plist.

Add Tests/CFPropertyList/deepcopy.m.
@DTW-Thalion DTW-Thalion force-pushed the fix/cfpropertylist-deepcopy branch from d91495c to 40f063b Compare July 3, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant