Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSConcretePointerFunctions implementation is incorrect for non-default options #311

Open
brooke-tilley opened this issue Aug 14, 2023 · 0 comments
Labels
bug Use this tag for reporting bugs or issues that impede the software's normal functionality. help wanted Mark issues that are open for contributions with this tag.

Comments

@brooke-tilley
Copy link

There are some serious issues with the implementation of NSConcretePointerFunctions, especially w.r.t. the NSPointerFunctionsOptions enum and the initialization of PFInfo. I briefly tried to fix these problems locally, but the fixes soon spiraled into fixes to NSConcreteMapTable, NSPropertyList, and so on; so I'm just going to leave an issue here.

A couple concrete issues that I can be 100% certain about:

  1. The enum values of NSPointerFunctionsOptions are not bitfields. In other words, most of the options don't have a mutually-exclusive bitwise representation (they are just sequential integers). However in the vast majority of places that interacts with these options, they are treated as bitfields and bitwise-AND'ed against in an attempt to determine if they are "set". This produces completely unexpected behaviour.
    • I have found instances of this issue in NSConcretePointerFunctions, NSConcreteMapTable, NSConcreteHashTable, and NSPointerArray, but it may occur elsewhere as well.
    • Here is one small example of a place where this happens.
  2. The initWithOptions function in NSConcretePointerFunctions.m (apart from its issues with said enum values) also does not correctly set the fields of its PFInfo _x instance variable. An example of this is the acquireFunction function pointer, which doesn't get set based on the Memory flags, but instead gets set based on the Personality flags, which should only affect the hashFunction, isEqualFunction, and describeFunction fields. So in many cases, the acquireFunction will be mis-set, which can cause all sorts of memory issues (for example, a non-objc pointer could be casted to id and then sent a retain message).

In addition to those concrete issues, I'm fairly certain that there are some issues with the way that weak pointers are handled, especially in NSConcreteMapTable which "overrides" parts of the NSPointerFunctions functionality, presumably because it wasn't working. There is a comment about this from 2013. When I locally tried to patch the NSConcretePointerFunctions implementation, it cascaded into spooky memory issues in NSConcreteMapTable, NSPropertyList, and so on. I assume this is because those implementations have unknowingly been relying on unexpected behaviour from NSConcretePointerFunctions.

As mentioned, I am not going to fix these problems myself as the attempted fix grew well outside of my scope, but I'm leaving this issue here because it is a rather large potential source of memory corruption issues, memory leaks, and so on.

@hmelder hmelder added bug Use this tag for reporting bugs or issues that impede the software's normal functionality. help wanted Mark issues that are open for contributions with this tag. labels Sep 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Use this tag for reporting bugs or issues that impede the software's normal functionality. help wanted Mark issues that are open for contributions with this tag.
Development

No branches or pull requests

2 participants