diff --git a/map/bookmark.cpp b/map/bookmark.cpp
index 006f60bf5a..2232507aa1 100644
--- a/map/bookmark.cpp
+++ b/map/bookmark.cpp
@@ -351,19 +351,38 @@ char const * kmlFooter =
"\n";
}
+namespace
+{
+ // According to kml/xml spec, we need to escape special symbols inside CDATA
+ inline bool ShouldUseCDATA(string const & s)
+ {
+ return s.find_first_of("<&") != string::npos;
+ }
+}
+
void BookmarkCategory::SaveToKML(ostream & s)
{
s << kmlHeader;
- s << " " << GetName() <<"\n";
+ // Use CDATA if we have special symbols in the name
+ if (ShouldUseCDATA(GetName()))
+ s << " \n";
+ else
+ s << " " << GetName() << "\n";
s << " " << (IsVisible() ? "1" : "0") <<"\n";
for (size_t i = 0; i < m_bookmarks.size(); ++i)
{
Bookmark const * bm = m_bookmarks[i];
- s << " \n"
- << " " << bm->GetName() << "\n"
- << " #" << bm->GetType() << "\n"
+ s << " \n";
+
+ // Use CDATA if we have special symbols in the name
+ if (ShouldUseCDATA(bm->GetName()))
+ s << " GetName() << "]]>\n";
+ else
+ s << " " << bm->GetName() << "\n";
+
+ s << " #" << bm->GetType() << "\n"
<< " \n"
<< " " << PointToString(bm->GetOrg()) << "\n"
<< " \n";
diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp
index c30f596c56..ac621a1c56 100644
--- a/map/map_tests/bookmarks_test.cpp
+++ b/map/map_tests/bookmarks_test.cpp
@@ -88,7 +88,15 @@ char const * kmlString =
""
"#placemark-blue"
""
- "27.566765,53.900047,0.000000"
+ "27.566765,53.900047,0"
+ ""
+ ""
+ ""
+ "]]>"
+ "]]>"
+ "#placemark-green"
+ ""
+ "27.551532,53.89306"
""
""
""
@@ -96,7 +104,7 @@ char const * kmlString =
void CheckBookmarks(BookmarkCategory const & cat)
{
- TEST_EQUAL(cat.GetBookmarksCount(), 3, ());
+ TEST_EQUAL(cat.GetBookmarksCount(), 4, ());
Bookmark const * bm = cat.GetBookmark(0);
TEST_EQUAL(bm->GetName(), "Nebraska", ());
@@ -107,10 +115,18 @@ char const * kmlString =
TEST_EQUAL(bm->GetType(), "placemark-pink", ());
bm = cat.GetBookmark(2);
- m2::PointD const org = bm->GetOrg();
+ m2::PointD org = bm->GetOrg();
TEST_ALMOST_EQUAL(MercatorBounds::XToLon(org.x), 27.566765, ());
TEST_ALMOST_EQUAL(MercatorBounds::YToLat(org.y), 53.900047, ());
+ TEST_EQUAL(bm->GetName(), "From: Минск, Минская область, Беларусь", ());
TEST_EQUAL(bm->GetType(), "placemark-blue", ());
+
+ bm = cat.GetBookmark(3);
+ org = bm->GetOrg();
+ TEST_ALMOST_EQUAL(MercatorBounds::XToLon(org.x), 27.551532, ());
+ TEST_ALMOST_EQUAL(MercatorBounds::YToLat(org.y), 53.89306, ());
+ TEST_EQUAL(bm->GetName(), "", ());
+
}
}