From 0039c5b981e7283efa333f1b18920d27540597e3 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 1 Jan 2021 19:06:08 -0800 Subject: [PATCH] Disallow parser.iterate("1"_padded), as it won't work --- include/simdjson/generic/ondemand/parser-inl.h | 7 +++++++ include/simdjson/generic/ondemand/parser.h | 3 +++ tests/ondemand/CMakeLists.txt | 1 + .../compilation_failure_tests/CMakeLists.txt | 17 +++++++++++++++++ .../iterate_temporary_buffer.cpp | 18 ++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 tests/ondemand/compilation_failure_tests/CMakeLists.txt create mode 100644 tests/ondemand/compilation_failure_tests/iterate_temporary_buffer.cpp diff --git a/include/simdjson/generic/ondemand/parser-inl.h b/include/simdjson/generic/ondemand/parser-inl.h index 335db412..4b4770a0 100644 --- a/include/simdjson/generic/ondemand/parser-inl.h +++ b/include/simdjson/generic/ondemand/parser-inl.h @@ -28,6 +28,13 @@ simdjson_warn_unused simdjson_really_inline simdjson_result parser::it return document::start(this); } +simdjson_warn_unused simdjson_really_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &buf = result.first; + return iterate(buf); +} + simdjson_warn_unused simdjson_really_inline simdjson_result parser::iterate_raw(const padded_string &buf) & noexcept { // Allocate if needed if (_capacity < buf.size()) { diff --git a/include/simdjson/generic/ondemand/parser.h b/include/simdjson/generic/ondemand/parser.h index e9af0889..f91e6ec5 100644 --- a/include/simdjson/generic/ondemand/parser.h +++ b/include/simdjson/generic/ondemand/parser.h @@ -63,6 +63,9 @@ public: * - UNCLOSED_STRING if there is an unclosed string in the document. */ simdjson_warn_unused simdjson_result iterate(const padded_string &json) & noexcept; + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + simdjson_warn_unused simdjson_result iterate(const std::string_view &json) & noexcept = delete; simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept = delete; /** * @private diff --git a/tests/ondemand/CMakeLists.txt b/tests/ondemand/CMakeLists.txt index 7413ac00..eb9ff4b7 100644 --- a/tests/ondemand/CMakeLists.txt +++ b/tests/ondemand/CMakeLists.txt @@ -1,6 +1,7 @@ # All remaining tests link with simdjson proper link_libraries(simdjson) include_directories(..) +add_subdirectory(compilation_failure_tests) add_cpp_test(ondemand_active_tests LABELS ondemand acceptance per_implementation) add_cpp_test(ondemand_compilation_tests LABELS ondemand acceptance per_implementation) diff --git a/tests/ondemand/compilation_failure_tests/CMakeLists.txt b/tests/ondemand/compilation_failure_tests/CMakeLists.txt new file mode 100644 index 00000000..c79d41a3 --- /dev/null +++ b/tests/ondemand/compilation_failure_tests/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# This directory contains files aimed to verify that constructs that +# are supposed to fail at compile time, indeed do so. +# To prevent bit rot, the same source file is compiled twice with +# the macro COMPILATION_TEST_USE_FAILING_CODE set to 0 or 1. +# + +# adds a compilation test. Two targets are created, one expected to +# succeed compilation and one that is expected to fail. +function(add_dual_compile_test TEST_NAME) + add_cpp_test(${TEST_NAME}_should_compile SOURCES ${TEST_NAME}.cpp COMPILE_ONLY LABELS no_mingw) + add_cpp_test(${TEST_NAME}_should_not_compile SOURCES ${TEST_NAME}.cpp COMPILE_ONLY WILL_FAIL LABELS acceptance no_mingw) + target_compile_definitions(${TEST_NAME}_should_not_compile PRIVATE COMPILATION_TEST_USE_FAILING_CODE=1) +endfunction(add_dual_compile_test) + + +add_dual_compile_test(iterate_temporary_buffer) diff --git a/tests/ondemand/compilation_failure_tests/iterate_temporary_buffer.cpp b/tests/ondemand/compilation_failure_tests/iterate_temporary_buffer.cpp new file mode 100644 index 00000000..3e595377 --- /dev/null +++ b/tests/ondemand/compilation_failure_tests/iterate_temporary_buffer.cpp @@ -0,0 +1,18 @@ +#include +#include "simdjson.h" + +using namespace simdjson::builtin; + +int main() { + ondemand::parser parser; +#if COMPILATION_TEST_USE_FAILING_CODE + auto doc = parser.iterate("1"_padded); +#else + auto json = "1"_padded; + auto doc = parser.iterate(json); +#endif + int64_t value; + auto error = doc.get(value); + if (error) { exit(1); } + std::cout << value << std::endl; +}