Functions sometimes take ownership over the objects passed in by reference (pointer).
For example, synctex_scanner_get_tag would destroy the scanner via synctex_scanner_parse which itself takes a scanner and destroys it on failure. There is a code path which theoretically may return 0 (failure code) but won't destroy the scanner. So it is impossible for a caller to tell whether scanner has been destroyed or not. Nothing in the description of the function implies the ownership.
Similarly, function synctex_iterator_new_display calls into synctex_scanner_get_tag, so it may as well destroy the scanner, and again nothing in its description mentions this possibility. The code inside synctex itself of course does not account for it either:
synctex_status_t synctex_display_query(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint)
{
if (scanner) {
synctex_iterator_free(scanner->iterator);
scanner->iterator = synctex_iterator_new_display(scanner, name, line, column, page_hint);
return synctex_iterator_count(scanner->iterator);
}
return SYNCTEX_STATUS_ERROR;
}
it should somehow check for the result of synctex_iterator_new_display but it doesn't, and just accesses a potentially freed memory scanner->iterator. Why does this code even need to assign to scanner->iterator externally (outside of synctex_iterator_new_display) is a whole different question.
This list goes on and on...
Functions sometimes take ownership over the objects passed in by reference (pointer).
For example,
synctex_scanner_get_tagwould destroy the scanner viasynctex_scanner_parsewhich itself takes a scanner and destroys it on failure. There is a code path which theoretically may return 0 (failure code) but won't destroy the scanner. So it is impossible for a caller to tell whether scanner has been destroyed or not. Nothing in the description of the function implies the ownership.Similarly, function
synctex_iterator_new_displaycalls intosynctex_scanner_get_tag, so it may as well destroy the scanner, and again nothing in its description mentions this possibility. The code inside synctex itself of course does not account for it either:it should somehow check for the result of
synctex_iterator_new_displaybut it doesn't, and just accesses a potentially freed memoryscanner->iterator. Why does this code even need to assign toscanner->iteratorexternally (outside ofsynctex_iterator_new_display) is a whole different question.This list goes on and on...