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(), "", ()); + } }