Repository navigation
Refactor ConfigEntry and related iterators for safer memory management - #1499
Conversation
|
Thanks. This is the review from Kimi:
|
All great points:
|
|
Feedback regarding the latest commit: GitError now carries two args, changing str(e) everywhereerrors.py now does raise GitError(message, giterr.klass). Since GitError is a plain C-defined exception, str() of a two-arg exception is the tuple repr: This affects nearly every libgit2 error raised through check_error (all real errors have a klass). Evidence it's already biting: the commit had to patch settings.py:72 • Users' tracebacks and logs will show ('message', 7) instead of message. Suggestion: attach the class as an attribute instead of a second arg — if giterr != ffi.NULL and giterr.klass != 0:
error = GitError(message)
error.klass = giterr.klass
raise error
raise GitError(message)(_pygit2 exceptions are heap types; instances accept attributes.) Then config.py checks getattr(e, 'klass', None) == C.GIT_ERROR_CONFIG, settings.py can revert to its Breaking change in parse_bool/parse_intThe change to ValueError is good, but it would break user code catching GitError. Instead it may raise InvalidError which inherits from both GitError and ValueError.
|
|
I have implemented your latest suggestions and fixed the issues you pointed out. |
ConfigEntryis holding on togit_config_entrypointers for its entire lifespan, but this isn't safe or necessary. When getting a single entry without an iterator, this isn't really a concern. However, when entries are iterated withgit_config_next, the previously-allocated iterator entry object is re-used. IfConfigEntryis still holding onto thegit_config_entry, its values could change inappropriately and unexpectedly. The solution to this is to eagerly copy the underlying C values into the Python structure and move on.Additionally,
git_config_entry_freeshould never be used for iterated entries. Freeing the iterator automatically frees any entries it allocated, and manually freeing the entry can cause a crash.git_config_entry_freeshould be called only for entries retrieved without an iterator.This pull request, which is a subset of the changes initially proposed in #1473, fixes this memory misuse by refactoring
ConfigEntryand its related iterators.