mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-01 09:21:37 +00:00
Narrows template ascii routines to prevent a possible signed overflow in generic code. (#5232)
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
73a648b685
commit
407fb5d537
@@ -35,19 +35,19 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
// @locale-independent functions for ASCII characters set.
|
// @locale-independent functions for ASCII characters set.
|
||||||
|
|
||||||
// Check that integer scalar is in closed range: (a <= x <= b)
|
// Fast checking that character lies in closed range: [a <= x <= b]
|
||||||
// using one compare (conditional branch) operator.
|
// using one compare (conditional branch) operator.
|
||||||
template<typename T> inline bool check_in_range(T x, T a, T b) {
|
inline bool check_ascii_range(char x, char a, char b) {
|
||||||
|
FLATBUFFERS_ASSERT(a <= b);
|
||||||
// (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`.
|
// (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`.
|
||||||
FLATBUFFERS_ASSERT(a <= b); // static_assert only if 'a' & 'b' templated
|
// The x, a, b will be promoted to int and subtracted without overflow.
|
||||||
typedef typename flatbuffers::make_unsigned<T>::type U;
|
return static_cast<unsigned int>(x - a) <= static_cast<unsigned int>(b - a);
|
||||||
return (static_cast<U>(x - a) <= static_cast<U>(b - a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case-insensitive isalpha
|
// Case-insensitive isalpha
|
||||||
inline bool is_alpha(char c) {
|
inline bool is_alpha(char c) {
|
||||||
// ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
|
// ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
|
||||||
return check_in_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF);
|
return check_ascii_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check (case-insensitive) that `c` is equal to alpha.
|
// Check (case-insensitive) that `c` is equal to alpha.
|
||||||
@@ -62,11 +62,11 @@ inline bool is_alpha_char(char c, char alpha) {
|
|||||||
// functions that are not affected by the currently installed C locale. although
|
// functions that are not affected by the currently installed C locale. although
|
||||||
// some implementations (e.g. Microsoft in 1252 codepage) may classify
|
// some implementations (e.g. Microsoft in 1252 codepage) may classify
|
||||||
// additional single-byte characters as digits.
|
// additional single-byte characters as digits.
|
||||||
inline bool is_digit(char c) { return check_in_range(c, '0', '9'); }
|
inline bool is_digit(char c) { return check_ascii_range(c, '0', '9'); }
|
||||||
|
|
||||||
inline bool is_xdigit(char c) {
|
inline bool is_xdigit(char c) {
|
||||||
// Replace by look-up table.
|
// Replace by look-up table.
|
||||||
return is_digit(c) || check_in_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF);
|
return is_digit(c) || check_ascii_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case-insensitive isalnum
|
// Case-insensitive isalnum
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ CheckedError Parser::Next() {
|
|||||||
"illegal Unicode sequence (unpaired high surrogate)");
|
"illegal Unicode sequence (unpaired high surrogate)");
|
||||||
}
|
}
|
||||||
// reset if non-printable
|
// reset if non-printable
|
||||||
attr_is_trivial_ascii_string_ &= check_in_range(*cursor_, ' ', '~');
|
attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~');
|
||||||
|
|
||||||
attribute_ += *cursor_++;
|
attribute_ += *cursor_++;
|
||||||
}
|
}
|
||||||
@@ -476,7 +476,7 @@ CheckedError Parser::Next() {
|
|||||||
}
|
}
|
||||||
std::string ch;
|
std::string ch;
|
||||||
ch = c;
|
ch = c;
|
||||||
if (false == check_in_range(c, ' ', '~')) ch = "code: " + NumToString(c);
|
if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c);
|
||||||
return Error("illegal character: " + ch);
|
return Error("illegal character: " + ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user