diff options
Diffstat (limited to 'dev-libs/glib/files/GMarkup-fix-optimization-regression.patch')
-rw-r--r-- | dev-libs/glib/files/GMarkup-fix-optimization-regression.patch | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/dev-libs/glib/files/GMarkup-fix-optimization-regression.patch b/dev-libs/glib/files/GMarkup-fix-optimization-regression.patch new file mode 100644 index 0000000..2f5b7b2 --- /dev/null +++ b/dev-libs/glib/files/GMarkup-fix-optimization-regression.patch @@ -0,0 +1,108 @@ +From 059ec81c9e88ee5ec67aafd135714754ea5b9552 Mon Sep 17 00:00:00 2001 +From: Michael Meeks <michael.meeks@novell.com> +Date: Tue, 9 Jun 2009 11:31:42 +0100 +Subject: [PATCH] move start_element emission out into a new (inlined) function, so + the alloca'd memory is released on return, rather than slowly blowing + the stack. + +--- + glib/gmarkup.c | 76 +++++++++++++++++++++++++++++++------------------------- + 1 files changed, 42 insertions(+), 34 deletions(-) + +diff --git a/glib/gmarkup.c b/glib/gmarkup.c +index 35118ad..bb8165b 100644 +--- a/glib/gmarkup.c ++++ b/glib/gmarkup.c +@@ -891,6 +891,47 @@ clear_attributes (GMarkupParseContext *context) + g_assert (context->attr_values == NULL || + context->attr_values[0] == NULL); + } ++ ++/* This has to be a separate function to ensure the alloca's ++ are unwound on exit - otherwise we grow & blow the stack ++ with large documents */ ++static inline void ++emit_start_element (GMarkupParseContext *context, GError **error) ++{ ++ int i; ++ const gchar *start_name; ++ const gchar **attr_names; ++ const gchar **attr_values; ++ GError *tmp_error; ++ ++ attr_names = g_newa (const gchar *, context->cur_attr + 2); ++ attr_values = g_newa (const gchar *, context->cur_attr + 2); ++ for (i = 0; i < context->cur_attr + 1; i++) ++ { ++ attr_names[i] = context->attr_names[i]->str; ++ attr_values[i] = context->attr_values[i]->str; ++ } ++ attr_names[i] = NULL; ++ attr_values[i] = NULL; ++ ++ /* Call user callback for element start */ ++ tmp_error = NULL; ++ start_name = current_element (context); ++ ++ if (context->parser->start_element && ++ name_validate (context, start_name, error)) ++ (* context->parser->start_element) (context, ++ start_name, ++ (const gchar **)attr_names, ++ (const gchar **)attr_values, ++ context->user_data, ++ &tmp_error); ++ clear_attributes (context); ++ ++ if (tmp_error != NULL) ++ propagate_error (context, error, tmp_error); ++} ++ + /** + * g_markup_parse_context_parse: + * @context: a #GMarkupParseContext +@@ -1217,40 +1258,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, + */ + if (context->state == STATE_AFTER_ELISION_SLASH || + context->state == STATE_AFTER_CLOSE_ANGLE) +- { +- int i; +- const gchar *start_name; +- const gchar **attr_names; +- const gchar **attr_values; +- GError *tmp_error; +- +- attr_names = g_newa (const gchar *, context->cur_attr + 2); +- attr_values = g_newa (const gchar *, context->cur_attr + 2); +- for (i = 0; i < context->cur_attr + 1; i++) +- { +- attr_names[i] = context->attr_names[i]->str; +- attr_values[i] = context->attr_values[i]->str; +- } +- attr_names[i] = NULL; +- attr_values[i] = NULL; +- +- /* Call user callback for element start */ +- tmp_error = NULL; +- start_name = current_element (context); +- +- if (context->parser->start_element && +- name_validate (context, start_name, error)) +- (* context->parser->start_element) (context, +- start_name, +- (const gchar **)attr_names, +- (const gchar **)attr_values, +- context->user_data, +- &tmp_error); +- clear_attributes (context); +- +- if (tmp_error != NULL) +- propagate_error (context, error, tmp_error); +- } ++ emit_start_element (context, error); + } + break; + +-- +1.6.1.3 + |