diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 66ae587c12d0000e2c4a45cf0bf983dbfb7eb4ca..698c5a46b850904b3c58c5507dec34f7c11b9a1c 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -243,54 +243,75 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt if (end_ptr) { *end_ptr = str + i; } - } else if (strneq(str, "rgb(", 4)) { + } else if (strneq(str, "rgb(", 4) || strneq(str, "rgba(", 5)) { bool hasp, hasd; gchar *s, *e; - gdouble r, g, b; + gdouble r, g, b, a; s = (gchar *) str + 4; + if (strneq(str, "rgba(", 5)) + s++; hasp = false; hasd = false; - r = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; +#define read_double(x) \ + do { \ + x = g_ascii_strtod(s, &e); \ + if (s == e) \ + return def; \ + s = e; \ + } while (0) + +#define read_double_or_percentage(x) \ + do { \ + read_double(x); \ + if (*s == '%') { \ + hasp = true; \ + s += 1; \ + } else { \ + hasd = true; \ + } \ + } while (0) + +#define read_spaces() \ + do { \ + while (*s && g_ascii_isspace(*s)) \ + s += 1; \ + } while (0) + +#define read_comma() \ + do { \ + read_spaces(); \ + if (*s != ',') \ + return def; \ + s += 1; \ + read_spaces(); \ + } while (0) + + read_double_or_percentage(r); + read_comma(); + read_double_or_percentage(g); + read_comma(); + read_double_or_percentage(b); + if (strneq(str, "rgba(", 5)) { + read_comma(); + read_double(a); } else { - hasd = true; + a = 1.0; } - while (*s && g_ascii_isspace(*s)) s += 1; - if (*s != ',') return def; - s += 1; - while (*s && g_ascii_isspace(*s)) s += 1; - g = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; - } else { - hasd = true; - } - while (*s && g_ascii_isspace(*s)) s += 1; - if (*s != ',') return def; - s += 1; - while (*s && g_ascii_isspace(*s)) s += 1; - b = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; - } else { - hasd = true; - } - while(*s && g_ascii_isspace(*s)) s += 1; + read_spaces(); + +#undef read_double +#undef read_double_or_percentage +#undef read_spaces +#undef read_comma + if (*s != ')') { return def; } + if (a != 1.0) { + return def; // TODO: https://gitlab.com/inkscape/inbox/-/issues/1195 + } ++s; if (hasp && hasd) return def; if (hasp) { @@ -307,7 +328,6 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt } return val; } else if (strneq(str, "hsl(", 4)) { - gchar *ptr = (gchar *) str + 4; gchar *e; // ptr after read diff --git a/testfiles/src/svg-color-test.cpp b/testfiles/src/svg-color-test.cpp index c4e937928d652785b51d4853851bc0598e429812..af9f756e6d1ef91b188223ddf44f69923b7f9fdd 100644 --- a/testfiles/src/svg-color-test.cpp +++ b/testfiles/src/svg-color-test.cpp @@ -54,7 +54,7 @@ TEST(SvgColorTest, testWrite) TEST(SvgColorTest, testReadColor) { - gchar const *val[] = {"#f0f", "#ff00ff", "rgb(255,0,255)", "fuchsia"}; + gchar const *val[] = {"#f0f", "#ff00ff", "rgb(255,0,255)", "rgba(255,0,255,1)", "fuchsia"}; size_t const n = sizeof(val) / sizeof(*val); for (size_t i = 0; i < n; i++) { gchar const *end = 0;