mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Merge pull request #325 from InvalidUsernameException/emoji-parses-as-int
Do not mis-parse certain wide-character emojis as integer
This commit is contained in:
commit
e5612e9f72
@ -1132,7 +1132,13 @@ template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
|
|||||||
|
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) {
|
fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) {
|
||||||
return int_luts<>::chdigit[static_cast<unsigned char>(c)];
|
using UnsignedUC = typename std::make_unsigned<UC>::type;
|
||||||
|
auto uc = static_cast<UnsignedUC>(c);
|
||||||
|
// For types larger than one byte, we need to force an index with sentinel
|
||||||
|
// value (using index zero because that is easiest) if any byte other than
|
||||||
|
// the low byte is non-zero.
|
||||||
|
auto mask = static_cast<UnsignedUC>(-((uc & ~0xFFull) == 0));
|
||||||
|
return int_luts<>::chdigit[static_cast<unsigned char>(uc & mask)];
|
||||||
}
|
}
|
||||||
|
|
||||||
fastfloat_really_inline constexpr size_t max_digits_u64(int base) {
|
fastfloat_really_inline constexpr size_t max_digits_u64(int base) {
|
||||||
|
|||||||
@ -831,6 +831,275 @@ int main() {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// dont parse UTF-16 code units of emojis as int if low byte is ascii digit
|
||||||
|
{
|
||||||
|
const std::u16string emojis[] = {
|
||||||
|
u"ℹ", u"ℹ️", u"☸", u"☸️", u"☹", u"☹️", u"✳", u"✳️",
|
||||||
|
u"✴", u"✴️", u"⤴", u"⤴️", u"⤵", u"⤵️", u"〰", u"〰️",
|
||||||
|
};
|
||||||
|
bool failed = false;
|
||||||
|
auto array_size = sizeof(emojis) / sizeof(emojis[0]);
|
||||||
|
for (size_t i = 0; i < array_size; i++) {
|
||||||
|
auto e = emojis[i];
|
||||||
|
int foo;
|
||||||
|
auto answer = fast_float::from_chars(e.data(), e.data() + e.size(), foo);
|
||||||
|
if (answer.ec == std::errc()) {
|
||||||
|
failed = true;
|
||||||
|
std::cerr << "Incorrectly parsed emoji #" << i << " as integer " << foo
|
||||||
|
<< "." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dont parse UTF-32 code points of emojis as int if low byte is ascii digit
|
||||||
|
{
|
||||||
|
const std::u32string emojis[] = {
|
||||||
|
U"ℹ",
|
||||||
|
U"ℹ️",
|
||||||
|
U"☸",
|
||||||
|
U"☸️",
|
||||||
|
U"☹",
|
||||||
|
U"☹️",
|
||||||
|
U"✳",
|
||||||
|
U"✳️",
|
||||||
|
U"✴",
|
||||||
|
U"✴️",
|
||||||
|
U"⤴",
|
||||||
|
U"⤴️",
|
||||||
|
U"⤵",
|
||||||
|
U"⤵️",
|
||||||
|
U"〰",
|
||||||
|
U"〰️",
|
||||||
|
U"🈲",
|
||||||
|
U"🈳",
|
||||||
|
U"🈴",
|
||||||
|
U"🈵",
|
||||||
|
U"🈶",
|
||||||
|
U"🈷",
|
||||||
|
U"🈷️",
|
||||||
|
U"🈸",
|
||||||
|
U"🈹",
|
||||||
|
U"🌰",
|
||||||
|
U"🌱",
|
||||||
|
U"🌲",
|
||||||
|
U"🌳",
|
||||||
|
U"🌴",
|
||||||
|
U"🌵",
|
||||||
|
U"🌶",
|
||||||
|
U"🌶️",
|
||||||
|
U"🌷",
|
||||||
|
U"🌸",
|
||||||
|
U"🌹",
|
||||||
|
U"🐰",
|
||||||
|
U"🐱",
|
||||||
|
U"🐲",
|
||||||
|
U"🐳",
|
||||||
|
U"🐴",
|
||||||
|
U"🐵",
|
||||||
|
U"🐶",
|
||||||
|
U"🐷",
|
||||||
|
U"🐸",
|
||||||
|
U"🐹",
|
||||||
|
U"🔰",
|
||||||
|
U"🔱",
|
||||||
|
U"🔲",
|
||||||
|
U"🔳",
|
||||||
|
U"🔴",
|
||||||
|
U"🔵",
|
||||||
|
U"🔶",
|
||||||
|
U"🔷",
|
||||||
|
U"🔸",
|
||||||
|
U"🔹",
|
||||||
|
U"😰",
|
||||||
|
U"😱",
|
||||||
|
U"😲",
|
||||||
|
U"😳",
|
||||||
|
U"😴",
|
||||||
|
U"😵",
|
||||||
|
U"😵💫",
|
||||||
|
U"😶",
|
||||||
|
U"😶🌫",
|
||||||
|
U"😶🌫️",
|
||||||
|
U"😷",
|
||||||
|
U"😸",
|
||||||
|
U"😹",
|
||||||
|
U"🤰",
|
||||||
|
U"🤰🏻",
|
||||||
|
U"🤰🏼",
|
||||||
|
U"🤰🏽",
|
||||||
|
U"🤰🏾",
|
||||||
|
U"🤰🏿",
|
||||||
|
U"🤱",
|
||||||
|
U"🤱🏻",
|
||||||
|
U"🤱🏼",
|
||||||
|
U"🤱🏽",
|
||||||
|
U"🤱🏾",
|
||||||
|
U"🤱🏿",
|
||||||
|
U"🤲",
|
||||||
|
U"🤲🏻",
|
||||||
|
U"🤲🏼",
|
||||||
|
U"🤲🏽",
|
||||||
|
U"🤲🏾",
|
||||||
|
U"🤲🏿",
|
||||||
|
U"🤳",
|
||||||
|
U"🤳🏻",
|
||||||
|
U"🤳🏼",
|
||||||
|
U"🤳🏽",
|
||||||
|
U"🤳🏾",
|
||||||
|
U"🤳🏿",
|
||||||
|
U"🤴",
|
||||||
|
U"🤴🏻",
|
||||||
|
U"🤴🏼",
|
||||||
|
U"🤴🏽",
|
||||||
|
U"🤴🏾",
|
||||||
|
U"🤴🏿",
|
||||||
|
U"🤵",
|
||||||
|
U"🤵♀",
|
||||||
|
U"🤵♀️",
|
||||||
|
U"🤵♂",
|
||||||
|
U"🤵♂️",
|
||||||
|
U"🤵🏻",
|
||||||
|
U"🤵🏻♀",
|
||||||
|
U"🤵🏻♀️",
|
||||||
|
U"🤵🏻♂",
|
||||||
|
U"🤵🏻♂️",
|
||||||
|
U"🤵🏼",
|
||||||
|
U"🤵🏼♀",
|
||||||
|
U"🤵🏼♀️",
|
||||||
|
U"🤵🏼♂",
|
||||||
|
U"🤵🏼♂️",
|
||||||
|
U"🤵🏽",
|
||||||
|
U"🤵🏽♀",
|
||||||
|
U"🤵🏽♀️",
|
||||||
|
U"🤵🏽♂",
|
||||||
|
U"🤵🏽♂️",
|
||||||
|
U"🤵🏾",
|
||||||
|
U"🤵🏾♀",
|
||||||
|
U"🤵🏾♀️",
|
||||||
|
U"🤵🏾♂",
|
||||||
|
U"🤵🏾♂️",
|
||||||
|
U"🤵🏿",
|
||||||
|
U"🤵🏿♀",
|
||||||
|
U"🤵🏿♀️",
|
||||||
|
U"🤵🏿♂",
|
||||||
|
U"🤵🏿♂️",
|
||||||
|
U"🤶",
|
||||||
|
U"🤶🏻",
|
||||||
|
U"🤶🏼",
|
||||||
|
U"🤶🏽",
|
||||||
|
U"🤶🏾",
|
||||||
|
U"🤶🏿",
|
||||||
|
U"🤷",
|
||||||
|
U"🤷♀",
|
||||||
|
U"🤷♀️",
|
||||||
|
U"🤷♂",
|
||||||
|
U"🤷♂️",
|
||||||
|
U"🤷🏻",
|
||||||
|
U"🤷🏻♀",
|
||||||
|
U"🤷🏻♀️",
|
||||||
|
U"🤷🏻♂",
|
||||||
|
U"🤷🏻♂️",
|
||||||
|
U"🤷🏼",
|
||||||
|
U"🤷🏼♀",
|
||||||
|
U"🤷🏼♀️",
|
||||||
|
U"🤷🏼♂",
|
||||||
|
U"🤷🏼♂️",
|
||||||
|
U"🤷🏽",
|
||||||
|
U"🤷🏽♀",
|
||||||
|
U"🤷🏽♀️",
|
||||||
|
U"🤷🏽♂",
|
||||||
|
U"🤷🏽♂️",
|
||||||
|
U"🤷🏾",
|
||||||
|
U"🤷🏾♀",
|
||||||
|
U"🤷🏾♀️",
|
||||||
|
U"🤷🏾♂",
|
||||||
|
U"🤷🏾♂️",
|
||||||
|
U"🤷🏿",
|
||||||
|
U"🤷🏿♀",
|
||||||
|
U"🤷🏿♀️",
|
||||||
|
U"🤷🏿♂",
|
||||||
|
U"🤷🏿♂️",
|
||||||
|
U"🤸",
|
||||||
|
U"🤸♀",
|
||||||
|
U"🤸♀️",
|
||||||
|
U"🤸♂",
|
||||||
|
U"🤸♂️",
|
||||||
|
U"🤸🏻",
|
||||||
|
U"🤸🏻♀",
|
||||||
|
U"🤸🏻♀️",
|
||||||
|
U"🤸🏻♂",
|
||||||
|
U"🤸🏻♂️",
|
||||||
|
U"🤸🏼",
|
||||||
|
U"🤸🏼♀",
|
||||||
|
U"🤸🏼♀️",
|
||||||
|
U"🤸🏼♂",
|
||||||
|
U"🤸🏼♂️",
|
||||||
|
U"🤸🏽",
|
||||||
|
U"🤸🏽♀",
|
||||||
|
U"🤸🏽♀️",
|
||||||
|
U"🤸🏽♂",
|
||||||
|
U"🤸🏽♂️",
|
||||||
|
U"🤸🏾",
|
||||||
|
U"🤸🏾♀",
|
||||||
|
U"🤸🏾♀️",
|
||||||
|
U"🤸🏾♂",
|
||||||
|
U"🤸🏾♂️",
|
||||||
|
U"🤸🏿",
|
||||||
|
U"🤸🏿♀",
|
||||||
|
U"🤸🏿♀️",
|
||||||
|
U"🤸🏿♂",
|
||||||
|
U"🤸🏿♂️",
|
||||||
|
U"🤹",
|
||||||
|
U"🤹♀",
|
||||||
|
U"🤹♀️",
|
||||||
|
U"🤹♂",
|
||||||
|
U"🤹♂️",
|
||||||
|
U"🤹🏻",
|
||||||
|
U"🤹🏻♀",
|
||||||
|
U"🤹🏻♀️",
|
||||||
|
U"🤹🏻♂",
|
||||||
|
U"🤹🏻♂️",
|
||||||
|
U"🤹🏼",
|
||||||
|
U"🤹🏼♀",
|
||||||
|
U"🤹🏼♀️",
|
||||||
|
U"🤹🏼♂",
|
||||||
|
U"🤹🏼♂️",
|
||||||
|
U"🤹🏽",
|
||||||
|
U"🤹🏽♀",
|
||||||
|
U"🤹🏽♀️",
|
||||||
|
U"🤹🏽♂",
|
||||||
|
U"🤹🏽♂️",
|
||||||
|
U"🤹🏾",
|
||||||
|
U"🤹🏾♀",
|
||||||
|
U"🤹🏾♀️",
|
||||||
|
U"🤹🏾♂",
|
||||||
|
U"🤹🏾♂️",
|
||||||
|
U"🤹🏿",
|
||||||
|
U"🤹🏿♀",
|
||||||
|
U"🤹🏿♀️",
|
||||||
|
U"🤹🏿♂",
|
||||||
|
U"🤹🏿♂️",
|
||||||
|
};
|
||||||
|
bool failed = false;
|
||||||
|
auto array_size = sizeof(emojis) / sizeof(emojis[0]);
|
||||||
|
for (size_t i = 0; i < array_size; i++) {
|
||||||
|
auto e = emojis[i];
|
||||||
|
int foo;
|
||||||
|
auto answer = fast_float::from_chars(e.data(), e.data() + e.size(), foo);
|
||||||
|
if (answer.ec == std::errc()) {
|
||||||
|
failed = true;
|
||||||
|
std::cerr << "Incorrectly parsed emoji #" << i << " as integer " << foo
|
||||||
|
<< "." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user