Fix segfault in StoreAddressSearchMatch on GMime 3
Passing NULL for "use default options" to internet_address_list_parse() and internet_address_list_to_string() relies on GMime's parser/format options singleton accessors (g_mime_parser_options_get_default(), g_mime_format_options_get_default()) always returning a valid object. At least the GMime 3.2.15 build shipped on Debian Trixie has a broken singleton that returns NULL instead, and the parser/formatter then dereferences that NULL unconditionally rather than falling back to safe defaults -- a reliable segfault on any input, not just malformed ones. Reproduced live in a Debian Trixie container (gdb backtrace through g_mime_parser_options_get_warning_callback() and g_mime_format_options_get_newline()), fixed by allocating our own short-lived options objects instead of relying on NULL, and confirmed against both the real store-address-search CTest under GMime 3.2.15 in that container and the full local suite under GMime 2.6.23. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,15 +57,31 @@ StoreAddressSearchMatch(const char *header_value, const char *substring)
|
||||
if (*substring == '\0') return TRUE;
|
||||
|
||||
#if GMIME_MAJOR_VERSION >= 3
|
||||
addresses = internet_address_list_parse(NULL, header_value);
|
||||
/* Do not pass NULL for "use default options": at least some packaged
|
||||
* GMime 3 builds (observed with GMime 3.2.15 on Debian Trixie) have a
|
||||
* broken g_mime_parser_options_get_default()/g_mime_format_options_
|
||||
* get_default() singleton that returns NULL instead of a real default
|
||||
* object, and the parser/formatter then dereferences that NULL
|
||||
* unconditionally instead of falling back to safe defaults -- a
|
||||
* reliable segfault on any input, confirmed live in a Debian Trixie
|
||||
* container. Allocate our own options objects instead. */
|
||||
{
|
||||
GMimeParserOptions *parser_options = g_mime_parser_options_new();
|
||||
GMimeFormatOptions *format_options = g_mime_format_options_new();
|
||||
addresses = internet_address_list_parse(parser_options, header_value);
|
||||
if (!addresses) {
|
||||
g_mime_parser_options_free(parser_options);
|
||||
g_mime_format_options_free(format_options);
|
||||
return Utf8ContainsCasefolded(header_value, substring);
|
||||
}
|
||||
normalized = internet_address_list_to_string(addresses, format_options, FALSE);
|
||||
g_mime_parser_options_free(parser_options);
|
||||
g_mime_format_options_free(format_options);
|
||||
}
|
||||
#else
|
||||
addresses = internet_address_list_parse_string(header_value);
|
||||
#endif
|
||||
if (!addresses)
|
||||
return Utf8ContainsCasefolded(header_value, substring);
|
||||
#if GMIME_MAJOR_VERSION >= 3
|
||||
normalized = internet_address_list_to_string(addresses, NULL, FALSE);
|
||||
#else
|
||||
normalized = internet_address_list_to_string(addresses, FALSE);
|
||||
#endif
|
||||
found = Utf8ContainsCasefolded(normalized, substring);
|
||||
|
||||
Reference in New Issue
Block a user