Fixing UTF-8 validation under PPC64 (#1346)
* Entering a new UTF-8 test * Maybe *I* had a bug in the tests. * Replacing nulls with 1s. * Let us try to be more verbose. * Return 0. * Fixing issue. * Adding puzzler scenario. * Fixing PPC64 Co-authored-by: Daniel Lemire <dlemire@rcs-power9-talos>
This commit is contained in:
parent
f785f76d98
commit
85001c55fb
|
@ -12,6 +12,24 @@
|
|||
#include <cstdlib>
|
||||
#include "supported_implementations.h"
|
||||
|
||||
extern "C" int VerboseTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
static const auto supported_implementations=get_runtime_supported_implementations();
|
||||
for(size_t i = 0; i <= Size; i++) {
|
||||
std::cout<<"size: "<<std::dec<<std::setw(8)<<i<<std::endl;
|
||||
std::cout<<"Input: \"";
|
||||
for(size_t j = 0; j < i; j++) {
|
||||
std::cout<<"\\x"<<std::hex<<std::setw(2)<<std::setfill('0')<<uint32_t(Data[j]);
|
||||
}
|
||||
std::cout<<"\""<<std::endl;
|
||||
for(const auto& e: supported_implementations) {
|
||||
if(!e->supported_by_runtime_system()) { continue; }
|
||||
const bool current=e->validate_utf8((const char*)Data,i);
|
||||
std::cout<<e->name()<<" returns "<<current<<std::endl;
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
|
||||
|
@ -51,6 +69,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||
}
|
||||
std::cerr << "\"" <<std::endl;
|
||||
|
||||
VerboseTestOneInput(Data, Size);
|
||||
|
||||
std::abort();
|
||||
}
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@ template <> struct simd8<uint8_t> : base8_numeric<uint8_t> {
|
|||
template <typename T> struct simd8x64 {
|
||||
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
|
||||
static_assert(NUM_CHUNKS == 4,
|
||||
"Westmere kernel should use four registers per 64-byte block.");
|
||||
"PPC64 kernel should use four registers per 64-byte block.");
|
||||
const simd8<T> chunks[NUM_CHUNKS];
|
||||
|
||||
simd8x64(const simd8x64<T> &o) = delete; // no copy allowed
|
||||
|
|
|
@ -49,7 +49,8 @@ simdjson_really_inline json_character_block json_character_block::classify(const
|
|||
}
|
||||
|
||||
simdjson_really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
return input.reduce_or().saturating_sub(0b10000000u).bits_not_set_anywhere();
|
||||
// careful: 0x80 is not ascii.
|
||||
return input.reduce_or().saturating_sub(0b01111111u).bits_not_set_anywhere();
|
||||
}
|
||||
|
||||
simdjson_unused simdjson_really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
|
|
|
@ -223,15 +223,17 @@ void test() {
|
|||
"\x80",
|
||||
"\x91\x85\x95\x9e",
|
||||
"\x6c\x02\x8e\x18",
|
||||
"[[[[[[[[[[[[[[[\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"};
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
"\x25\x5b\x6e\x2c\x32\x2c\x5b\x5b\x33\x2c\x34\x2c\x05\x29\x2c\x33\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5d\x2c\x35\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x20\x01\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x23\x0a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x7e\x7e\x0a\x0a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5d\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x01\x01\x80\x01\x01\x01\x79\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
|
||||
"[[[[[[[[[[[[[[[\x80\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x010\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
|
||||
"\x20\x0b\x01\x01\x01\x64\x3a\x64\x3a\x64\x3a\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x30\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x80\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"};
|
||||
for (size_t i = 0; i < sizeof(goodsequences)/sizeof(goodsequences[0]); i++) {
|
||||
size_t len = std::strlen(goodsequences[i]);
|
||||
if (!simdjson::validate_utf8(goodsequences[i], len)) {
|
||||
printf("bug goodsequences[%zu]\n", i);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < 26; i++) {
|
||||
for (size_t i = 0; i < sizeof(badsequences)/sizeof(badsequences[0]); i++) {
|
||||
size_t len = std::strlen(badsequences[i]);
|
||||
if (simdjson::validate_utf8(badsequences[i], len)) {
|
||||
printf("bug lookup2 badsequences[%zu]\n", i);
|
||||
|
@ -240,7 +242,30 @@ void test() {
|
|||
}
|
||||
printf("tests ok.\n");
|
||||
}
|
||||
|
||||
// This is an attempt at reproducing an issue with the utf8 fuzzer
|
||||
void puzzler() {
|
||||
std::cout << "running puzzler... " << std::endl;
|
||||
const char* bad64 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
size_t length = 64;
|
||||
std::cout << "Input: \"";
|
||||
for(size_t j = 0; j < length; j++) {
|
||||
std::cout << "\\x" << std::hex << std::setw(2) << std::setfill('0') << uint32_t(bad64[j]);
|
||||
}
|
||||
std::cout << "\"" << std::endl;
|
||||
bool is_ok{true};
|
||||
for(const auto& e: simdjson::available_implementations) {
|
||||
if(!e->supported_by_runtime_system()) { continue; }
|
||||
const bool current = e->validate_utf8(bad64, length);
|
||||
std::cout << e->name() << " returns " << current << std::endl;
|
||||
if(current) { is_ok = false; }
|
||||
}
|
||||
if(!is_ok) { abort(); }
|
||||
std::cout << "Ok!" << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
puzzler();
|
||||
brute_force_tests();
|
||||
test();
|
||||
return EXIT_SUCCESS;
|
||||
|
|
Loading…
Reference in New Issue