]> TLD Linux GIT Repositories - packages/mc.git/blob - mc-search-segv.patch
- fix segmentation faults in search functions
[packages/mc.git] / mc-search-segv.patch
1 diff --git a/lib/search/regex.c b/lib/search/regex.c
2 index f6eb24e..53e3b6f 100644
3 --- a/lib/search/regex.c
4 +++ b/lib/search/regex.c
5 @@ -249,6 +249,60 @@ mc_search__cond_struct_new_regex_ci_str (const char *charset, const GString * as
6  
7  /* --------------------------------------------------------------------------------------------- */
8  
9 +#ifdef SEARCH_TYPE_GLIB
10 +/* Glib doesn't like invalid UTF-8 so sanitize it first: ticket 3449.
11 + * Be careful: there might be embedded NULs in the strings. */
12 +static gboolean
13 +mc_search__g_regex_match_full_safe (const GRegex * regex,
14 +                                    const gchar * string,
15 +                                    gssize string_len,
16 +                                    gint start_position,
17 +                                    GRegexMatchFlags match_options,
18 +                                    GMatchInfo ** match_info, GError ** error)
19 +{
20 +    char *string_safe, *p, *end;
21 +    gboolean ret;
22 +
23 +    if ((g_regex_get_compile_flags (regex) & G_REGEX_RAW)
24 +        || g_utf8_validate (string, string_len, NULL))
25 +    {
26 +        return g_regex_match_full (regex, string, string_len, start_position, match_options,
27 +                                   match_info, error);
28 +    }
29 +
30 +    if (string_len < 0)
31 +    {
32 +        string_len = strlen (string);
33 +    }
34 +    p = string_safe = g_strndup (string, string_len);
35 +    end = p + string_len;
36 +
37 +    while (p < end)
38 +    {
39 +        gunichar c = g_utf8_get_char_validated (p, -1);
40 +        if (c != (gunichar) (-1) && c != (gunichar) (-2))
41 +        {
42 +            p = g_utf8_next_char (p);
43 +        }
44 +        else
45 +        {
46 +            /* U+FFFD would be the proper choice, but then we'd have to
47 +               maintain mapping between old and new offsets.
48 +               So rather do a byte by byte replacement. */
49 +            *p++ = '\0';
50 +        }
51 +    }
52 +
53 +    ret =
54 +        g_regex_match_full (regex, string_safe, string_len, start_position, match_options,
55 +                            match_info, error);
56 +    g_free (string_safe);
57 +    return ret;
58 +}
59 +#endif /* SEARCH_TYPE_GLIB */
60 +
61 +/* --------------------------------------------------------------------------------------------- */
62 +
63  static mc_search__found_cond_t
64  mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * regex,
65                                   GString * search_str)
66 @@ -256,8 +310,9 @@ mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t *
67  #ifdef SEARCH_TYPE_GLIB
68      GError *mcerror = NULL;
69  
70 -    if (!g_regex_match_full (regex, search_str->str, search_str->len, 0, G_REGEX_MATCH_NEWLINE_ANY,
71 -                             &lc_mc_search->regex_match_info, &mcerror))
72 +    if (!mc_search__g_regex_match_full_safe
73 +        (regex, search_str->str, search_str->len, 0, G_REGEX_MATCH_NEWLINE_ANY,
74 +         &lc_mc_search->regex_match_info, &mcerror))
75      {
76          g_match_info_free (lc_mc_search->regex_match_info);
77          lc_mc_search->regex_match_info = NULL;