svg-parser - unify error messages text + update unit test

This commit is contained in:
artemp 2017-08-08 12:38:24 +01:00
parent 8cdd61e846
commit 3597c585be
2 changed files with 76 additions and 63 deletions

View file

@ -169,7 +169,7 @@ void handle_unsupported(svg_parser& parser, T const& ar, char const* name)
{ {
if (e == element) if (e == element)
{ {
parser.err_handler().on_error(std::string("Unsupported:'") + name + "'"); parser.err_handler().on_error(std::string("SVG support error: <" + std::string(name) + "> element is not supported"));
} }
} }
} }
@ -208,7 +208,7 @@ mapnik::color parse_color(T & err_handler, const char* str)
} }
catch (mapnik::config_error const& ex) catch (mapnik::config_error const& ex)
{ {
err_handler.on_error(ex.what()); err_handler.on_error("SVG parse error: failed to parse <color> with value \"" + std::string(str) + "\"");
} }
return c; return c;
} }
@ -228,7 +228,7 @@ double parse_double(T & err_handler, const char* str)
double val = 0.0; double val = 0.0;
if (!parse(str, str + std::strlen(str),double_,val)) if (!parse(str, str + std::strlen(str),double_,val))
{ {
err_handler.on_error("Failed to parse double: \"" + std::string(str) + "\""); err_handler.on_error("SVG parse error: failed to parse <number> with value \"" + std::string(str) + "\"");
} }
return val; return val;
} }
@ -261,12 +261,7 @@ double parse_svg_value(T & err_handler, const char* str, bool & percent)
lit('%')[ref(val) *= 0.01][ref(percent) = true]), lit('%')[ref(val) *= 0.01][ref(percent) = true]),
skip_type())) skip_type()))
{ {
err_handler.on_error("Failed to parse SVG value: '" + std::string(str) + "'"); err_handler.on_error("SVG parse error: failed to parse <number> with value \"" + std::string(str) + "\"");
}
else if (cur != end)
{
err_handler.on_error("Failed to parse SVG value: '" + std::string(str) +
"', trailing garbage: '" + cur + "'");
} }
return val; return val;
} }
@ -286,7 +281,7 @@ bool parse_viewbox(T & err_handler, const char* str, V & viewbox)
double_ >> -lit(',') >> double_ >> -lit(',') >>
double_, skip_type(), viewbox)) double_, skip_type(), viewbox))
{ {
err_handler.on_error("failed to parse SVG viewbox from " + std::string(str)); err_handler.on_error("SVG parse error: failed to parse <viewbox> with value \"" + std::string(str) + "\"");
return false; return false;
} }
return true; return true;
@ -379,7 +374,7 @@ std::pair<unsigned,bool> parse_preserve_aspect_ratio(T & err_handler, char const
} }
catch (qi::expectation_failure<char const*> const& ex) catch (qi::expectation_failure<char const*> const& ex)
{ {
err_handler.on_error("Failed to parse \"preserveAspectRatio\" attribute: '" + std::string(str) + "'"); err_handler.on_error("SVG parse error: failed to parse <preserveAspectRatio> with value \"" + std::string(str) + "\"");
return {xMidYMid, true} ; // default return {xMidYMid, true} ; // default
} }
return preserve_aspect_ratio; return preserve_aspect_ratio;
@ -554,7 +549,7 @@ void parse_stroke(svg_parser& parser, char const* value)
} }
else if (parse_id_from_url(value, id)) else if (parse_id_from_url(value, id))
{ {
// see if we have a known gradient fill // see if we have a known gradient stroke
if (parser.gradient_map_.count(id) > 0) if (parser.gradient_map_.count(id) > 0)
{ {
parser.path_.add_stroke_gradient(parser.gradient_map_[id]); parser.path_.add_stroke_gradient(parser.gradient_map_[id]);
@ -571,14 +566,14 @@ void parse_stroke(svg_parser& parser, char const* value)
else else
{ {
std::stringstream ss; std::stringstream ss;
ss << "Failed to find gradient stroke: " << id; ss << "SVG parse error: failed to locate <gradient> stroke with <id> \"" << id << "\"";
parser.err_handler().on_error(ss.str()); parser.err_handler().on_error(ss.str());
} }
} }
else else
{ {
std::stringstream ss; std::stringstream ss;
ss << "Failed to find gradient stroke: " << id; ss << "SVG parse error: failed to locate <gradient> stroke with <id> \"" << id << "\"";
parser.err_handler().on_error(ss.str()); parser.err_handler().on_error(ss.str());
} }
} }
@ -614,14 +609,14 @@ void parse_fill(svg_parser& parser, char const* value)
else else
{ {
std::stringstream ss; std::stringstream ss;
ss << "Failed to find gradient fill: " << id; ss << "SVG parse error: failed to locate <gradient> fill with <id> \"" << id << "\"";
parser.err_handler().on_error(ss.str()); parser.err_handler().on_error(ss.str());
} }
} }
else else
{ {
std::stringstream ss; std::stringstream ss;
ss << "Failed to find gradient fill: " << id; ss << "SVG parse error: failed to locate <gradient> fill with <id> \"" << id << "\"";
parser.err_handler().on_error(ss.str()); parser.err_handler().on_error(ss.str());
} }
} }
@ -867,12 +862,12 @@ void parse_path(svg_parser & parser, rapidxml::xml_node<char> const* node)
auto const* id_attr = parse_id(parser, node); auto const* id_attr = parse_id(parser, node);
if (id_attr) if (id_attr)
{ {
parser.err_handler().on_error(std::string("unable to parse invalid svg <path> with id '") parser.err_handler().on_error(std::string("SVG parse error: failed to parse <path> with <id> \"")
+ id_attr->value() + "'"); + id_attr->value() + "\"");
} }
else else
{ {
parser.err_handler().on_error(std::string("unable to parse invalid svg <path>")); parser.err_handler().on_error(std::string("SVG parse error: failed to parse <path>"));
} }
} }
parser.path_.end_path(); parser.path_.end_path();
@ -923,11 +918,15 @@ void parse_use(svg_parser & parser, rapidxml::xml_node<char> const* node)
} }
if (w < 0.0) if (w < 0.0)
{ {
parser.err_handler().on_error("parse_use: Invalid width"); std::stringstream ss;
ss << "SVG validation error: invalid <use> width \"" << w << "\"";
parser.err_handler().on_error(ss.str());
} }
else if (h < 0.0) else if (h < 0.0)
{ {
parser.err_handler().on_error("parse_use: Invalid height"); std::stringstream ss;
ss << "SVG validation error: invalid <use> height \"" << w << "\"";
parser.err_handler().on_error(ss.str());
} }
agg::trans_affine t{}; agg::trans_affine t{};
if (!node->first_attribute("transform") && w != 0.0 && h != 0.0) if (!node->first_attribute("transform") && w != 0.0 && h != 0.0)
@ -952,7 +951,7 @@ void parse_polygon(svg_parser & parser, rapidxml::xml_node<char> const* node)
parser.path_.begin_path(); parser.path_.begin_path();
if (!mapnik::svg::parse_points(attr->value(), parser.path_)) if (!mapnik::svg::parse_points(attr->value(), parser.path_))
{ {
parser.err_handler().on_error(std::string("Failed to parse <polygon> 'points'")); parser.err_handler().on_error(std::string("SVG parse error: failed to parse <polygon> points"));
} }
parser.path_.close_subpath(); parser.path_.close_subpath();
parser.path_.end_path(); parser.path_.end_path();
@ -967,7 +966,7 @@ void parse_polyline(svg_parser & parser, rapidxml::xml_node<char> const* node)
parser.path_.begin_path(); parser.path_.begin_path();
if (!mapnik::svg::parse_points(attr->value(), parser.path_)) if (!mapnik::svg::parse_points(attr->value(), parser.path_))
{ {
parser.err_handler().on_error(std::string("Failed to parse <polyline> 'points'")); parser.err_handler().on_error(std::string("SVG parse error: failed to parse <polyline> points"));
} }
parser.path_.end_path(); parser.path_.end_path();
} }
@ -1027,7 +1026,9 @@ void parse_circle(svg_parser & parser, rapidxml::xml_node<char> const* node)
{ {
if (r < 0.0) if (r < 0.0)
{ {
parser.err_handler().on_error("parse_circle: Invalid radius"); std::stringstream ss;
ss << "SVG validation error: invalid <circle> radius \"" << r << "\"";
parser.err_handler().on_error(ss.str());
} }
else else
{ {
@ -1071,14 +1072,17 @@ void parse_ellipse(svg_parser & parser, rapidxml::xml_node<char> const * node)
if (rx != 0.0 && ry != 0.0) if (rx != 0.0 && ry != 0.0)
{ {
if (rx < 0.0) if (rx < 0.0)
{ {
parser.err_handler().on_error("parse_ellipse: Invalid rx"); std::stringstream ss;
ss << "SVG validation error: invalid <ellipse> rx \"" << rx << "\"";
parser.err_handler().on_error(ss.str());
} }
else if (ry < 0.0) else if (ry < 0.0)
{ {
parser.err_handler().on_error("parse_ellipse: Invalid ry"); std::stringstream ss;
ss << "SVG validation error: invalid <ellipse> ry \"" << ry << "\"";
parser.err_handler().on_error(ss.str());
} }
else else
{ {
@ -1150,21 +1154,29 @@ void parse_rect(svg_parser & parser, rapidxml::xml_node<char> const* node)
if (w != 0.0 && h != 0.0) if (w != 0.0 && h != 0.0)
{ {
if(w < 0.0) if (w < 0.0)
{ {
parser.err_handler().on_error("parse_rect: Invalid width"); std::stringstream ss;
ss << "SVG validation error: invalid <rect> width \"" << w << "\"";
parser.err_handler().on_error(ss.str());
} }
else if(h < 0.0) else if (h < 0.0)
{ {
parser.err_handler().on_error("parse_rect: Invalid height"); std::stringstream ss;
ss << "SVG validation error: invalid <rect> height \"" << h << "\"";
parser.err_handler().on_error(ss.str());
} }
else if(rx < 0.0) else if (rx < 0.0)
{ {
parser.err_handler().on_error("parse_rect: Invalid rx"); std::stringstream ss;
ss << "SVG validation error: invalid <rect> rx \"" << rx << "\"";
parser.err_handler().on_error(ss.str());
} }
else if(ry < 0.0) else if (ry < 0.0)
{ {
parser.err_handler().on_error("parse_rect: Invalid ry"); std::stringstream ss;
ss << "SVG validation error: invalid <rect> ry \"" << ry << "\"";
parser.err_handler().on_error(ss.str());
} }
else else
{ {
@ -1431,7 +1443,7 @@ void svg_parser::parse(std::string const& filename)
if (!stream) if (!stream)
{ {
std::stringstream ss; std::stringstream ss;
ss << "Unable to open '" << filename << "'"; ss << "SVG error: unbale to open \"" << filename << "\"";
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }
@ -1449,7 +1461,7 @@ void svg_parser::parse(std::string const& filename)
catch (rapidxml::parse_error const& ex) catch (rapidxml::parse_error const& ex)
{ {
std::stringstream ss; std::stringstream ss;
ss << "svg_parser::parse - Unable to parse '" << filename << "'"; ss << "SVG error: unable to parse \"" << filename << "\"";
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }
@ -1473,7 +1485,8 @@ void svg_parser::parse_from_string(std::string const& svg)
catch (rapidxml::parse_error const& ex) catch (rapidxml::parse_error const& ex)
{ {
std::stringstream ss; std::stringstream ss;
ss << "Unable to parse '" << svg << "'"; std::string str = (svg.length() > 1024) ? svg.substr(0, 1024) + "..." : svg;
ss << "SVG error: unable to parse \"" << str << "\"";
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }
for (rapidxml::xml_node<char> const* child = doc.first_node(); for (rapidxml::xml_node<char> const* child = doc.first_node();

View file

@ -87,7 +87,7 @@ TEST_CASE("SVG parser") {
std::string svg_name("FAIL"); std::string svg_name("FAIL");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Unable to open 'FAIL'" "SVG error: unbale to open \"FAIL\""
}; };
test_parser p; test_parser p;
@ -106,7 +106,7 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/invalid.svg"); std::string svg_name("./test/data/svg/invalid.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Unable to parse '<?xml version=\"1.0\"?>\n<svg width=\"12cm\" height=\"4cm\" viewBox=\"0 0 1200 400\"\nxmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" baseProfile=\"tiny\">\n'" "SVG error: unable to parse \"<?xml version=\"1.0\"?>\n<svg width=\"12cm\" height=\"4cm\" viewBox=\"0 0 1200 400\"\nxmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" baseProfile=\"tiny\">\n\""
}; };
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
@ -129,7 +129,7 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/invalid.svg"); std::string svg_name("./test/data/svg/invalid.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"svg_parser::parse - Unable to parse './test/data/svg/invalid.svg'" "SVG error: unable to parse \"./test/data/svg/invalid.svg\""
}; };
test_parser p; test_parser p;
@ -149,9 +149,9 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/color_fail.svg"); std::string svg_name("./test/data/svg/color_fail.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Failed to parse color: \"fail\"", "SVG parse error: failed to parse <color> with value \"fail\"",
"Failed to parse SVG value: 'fail'", "SVG parse error: failed to parse <number> with value \"fail\"",
"Failed to parse color: \"fail\"", "SVG parse error: failed to parse <color> with value \"fail\""
}; };
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
@ -181,20 +181,20 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/errors.svg"); std::string svg_name("./test/data/svg/errors.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"parse_rect: Invalid width", "SVG validation error: invalid <rect> width \"-100\"",
"Failed to parse SVG value: 'FAIL'", "SVG parse error: failed to parse <number> with value \"FAIL\"",
"parse_rect: Invalid height", "SVG validation error: invalid <rect> height \"-100\"",
"parse_rect: Invalid rx", "SVG validation error: invalid <rect> rx \"-1000\"",
"parse_rect: Invalid ry", "SVG validation error: invalid <rect> ry \"-1000\"",
"Failed to parse SVG value: '100invalidunit', trailing garbage: 'validunit'", "SVG parse error: failed to parse <number> with value \"100invalidunit\"",
"unable to parse invalid svg <path>", "SVG parse error: failed to parse <path>",
"unable to parse invalid svg <path> with id 'fail-path'", "SVG parse error: failed to parse <path> with <id> \"fail-path\"",
"unable to parse invalid svg <path> with id 'fail-path'", "SVG parse error: failed to parse <path> with <id> \"fail-path\"",
"parse_circle: Invalid radius", "SVG validation error: invalid <circle> radius \"-50\"",
"Failed to parse <polygon> 'points'", "SVG parse error: failed to parse <polygon> points",
"Failed to parse <polyline> 'points'", "SVG parse error: failed to parse <polyline> points",
"parse_ellipse: Invalid rx", "SVG validation error: invalid <ellipse> rx \"-10\"",
"parse_ellipse: Invalid ry", "SVG validation error: invalid <ellipse> ry \"-10\""
}; };
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
@ -227,7 +227,7 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/gradient-radial-error.svg"); std::string svg_name("./test/data/svg/gradient-radial-error.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Failed to parse SVG value: 'FAIL'" "SVG parse error: failed to parse <number> with value \"FAIL\""
}; };
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());
@ -666,8 +666,8 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/gradient-nodef.svg"); std::string svg_name("./test/data/svg/gradient-nodef.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Failed to find gradient fill: MyGradient", "SVG parse error: failed to locate <gradient> fill with <id> \"MyGradient\"",
"Failed to find gradient stroke: MyGradient", "SVG parse error: failed to locate <gradient> stroke with <id> \"MyGradient\""
}; };
{ {
test_parser p; test_parser p;
@ -692,8 +692,8 @@ TEST_CASE("SVG parser") {
std::string svg_name("./test/data/svg/gradient-no-id.svg"); std::string svg_name("./test/data/svg/gradient-no-id.svg");
char const* expected_errors[] = char const* expected_errors[] =
{ {
"Failed to find gradient fill: MyGradient", "SVG parse error: failed to locate <gradient> fill with <id> \"MyGradient\"",
"Failed to find gradient stroke: MyGradient", "SVG parse error: failed to locate <gradient> stroke with <id> \"MyGradient\""
}; };
std::ifstream in(svg_name.c_str()); std::ifstream in(svg_name.c_str());