diff --git a/include/nlohmann/detail/view/string_ref.hpp b/include/nlohmann/detail/view/string_ref.hpp index bb9605bf6..d401500ec 100644 --- a/include/nlohmann/detail/view/string_ref.hpp +++ b/include/nlohmann/detail/view/string_ref.hpp @@ -40,6 +40,8 @@ class string_ref using const_iterator = const char*; string_ref() noexcept = default; + // s must be null-terminated, as for std::string_view(const char*) + // flawfinder: ignore string_ref(const char* s) : m_data(s), m_size(std::strlen(s)) {} // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) string_ref(const char* s, std::size_t n) noexcept : m_data(s), m_size(n) {} template diff --git a/include/nlohmann/json_view.hpp b/include/nlohmann/json_view.hpp index 7aec0cb2f..d70bde43f 100644 --- a/include/nlohmann/json_view.hpp +++ b/include/nlohmann/json_view.hpp @@ -872,6 +872,7 @@ class basic_json_document /// parse into this document, reusing its memory template + // flawfinder: ignore (a member function, not POSIX read()) void read(InputType&& input, const bool allow_exceptions = true, const bool ignore_comments = false, @@ -1044,6 +1045,8 @@ class basic_json_document return; } const char* cs = reinterpret_cast(s); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + // C strings are null-terminated, as for json::parse(const char*) + // flawfinder: ignore build(cs, std::strlen(cs), ae, c, tc, false, true); } diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp index 121840e95..460ad9f4a 100644 --- a/single_include/nlohmann/json_view.hpp +++ b/single_include/nlohmann/json_view.hpp @@ -3930,6 +3930,8 @@ class string_ref using const_iterator = const char*; string_ref() noexcept = default; + // s must be null-terminated, as for std::string_view(const char*) + // flawfinder: ignore string_ref(const char* s) : m_data(s), m_size(std::strlen(s)) {} // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) string_ref(const char* s, std::size_t n) noexcept : m_data(s), m_size(n) {} template @@ -4925,6 +4927,7 @@ class basic_json_document /// parse into this document, reusing its memory template + // flawfinder: ignore (a member function, not POSIX read()) void read(InputType&& input, const bool allow_exceptions = true, const bool ignore_comments = false, @@ -5097,6 +5100,8 @@ class basic_json_document return; } const char* cs = reinterpret_cast(s); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + // C strings are null-terminated, as for json::parse(const char*) + // flawfinder: ignore build(cs, std::strlen(cs), ae, c, tc, false, true); } diff --git a/tests/benchmarks/json_view/compare.py b/tests/benchmarks/json_view/compare.py index 0901011ca..91e7d0a83 100755 --- a/tests/benchmarks/json_view/compare.py +++ b/tests/benchmarks/json_view/compare.py @@ -30,7 +30,8 @@ import platform import re import shlex import shutil -import subprocess +# runs only the compilers and benchmark binaries this script builds +import subprocess # nosec B404 import sys import tarfile import urllib.request @@ -71,12 +72,14 @@ DEFAULT_CORPUS = [ def run(cmd, **kwargs): print('+ ' + ' '.join(shlex.quote(c) for c in cmd), flush=True) - return subprocess.run(cmd, check=True, **kwargs) + # cmd is an argument list built by this script, never a shell string + return subprocess.run(cmd, check=True, **kwargs) # nosec B603 def output(cmd): try: - return subprocess.run(cmd, check=True, capture_output=True, text=True).stdout.strip() + # cmd is an argument list built by this script, never a shell string + return subprocess.run(cmd, check=True, capture_output=True, text=True).stdout.strip() # nosec B603 except (OSError, subprocess.CalledProcessError): return '' @@ -150,7 +153,8 @@ def download_library(name, work): os.makedirs(os.path.dirname(archive), exist_ok=True) if not os.path.isfile(archive): print(f'downloading {pin["url"]}', flush=True) - urllib.request.urlretrieve(pin['url'], archive) + # the URLs are the https constants in PINNED, and the SHA-256 is checked below + urllib.request.urlretrieve(pin['url'], archive) # nosec B310 with open(archive, 'rb') as f: digest = hashlib.sha256(f.read()).hexdigest() if digest != pin['sha256']: @@ -160,7 +164,7 @@ def download_library(name, work): with tarfile.open(archive) as t: # (the 'data' filter rejects links and paths outside the target where Python has it) kwargs = {'filter': 'data'} if hasattr(tarfile, 'data_filter') else {} - t.extractall(os.path.join(work, 'download'), **kwargs) # noqa: S202 (checked archive) + t.extractall(os.path.join(work, 'download'), **kwargs) # noqa: S202 (checked archive) # nosec B202 if name == 'yyjson': return Library(name, [os.path.join(src, 'src')], [os.path.join(src, 'src', 'yyjson.c')], [], pin['version']) if name == 'simdjson':