diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-03-01 17:01:22 -0800 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-03-02 11:40:03 -0800 |
commit | c2bb0b4911505c7a1a5a78c02d3785856f42ee99 (patch) | |
tree | 44be7cb71d3a1b009cac92466cebd4af510d2164 | |
parent | 8108e1b59cdc97d6ad191acf9e084b8292069a11 (diff) | |
download | qtlocation-mapboxgl-c2bb0b4911505c7a1a5a78c02d3785856f42ee99.tar.gz |
[core] Safeguard ICU UChar usage
-rw-r--r-- | include/mbgl/util/traits.hpp | 16 | ||||
-rw-r--r-- | platform/default/bidi.cpp | 16 |
2 files changed, 25 insertions, 7 deletions
diff --git a/include/mbgl/util/traits.hpp b/include/mbgl/util/traits.hpp index 9d6f947cd2..5b9401aad7 100644 --- a/include/mbgl/util/traits.hpp +++ b/include/mbgl/util/traits.hpp @@ -1,5 +1,6 @@ #pragma once +#include <cstdint> #include <type_traits> namespace mbgl { @@ -9,4 +10,19 @@ constexpr auto underlying_type(T t) -> typename std::underlying_type_t<T> { return typename std::underlying_type_t<T>(t); } +template <typename T> struct is_utf16char_like: std::false_type {}; +template <typename T> struct is_utf16char_like<const T>: is_utf16char_like<T> {}; +template <> struct is_utf16char_like<char16_t>: std::true_type {}; +template <> struct is_utf16char_like<wchar_t>: std::true_type {}; +template <> struct is_utf16char_like<uint16_t>: std::true_type {}; + +template <typename T> using is_utf16char_like_pointer = std::integral_constant<bool, std::is_pointer<T>::value + && is_utf16char_like<typename std::remove_pointer<T>::type>::value>; + +template <class OutPointer, class InChar> +typename std::enable_if<is_utf16char_like<InChar>::value && is_utf16char_like_pointer<OutPointer>::value, OutPointer>::type utf16char_cast(InChar *in) +{ + return reinterpret_cast<OutPointer>(in); +} + } // namespace mbgl diff --git a/platform/default/bidi.cpp b/platform/default/bidi.cpp index 25b4dbe3a7..59df6dd6df 100644 --- a/platform/default/bidi.cpp +++ b/platform/default/bidi.cpp @@ -1,9 +1,11 @@ -#include <memory> - #include <mbgl/text/bidi.hpp> +#include <mbgl/util/traits.hpp> + #include <unicode/ubidi.h> #include <unicode/ushape.h> +#include <memory> + namespace mbgl { class BiDiImpl { @@ -28,7 +30,7 @@ std::u16string applyArabicShaping(const std::u16string& input) { UErrorCode errorCode = U_ZERO_ERROR; const int32_t outputLength = - u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), NULL, 0, + u_shapeArabic(mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()), NULL, 0, (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) | (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK), &errorCode); @@ -37,7 +39,7 @@ std::u16string applyArabicShaping(const std::u16string& input) { errorCode = U_ZERO_ERROR; auto outputText = std::make_unique<UChar[]>(outputLength); - u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), outputText.get(), outputLength, + u_shapeArabic(mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()), outputText.get(), outputLength, (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) | (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK), &errorCode); @@ -46,7 +48,7 @@ std::u16string applyArabicShaping(const std::u16string& input) { if (U_FAILURE(errorCode)) return input; - return std::u16string(outputText.get(), outputLength); + return std::u16string(mbgl::utf16char_cast<const char16_t*>(outputText.get()), outputLength); } void BiDi::mergeParagraphLineBreaks(std::set<size_t>& lineBreakPoints) { @@ -86,7 +88,7 @@ std::vector<std::u16string> BiDi::processText(const std::u16string& input, std::set<std::size_t> lineBreakPoints) { UErrorCode errorCode = U_ZERO_ERROR; - ubidi_setPara(impl->bidiText, input.c_str(), static_cast<int32_t>(input.size()), + ubidi_setPara(impl->bidiText, mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()), UBIDI_DEFAULT_LTR, NULL, &errorCode); if (U_FAILURE(errorCode)) { @@ -121,7 +123,7 @@ std::u16string BiDi::getLine(std::size_t start, std::size_t end) { u_errorName(errorCode)); } - return std::u16string(outputText.get(), outputLength); + return std::u16string(mbgl::utf16char_cast<const char16_t*>(outputText.get()), outputLength); } } // end namespace mbgl |