Fixes memory leak on every node accessor - #38
Merged
Conversation
redvers
force-pushed
the
fix/raw-xmlchar-leaks
branch
from
May 22, 2026 05:19
be2c393 to
de28dc4
Compare
libxml2 has functions that return const xmlChar* / const char* / const unsigned char* and must not be freed by the caller. Freeing them either corrupts a libxml2-owned buffer (xmlBufferContent, xmlOutputBufferGetContent) or attempts to free a pointer into the caller's input string (xmlStrchr, xmlSplitQName3) or a parser-owned name table (xmlParseName, xmlTextReaderConst*). Authoritative source: meta/libxml2.xml (the castxml output) records the C-level return type of every function. Pointer types `_2682`, `_2695`, `_2696` are `const char*`, `const xmlChar*`, `const unsigned char*` respectively. 53 libxml2 functions return one of these; 42 of them are wrapped through this generator (the remaining 11 are ICU symbols ucnv_* / u_errorName_74 which the Pony binding does not wrap). Mechanism --------- Two typedefs in usetypes.xml: `String` emits an Xml2Free call after the clone; `String val` does not. use.xml's per-function `rv` attribute selects which typedef applies. castxml2pony emits rv="String" for every xmlChar*-returning function regardless of const-ness; the 42 const-returning entries are rewritten to rv="String val". Changes ------- meta/Makefile: castxml2pony_uses gains a sed loop over a CONST_RETURN_FNS variable that marks each const-returning entry's <use> as rv="String val". The list lives in the Makefile so the conversion replays on any future full regen from castxml output. meta/uses/use.xml: 41 <use> entries rewritten to rv="String val" (xmlBufferContent was already done). meta/functions.pony, meta/uses.pony, libxml2/raw/functions.pony, libxml2/raw/uses.pony: regen output. The 40 newly exempted wrappers now return `String val` and skip the free. Tests ----- None of the newly exempted functions are called from the in-scope Pony API. All 63 existing tests pass; stability confirmed across 4 consecutive runs. TestRepeatedCstringAccessors continues to exercise xmlBufferContent through nodeDump. If a future PR wraps any of the now-exempted functions, the Pony API call site receives `String val` instead of `String`. That is the correct shape for borrowed-from-libxml2 strings; it does not break any existing caller.
redvers
force-pushed
the
fix/raw-xmlchar-leaks
branch
from
May 22, 2026 06:32
d38fda1 to
504a823
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
libxml2 has functions that return const xmlChar* / const char* /
const unsigned char* and must not be freed by the caller. Freeing
them either corrupts a libxml2-owned buffer (xmlBufferContent,
xmlOutputBufferGetContent) or attempts to free a pointer into the
caller's input string (xmlStrchr, xmlSplitQName3) or a parser-owned
name table (xmlParseName, xmlTextReaderConst*).
Authoritative source: meta/libxml2.xml (the castxml output) records
the C-level return type of every function. Pointer types
_2682,_2695,_2696areconst char*,const xmlChar*,const unsigned char*respectively. 53 libxml2 functions return one ofthese; 42 of them are wrapped through this generator (the remaining
11 are ICU symbols ucnv_* / u_errorName_74 which the Pony binding
does not wrap).
Mechanism
Two typedefs in usetypes.xml:
Stringemits an Xml2Free call afterthe clone;
String valdoes not. use.xml's per-functionrvattribute selects which typedef applies. castxml2pony emits
rv="String" for every xmlChar*-returning function regardless of
const-ness; the 42 const-returning entries are rewritten to
rv="String val".
Changes
meta/Makefile: castxml2pony_uses gains a sed loop over a
CONST_RETURN_FNS variable that marks each const-returning entry's
as rv="String val". The list lives in the Makefile so the
conversion replays on any future full regen from castxml output.
meta/uses/use.xml: 41 entries rewritten to rv="String val"
(xmlBufferContent was already done).
meta/functions.pony, meta/uses.pony, libxml2/raw/functions.pony,
libxml2/raw/uses.pony: regen output. The 40 newly exempted
wrappers now return
String valand skip the free.Tests
None of the newly exempted functions are called from the in-scope
Pony API. All 63 existing tests pass; stability confirmed across 4
consecutive runs. TestRepeatedCstringAccessors continues to
exercise xmlBufferContent through nodeDump.
If a future PR wraps any of the now-exempted functions, the Pony
API call site receives
String valinstead ofString. That isthe correct shape for borrowed-from-libxml2 strings; it does not
break any existing caller.