From 2d88fec4583439b51c178dd162e1da323579e730 Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Mon, 15 Feb 2016 02:45:29 +0100 Subject: [PATCH] to_expression_string: fix backslash-escapes in strings --- include/mapnik/value.hpp | 47 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index 289759839..1192442b7 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -710,14 +710,55 @@ struct to_unicode_impl struct to_expression_string_impl { + struct EscapingByteSink : U_NAMESPACE_QUALIFIER ByteSink + { + std::string dest_; + char quote_; + + explicit EscapingByteSink(char quote) + : quote_(quote) + {} + + virtual void Append(const char* data, int32_t n) + { + // reserve enough room to hold the appended chunk and quotes; + // if another chunk follows, or any character needs escaping, + // the string will grow naturally + if (dest_.empty()) + { + dest_.reserve(2 + static_cast(n)); + dest_.append(1, quote_); + } + else + { + dest_.reserve(dest_.size() + n + 1); + } + + for (auto end = data + n; data < end; ++data) + { + if (*data == '\\' || *data == quote_) + dest_.append(1, '\\'); + dest_.append(1, *data); + } + } + + virtual void Flush() + { + if (dest_.empty()) + dest_.append(2, quote_); + else + dest_.append(1, quote_); + } + }; + explicit to_expression_string_impl(char quote = '\'') : quote_(quote) {} std::string operator() (value_unicode_string const& val) const { - std::string utf8; - to_utf8(val,utf8); - return quote_ + utf8 + quote_; + EscapingByteSink sink(quote_); + val.toUTF8(sink); + return sink.dest_; } std::string operator() (value_integer val) const