[librsvg: 3/7] Make rsvg_css_parse_number_list() correspond to the Rust version
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/7] Make rsvg_css_parse_number_list() correspond to the Rust version
- Date: Thu, 22 Jun 2017 18:25:40 +0000 (UTC)
commit 78bb1392d3b45ca7ace11aa5de097e4c4d8dd446
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Jun 20 09:25:48 2017 -0500
Make rsvg_css_parse_number_list() correspond to the Rust version
And start turning the callers into using the new API.
Also, this actually makes feConvolveMatrix be rendered. Apparently they
weren't working at all before?
rsvg-css.c | 25 +++++++++++++------
rsvg-css.h | 14 ++++++++++-
rsvg-filter.c | 72 +++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 87 insertions(+), 24 deletions(-)
---
diff --git a/rsvg-css.c b/rsvg-css.c
index 199792a..a75bfa7 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -318,20 +318,28 @@ rsvg_css_parse_list (const char *in_str, guint * out_list_len)
return string_array;
}
-gdouble *
-rsvg_css_parse_number_list (const char *in_str, guint * out_list_len)
+gboolean
+rsvg_css_parse_number_list (const char *in_str,
+ NumberListLength nlength,
+ gsize size,
+ gdouble **out_list,
+ gsize *out_list_len)
{
gchar **string_array;
gdouble *output;
guint len, i;
- if (out_list_len)
- *out_list_len = 0;
+ *out_list = NULL;
+ *out_list_len = 0;
string_array = rsvg_css_parse_list (in_str, &len);
if (!(string_array && len))
- return NULL;
+ return FALSE;
+
+ if ((nlength == NUMBER_LIST_LENGTH_EXACT && (gsize) len != size)
+ || (nlength == NUMBER_LIST_LENGTH_MAXIMUM && (gsize) len > size))
+ return FALSE;
output = g_new0 (gdouble, len);
@@ -341,10 +349,11 @@ rsvg_css_parse_number_list (const char *in_str, guint * out_list_len)
g_strfreev (string_array);
- if (out_list_len != NULL)
- *out_list_len = len;
+ *out_list_len = len;
+
+ *out_list = output;
- return output;
+ return TRUE;
}
gboolean
diff --git a/rsvg-css.h b/rsvg-css.h
index 353bc11..4efbde6 100644
--- a/rsvg-css.h
+++ b/rsvg-css.h
@@ -133,8 +133,20 @@ gboolean rsvg_css_parse_number_optional_number (const char *str, double *out_x,
G_GNUC_INTERNAL
gchar **rsvg_css_parse_list (const char *in_str, guint * out_list_len);
+
+/* Keep in sync with rust/src/parsers.rs:NumberListLength */
+typedef enum {
+ NUMBER_LIST_LENGTH_EXACT,
+ NUMBER_LIST_LENGTH_MAXIMUM
+} NumberListLength;
+
G_GNUC_INTERNAL
-gdouble *rsvg_css_parse_number_list (const char *in_str, guint * out_list_len);
+gboolean rsvg_css_parse_number_list (const char *in_str,
+ NumberListLength nlength,
+ gsize size,
+ gdouble **out_list,
+ gsize *out_list_len);
+
G_GNUC_INTERNAL
gboolean rsvg_css_parse_overflow (const char *str, gboolean * inherit);
G_GNUC_INTERNAL
diff --git a/rsvg-filter.c b/rsvg-filter.c
index aea801f..1729eca 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -1247,7 +1247,6 @@ rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, R
{
RsvgFilterPrimitiveConvolveMatrix *filter = impl;
gint i, j;
- guint listlen = 0;
const char *value;
gboolean has_target_x, has_target_y;
@@ -1279,16 +1278,29 @@ rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, R
}
if ((value = rsvg_property_bag_lookup (atts, "divisor")))
filter->divisor = atof (value);
+
if ((value = rsvg_property_bag_lookup (atts, "order"))) {
double tempx, tempy;
- if (rsvg_css_parse_number_optional_number (value, &tempx, &tempy)) {
- filter->orderx = MAX (tempx, G_MAXINT);
- filter->ordery = MAX (tempy, G_MAXINT);
+ if (rsvg_css_parse_number_optional_number (value, &tempx, &tempy)
+ && tempx >= 1.0 && tempy <= 100.0
+ && tempy >= 1.0 && tempy <= 100.0) {
+ filter->orderx = (int) tempx;
+ filter->ordery = (int) tempy;
+ g_assert (filter->orderx >= 1);
+ g_assert (filter->ordery >= 1);
+
+#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
+
+ if (SIZE_OVERFLOWS (filter->orderx, filter->ordery)) {
+ rsvg_node_set_attribute_parse_error (node, "order", "number of kernelMatrix elements would
be too big");
+ return;
+ }
} else {
- rsvg_node_set_attribute_parse_error (node, "order", "expected number-optional-number");
+ rsvg_node_set_attribute_parse_error (node, "order", "invalid size for convolve matrix");
return;
}
}
+
if ((value = rsvg_property_bag_lookup (atts, "kernelUnitLength"))) {
if (!rsvg_css_parse_number_optional_number (value, &filter->dx, &filter->dy)) {
rsvg_node_set_attribute_parse_error (node, "kernelUnitLength", "expected
number-optional-number");
@@ -1296,8 +1308,23 @@ rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, R
}
}
- if ((value = rsvg_property_bag_lookup (atts, "kernelMatrix")))
- filter->KernelMatrix = rsvg_css_parse_number_list (value, &listlen);
+ if ((value = rsvg_property_bag_lookup (atts, "kernelMatrix"))) {
+ gsize num_elems;
+ gsize got_num_elems;
+
+ num_elems = filter->orderx * filter->ordery;
+
+ if (!rsvg_css_parse_number_list (value,
+ NUMBER_LIST_LENGTH_EXACT,
+ num_elems,
+ &filter->KernelMatrix,
+ &got_num_elems)) {
+ rsvg_node_set_attribute_parse_error (node, "kernelMatrix", "expected a matrix of numbers");
+ return;
+ }
+
+ g_assert (num_elems == got_num_elems);
+ }
if ((value = rsvg_property_bag_lookup (atts, "edgeMode"))) {
if (!strcmp (value, "wrap"))
@@ -1308,9 +1335,6 @@ rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, R
filter->edgemode = 0;
}
- if ((gint64) listlen != (gint64) filter->orderx * filter->ordery)
- filter->orderx = filter->ordery = 0;
-
if (filter->divisor == 0) {
for (j = 0; j < filter->orderx; j++)
for (i = 0; i < filter->ordery; i++)
@@ -2374,7 +2398,7 @@ rsvg_filter_primitive_color_matrix_set_atts (RsvgNode *node, gpointer impl, Rsvg
{
RsvgFilterPrimitiveColorMatrix *filter = impl;
gint type;
- guint listlen = 0;
+ gsize listlen = 0;
const char *value;
type = 0;
@@ -2388,7 +2412,16 @@ rsvg_filter_primitive_color_matrix_set_atts (RsvgNode *node, gpointer impl, Rsvg
if ((value = rsvg_property_bag_lookup (atts, "values"))) {
unsigned int i;
- double *temp = rsvg_css_parse_number_list (value, &listlen);
+ double *temp;
+ if (!rsvg_css_parse_number_list (value,
+ NUMBER_LIST_LENGTH_MAXIMUM,
+ 20,
+ &temp,
+ &listlen)) {
+ rsvg_node_set_attribute_parse_error (node, "values", "invalid number list");
+ return;
+ }
+
filter->KernelMatrix = g_new0 (int, listlen);
for (i = 0; i < listlen; i++)
filter->KernelMatrix[i] = temp[i] * 255.;
@@ -2504,7 +2537,7 @@ typedef struct _RsvgFilterPrimitiveComponentTransfer
struct _RsvgNodeComponentTransferFunc {
ComponentTransferFunc function;
gint *tableValues;
- guint nbTableValues;
+ gsize nbTableValues;
gint slope;
gint intercept;
gint amplitude;
@@ -2747,10 +2780,19 @@ rsvg_node_component_transfer_function_set_atts (RsvgNode *node, gpointer impl, R
else if (!strcmp (value, "gamma"))
data->function = gamma_component_transfer_func;
}
+
if ((value = rsvg_property_bag_lookup (atts, "tableValues"))) {
unsigned int i;
- double *temp = rsvg_css_parse_number_list (value,
- &data->nbTableValues);
+ double *temp;
+ if (!rsvg_css_parse_number_list (value,
+ NUMBER_LIST_LENGTH_MAXIMUM,
+ 256,
+ &temp,
+ &data->nbTableValues)) {
+ rsvg_node_set_attribute_parse_error (node, "tableValues", "invalid number list");
+ return;
+ }
+
data->tableValues = g_new0 (gint, data->nbTableValues);
for (i = 0; i < data->nbTableValues; i++)
data->tableValues[i] = temp[i] * 255.;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]