From f8beeeb76fbc5e83ebbecccc6fc5aed10a6b4978 Mon Sep 17 00:00:00 2001 From: mental Date: Wed, 28 Feb 2007 04:34:21 +0000 Subject: [PATCH] refactor sp_svg_transform_write to return a dynamically-allocated string -- dynamic allocation won't hurt you, but buffer overruns will! --- src/dialogs/clonetiler.cpp | 9 +++------ src/flood-context.cpp | 9 +++------ src/gradient-chemistry.cpp | 36 +++++++++++---------------------- src/selection-chemistry.cpp | 25 +++++++++-------------- src/sp-gradient.cpp | 9 +++------ src/sp-item-group.cpp | 9 +++------ src/sp-item.cpp | 9 +++------ src/sp-pattern.cpp | 19 ++++++------------ src/splivarot.cpp | 8 +++----- src/svg/svg-affine.cpp | 40 ++++++++++++++----------------------- src/svg/svg.h | 4 ++-- 11 files changed, 62 insertions(+), 115 deletions(-) diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index 130480608..3e01a7498 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -1286,12 +1286,9 @@ clonetiler_apply (GtkWidget *widget, void *) center_set = true; } - gchar affinestr[80]; - if (sp_svg_transform_write(affinestr, 79, t)) { - clone->setAttribute("transform", affinestr); - } else { - clone->setAttribute("transform", NULL); - } + gchar *affinestr=sp_svg_transform_write(t); + clone->setAttribute("transform", affinestr); + g_free(affinestr); if (opacity < 1.0) { sp_repr_set_css_double(clone, "opacity", opacity); diff --git a/src/flood-context.cpp b/src/flood-context.cpp index 896d4d29f..a6a66e952 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -347,12 +347,9 @@ static void do_trace(GdkPixbuf *px, SPDesktop *desktop, NR::Matrix transform) { sp_svg_transform_read(t_str, &item_t); item_t *= local.inverse(); // (we're dealing with unattached repr, so we write to its attr instead of using sp_item_set_transform) - gchar affinestr[80]; - if (sp_svg_transform_write(affinestr, 79, item_t)) { - pathRepr->setAttribute("transform", affinestr); - } else { - pathRepr->setAttribute("transform", NULL); - } + gchar *affinestr=sp_svg_transform_write(item_t); + pathRepr->setAttribute("transform", affinestr); + g_free(affinestr); } Inkscape::Selection *selection = sp_desktop_selection(desktop); diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 78ea13507..f55694fcf 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -280,12 +280,9 @@ sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item) gr->gradientTransform = squeeze; { - gchar c[256]; - if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { - SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); - } else { - SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", NULL); - } + gchar *c=sp_svg_transform_write(gr->gradientTransform); + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); + g_free(c); } } else { sp_repr_set_svg_double(repr, "x1", (center - NR::Point(width/2, 0))[NR::X]); @@ -350,12 +347,9 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop // apply skew to the gradient gr->gradientTransform = skew; { - gchar c[256]; - if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { - SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); - } else { - SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", NULL); - } + gchar *c=sp_svg_transform_write(gr->gradientTransform); + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); + g_free(c); } // Matrix to convert points to userspace coords; postmultiply by inverse of skew so @@ -423,12 +417,9 @@ sp_gradient_transform_multiply(SPGradient *gradient, NR::Matrix postmul, bool se } gradient->gradientTransform_set = TRUE; - gchar c[256]; - if (sp_svg_transform_write(c, 256, gradient->gradientTransform)) { - SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", c); - } else { - SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", NULL); - } + gchar *c=sp_svg_transform_write(gradient->gradientTransform); + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", c); + g_free(c); } SPGradient * @@ -925,12 +916,9 @@ sp_item_gradient_set_coords (SPItem *item, guint point_type, guint point_i, NR:: gradient->gradientTransform = new_transform; gradient->gradientTransform_set = TRUE; if (write_repr) { - gchar s[256]; - if (sp_svg_transform_write(s, 256, gradient->gradientTransform)) { - SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", s); - } else { - SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", NULL); - } + gchar *s=sp_svg_transform_write(gradient->gradientTransform); + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", s); + g_free(s); } else { SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index d3fff18e9..1885ca6eb 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -101,12 +101,9 @@ void sp_selection_copy_one (Inkscape::XML::Node *repr, NR::Matrix full_t, GSList // write the complete accumulated transform passed to us // (we're dealing with unattached repr, so we write to its attr // instead of using sp_item_set_transform) - gchar affinestr[80]; - if (sp_svg_transform_write(affinestr, 79, full_t)) { - copy->setAttribute("transform", affinestr); - } else { - copy->setAttribute("transform", NULL); - } + gchar *affinestr=sp_svg_transform_write(full_t); + copy->setAttribute("transform", affinestr); + g_free(affinestr); *clip = g_slist_prepend(*clip, copy); } @@ -185,12 +182,9 @@ GSList *sp_selection_paste_impl (SPDocument *document, SPObject *parent, GSList sp_svg_transform_read(t_str, &item_t); item_t *= local.inverse(); // (we're dealing with unattached repr, so we write to its attr instead of using sp_item_set_transform) - gchar affinestr[80]; - if (sp_svg_transform_write(affinestr, 79, item_t)) { - copy->setAttribute("transform", affinestr); - } else { - copy->setAttribute("transform", NULL); - } + gchar *affinestr=sp_svg_transform_write(item_t); + copy->setAttribute("transform", affinestr); + g_free(affinestr); } parent->appendChildRepr(copy); @@ -2549,10 +2543,9 @@ sp_selection_create_bitmap_copy () } // Write transform - gchar c[256]; - if (sp_svg_transform_write(c, 256, t)) { - repr->setAttribute("transform", c); - } + gchar *c=sp_svg_transform_write(t); + repr->setAttribute("transform", c); + g_free(t); // add the new repr to the parent parent->appendChild(repr); diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 71dc0e20e..94e6ce6c2 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -661,12 +661,9 @@ sp_gradient_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) } if ((flags & SP_OBJECT_WRITE_ALL) || gr->gradientTransform_set) { - gchar c[256]; - if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { - repr->setAttribute("gradientTransform", c); - } else { - repr->setAttribute("gradientTransform", NULL); - } + gchar *c=sp_svg_transform_write(gr->gradientTransform); + repr->setAttribute("gradientTransform", c); + g_free(c); } if ((flags & SP_OBJECT_WRITE_ALL) || gr->spread_set) { diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index bb94425c5..91afd8db1 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -387,12 +387,9 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // This is just a way to temporarily remember the transform in repr. When repr is // reattached outside of the group, the transform will be written more properly // (i.e. optimized into the object if the corresponding preference is set) - gchar affinestr[80]; - if (sp_svg_transform_write(affinestr, 79, ctrans)) { - nrepr->setAttribute("transform", affinestr); - } else { - nrepr->setAttribute("transform", NULL); - } + gchar *affinestr=sp_svg_transform_write(ctrans); + nrepr->setAttribute("transform", affinestr); + g_free(affinestr); items = g_slist_prepend (items, nrepr); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index cefa7f82a..6893c752b 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -634,12 +634,9 @@ sp_item_write(SPObject *const object, Inkscape::XML::Node *repr, guint flags) { SPItem *item = SP_ITEM(object); - gchar c[256]; - if (sp_svg_transform_write(c, 256, item->transform)) { - repr->setAttribute("transform", c); - } else { - repr->setAttribute("transform", NULL); - } + gchar *c = sp_svg_transform_write(item->transform); + repr->setAttribute("transform", c); + g_free(c); SPObject const *const parent = SP_OBJECT_PARENT(object); /** \todo Can someone please document why this is conditional on having diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 8de8ac77b..3640a6768 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -484,12 +484,9 @@ sp_pattern_transform_multiply (SPPattern *pattern, NR::Matrix postmul, bool set) } pattern->patternTransform_set = TRUE; - gchar c[256]; - if (sp_svg_transform_write(c, 256, pattern->patternTransform)) { - SP_OBJECT_REPR(pattern)->setAttribute("patternTransform", c); - } else { - SP_OBJECT_REPR(pattern)->setAttribute("patternTransform", NULL); - } + gchar *c=sp_svg_transform_write(pattern->patternTransform); + SP_OBJECT_REPR(pattern)->setAttribute("patternTransform", c); + g_free(c); } const gchar * @@ -503,13 +500,9 @@ pattern_tile (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix t sp_repr_set_svg_double(repr, "width", bounds.extent(NR::X)); sp_repr_set_svg_double(repr, "height", bounds.extent(NR::Y)); - gchar t[256]; - if (sp_svg_transform_write(t, 256, transform)) { - repr->setAttribute("patternTransform", t); - } else { - repr->setAttribute("patternTransform", NULL); - } - + gchar *t=sp_svg_transform_write(transform); + repr->setAttribute("patternTransform", t); + g_free(t); defsrepr->appendChild(repr); const gchar *pat_id = repr->attribute("id"); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index a23d6da02..e5154c130 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -474,11 +474,7 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin // premultiply by the inverse of parent's repr SPItem *parent_item = SP_ITEM(sp_desktop_document(desktop)->getObjectByRepr(parent)); NR::Matrix local = sp_item_i2doc_affine(parent_item); - gchar affinestr[80]; - gchar *transform = NULL; - if (!local.test_identity() && sp_svg_transform_write(affinestr, 79, local.inverse())) { - transform = affinestr; - } + gchar *transform = sp_svg_transform_write(local); // now that we have the result, add it on the canvas if ( bop == bool_op_cut || bop == bool_op_slice ) { @@ -575,6 +571,8 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin Inkscape::GC::release(repr); } + g_free(transform); + sp_document_done(sp_desktop_document(desktop), verb, description); delete res; diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index 6565b9353..71ee5dcb5 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -157,21 +157,20 @@ sp_svg_transform_read(gchar const *str, NR::Matrix *transform) #define EQ(a,b) (fabs ((a) - (b)) < 1e-9) -unsigned -sp_svg_transform_write(gchar str[], unsigned const size, NR::Matrix const &transform) +gchar * +sp_svg_transform_write(NR::Matrix const &transform) { NRMatrix const t(transform); - return sp_svg_transform_write(str, size, &t); + return sp_svg_transform_write(&t); } -unsigned -sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transform) +gchar * +sp_svg_transform_write(NRMatrix const *transform) { double e; if (!transform) { - *str = 0; - return 0; + return NULL; } e = 0.000001 * NR_MATRIX_DF_EXPANSION (transform); @@ -183,8 +182,7 @@ sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transfo if (NR_DF_TEST_CLOSE (transform->c[4], 0.0, e) && NR_DF_TEST_CLOSE (transform->c[5], 0.0, e)) { if (NR_DF_TEST_CLOSE (transform->c[0], 1.0, e) && NR_DF_TEST_CLOSE (transform->c[3], 1.0, e)) { /* We are more or less identity */ - *str = 0; - return 0; + return NULL; } else { /* We are more or less scale */ gchar c[256]; @@ -195,11 +193,9 @@ sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transfo c[p++] = ','; p += sp_svg_number_write_de (c + p, transform->c[3], prec, min_exp, FALSE); c[p++] = ')'; + c[p] = '\000'; g_assert( p <= sizeof(c) ); - p = MIN (p, size - 1 ); - memcpy (str, c, p); - str[p] = 0; - return p; + return g_strdup(c); } } else { if (NR_DF_TEST_CLOSE (transform->c[0], 1.0, e) && NR_DF_TEST_CLOSE (transform->c[3], 1.0, e)) { @@ -212,11 +208,9 @@ sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transfo c[p++] = ','; p += sp_svg_number_write_de (c + p, transform->c[5], prec, min_exp, FALSE); c[p++] = ')'; + c[p] = '\000'; g_assert( p <= sizeof(c) ); - p = MIN(p, size - 1); - memcpy (str, c, p); - str[p] = 0; - return p; + return g_strdup(c); } else { gchar c[256]; unsigned p = 0; @@ -234,11 +228,9 @@ sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transfo c[p++] = ','; p += sp_svg_number_write_de (c + p, transform->c[5], prec, min_exp, FALSE); c[p++] = ')'; + c[p] = '\000'; g_assert( p <= sizeof(c) ); - p = MIN(p, size - 1); - memcpy (str, c, p); - str[p] = 0; - return p; + return g_strdup(c); } } } else { @@ -258,11 +250,9 @@ sp_svg_transform_write(gchar str[], unsigned const size, NRMatrix const *transfo c[p++] = ','; p += sp_svg_number_write_de (c + p, transform->c[5], prec, min_exp, FALSE); c[p++] = ')'; + c[p] = '\000'; g_assert( p <= sizeof(c) ); - p = MIN(p, size - 1); - memcpy (str, c, p); - str[p] = 0; - return p; + return g_strdup(c); } } diff --git a/src/svg/svg.h b/src/svg/svg.h index b60777381..60b44f8e8 100644 --- a/src/svg/svg.h +++ b/src/svg/svg.h @@ -57,8 +57,8 @@ std::string sp_svg_length_write_with_units(SVGLength const &length); bool sp_svg_transform_read(gchar const *str, NR::Matrix *transform); -unsigned sp_svg_transform_write(gchar str[], unsigned size, NR::Matrix const &transform); -unsigned sp_svg_transform_write(gchar str[], unsigned size, NRMatrix const *transform); +gchar *sp_svg_transform_write(NR::Matrix const &transform); +gchar *sp_svg_transform_write(NRMatrix const *transform); double sp_svg_read_percentage (const char * str, double def); -- 2.30.2