Skip to content

Commit 4bf4bb0

Browse files
author
Dane Springmeyer
committed
Merge pull request mapnik#2880 from zerebubuth/fix/rapidxml-loader-trim-whitespace
Fix rapidxml XML loader to trim whitespace
2 parents 42e1adc + 1778d19 commit 4bf4bb0

File tree

5 files changed

+65
-11
lines changed

5 files changed

+65
-11
lines changed

include/mapnik/xml_loader.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@
2323
#ifndef MAPNIK_LIBXML2_LOADER_HPP
2424
#define MAPNIK_LIBXML2_LOADER_HPP
2525

26+
// mapnik
27+
#include <mapnik/config.hpp> // for MAPNIK_DECL
28+
2629
// stl
2730
#include <string>
2831

2932
namespace mapnik
3033
{
31-
class xml_node;
32-
void read_xml(std::string const & filename, xml_node &node);
33-
void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path="");
34+
class MAPNIK_DECL xml_node;
35+
MAPNIK_DECL void read_xml(std::string const & filename, xml_node &node);
36+
MAPNIK_DECL void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path="");
3437
}
3538

3639
#endif // MAPNIK_LIBXML2_LOADER_HPP

include/mapnik/xml_node.hpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#ifndef MAPNIK_XML_NODE_H
2424
#define MAPNIK_XML_NODE_H
2525

26+
//mapnik
27+
#include <mapnik/config.hpp> // for MAPNIK_DECL
28+
2629
//boost
2730
#include <boost/optional.hpp>
2831

@@ -34,17 +37,17 @@
3437

3538
namespace mapnik
3639
{
37-
class xml_tree;
40+
class MAPNIK_DECL xml_tree;
3841

39-
class xml_attribute
42+
class MAPNIK_DECL xml_attribute
4043
{
4144
public:
4245
xml_attribute(const char * value_);
4346
std::string value;
4447
mutable bool processed;
4548
};
4649

47-
class node_not_found: public std::exception
50+
class MAPNIK_DECL node_not_found: public std::exception
4851
{
4952
public:
5053
node_not_found(std::string const& node_name);
@@ -56,7 +59,7 @@ class node_not_found: public std::exception
5659
mutable std::string msg_;
5760
};
5861

59-
class attribute_not_found: public std::exception
62+
class MAPNIK_DECL attribute_not_found: public std::exception
6063
{
6164
public:
6265
attribute_not_found(std::string const& node_name, std::string const& attribute_name);
@@ -69,7 +72,7 @@ class attribute_not_found: public std::exception
6972
mutable std::string msg_;
7073
};
7174

72-
class more_than_one_child: public std::exception
75+
class MAPNIK_DECL more_than_one_child: public std::exception
7376
{
7477
public:
7578
more_than_one_child(std::string const& node_name);
@@ -81,7 +84,7 @@ class more_than_one_child: public std::exception
8184
mutable std::string msg_;
8285
};
8386

84-
class xml_node
87+
class MAPNIK_DECL xml_node
8588
{
8689
public:
8790
using const_iterator = std::list<xml_node>::const_iterator;

include/mapnik/xml_tree.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
namespace mapnik
3434
{
3535

36-
class xml_tree
36+
class MAPNIK_DECL xml_tree
3737
{
3838
public:
3939
xml_tree(std::string const& encoding="utf8");

src/rapidxml_loader.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ class rapidxml_loader : util::noncopyable
138138
{
139139
if (cur_node->value_size() > 0) // Don't add empty text nodes
140140
{
141-
node.add_child(cur_node->value(), 0, true);
141+
// parsed text values should have leading and trailing
142+
// whitespace trimmed.
143+
std::string trimmed = cur_node->value();
144+
mapnik::util::trim(trimmed);
145+
node.add_child(trimmed.c_str(), 0, true);
142146
}
143147
}
144148
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "catch.hpp"
2+
3+
#include <mapnik/debug.hpp>
4+
#include <mapnik/value.hpp>
5+
#include <mapnik/xml_tree.hpp>
6+
#include <mapnik/xml_loader.hpp>
7+
8+
TEST_CASE("xml parser") {
9+
10+
SECTION("trims whitespace") {
11+
12+
// simple and non-valid mapnik XML reduced from the empty_parameter2.xml
13+
// test case. this is to check that the xml parsing routine is trimming
14+
// whitespace from text nodes as part of the parsing operation.
15+
const std::string xml("<Map>"
16+
" <Layer>"
17+
" <Datasource>"
18+
" <Parameter name=\"empty\"><![CDATA[ ]]></Parameter>"
19+
" </Datasource>"
20+
" </Layer>"
21+
"</Map>");
22+
23+
mapnik::xml_tree tree("utf8");
24+
tree.set_filename("xml_datasource_parameter_trim.cpp");
25+
REQUIRE_NOTHROW(read_xml_string(xml, tree.root(), ""));
26+
27+
REQUIRE(tree.root().has_child("Map"));
28+
mapnik::xml_node const &map = tree.root().get_child("Map");
29+
30+
REQUIRE(map.has_child("Layer"));
31+
mapnik::xml_node const &layer = map.get_child("Layer");
32+
33+
REQUIRE(layer.has_child("Datasource"));
34+
mapnik::xml_node const &datasource = layer.get_child("Datasource");
35+
36+
REQUIRE(datasource.has_child("Parameter"));
37+
mapnik::xml_node const &parameter = datasource.get_child("Parameter");
38+
39+
// parser should call mapnik::util::trim on the text content and
40+
// this should result in an empty text string in the parameter.
41+
REQUIRE(parameter.get_text() == "");
42+
}
43+
}
44+

0 commit comments

Comments
 (0)