From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- security/nss/gtests/pk11_gtest/json_reader.h | 140 +++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 security/nss/gtests/pk11_gtest/json_reader.h (limited to 'security/nss/gtests/pk11_gtest/json_reader.h') diff --git a/security/nss/gtests/pk11_gtest/json_reader.h b/security/nss/gtests/pk11_gtest/json_reader.h new file mode 100644 index 0000000000..ed4d9bb892 --- /dev/null +++ b/security/nss/gtests/pk11_gtest/json_reader.h @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef PK11GTEST_JSON_H_ +#define PK11GTEST_JSON_H_ + +#include +#include +#include +#include "gtest/gtest.h" +#include "nss_scoped_ptrs.h" +#include "secoidt.h" + +// If we make a few assumptions about the file, parsing JSON can be easy. +// This is not a full parser, it only works on a narrow set of inputs. +class JsonReader { + public: + JsonReader(const std::string& n); + + void next() { i_++; } + uint8_t peek() { + TopUp(); + return buf_[i_]; + } + uint8_t take() { + uint8_t v = peek(); + next(); + return v; + } + + // No input checking, overflow protection, or any safety. + // Returns 0 if there isn't a number here rather than aborting. + uint64_t ReadInt(); + // No input checking, no unicode, no escaping (not even \"), just read ASCII. + std::string ReadString(); + std::string ReadLabel(); + std::vector ReadHex(); + SECOidTag ReadHash(); + SECStatus ReadSECStatus(); + bool ReadBool(); + + bool NextItem(uint8_t h = '{', uint8_t t = '}'); + bool NextItemArray() { return NextItem('[', ']'); } + void SkipValue(); + + private: + void TopUp(); + void SkipWhitespace(); + // This only handles lowercase. + uint8_t Hex(uint8_t c); + + ScopedPRFileDesc f_; + uint8_t buf_[4096]; + size_t available_; + size_t i_; +}; + +// The way this is expected to work is that this reads the header, then +// passes off the content of each "testGroups" member to `group_handler`. +// That function processes any attributes in that structure, calls +// `WycheproofReadTests` to load individual cases and runs those tests. +void WycheproofHeader(const std::string& name, const std::string& algorithm, + const std::string& schema, + std::function group_handler); + +template +struct id { + typedef T type; +}; + +template +using nondeduced = typename id::type; + +// Read into a block of test cases, handling standard attributes on Wycheproof +// tests. +// +// `T` needs `uint64_t id` and `bool valid` fields. +// `attr_reader` is responsible for reading values into the test case struct. +// `acceptable` determines whether a test marked "acceptable" is valid by +// default. `process_flags` allows for processing the flags on an entry. +// +// Note that this gathers all tests into a vector rather than running tests as +// they arrive. This is necessary because the testGroup JSON struct might have +// fields that haven't been read when this list is constructed (it doesn't in +// the current files, but this is not guaranteed). Tests can only run after all +// of the group attributes have been read and processed. +template +void WycheproofReadTests( + JsonReader& r, std::vector* tests, + const std::function>& + attr_reader, + bool acceptable = true, + const std::function&)>>& + process_flags = nullptr) { + while (r.NextItemArray()) { + T tc; + std::string comment; + std::string result; + std::vector flags; + + while (r.NextItem()) { + std::string n = r.ReadLabel(); + if (n == "") { + break; + } + if (n == "tcId") { + tc.id = r.ReadInt(); + } else if (n == "result") { + result = r.ReadString(); + } else if (n == "comment") { + comment = r.ReadString(); + } else if (n == "flags") { + while (r.NextItemArray()) { + flags.push_back(r.ReadString()); + } + } else { + ASSERT_NO_FATAL_FAILURE(attr_reader(tc, n, r)); + } + } + + tc.valid = (result == "valid") || (acceptable && result == "acceptable"); + if (process_flags) { + process_flags(tc, result, flags); + } + + std::cout << " tc " << tc.id << ": " << comment << " [" << result; + for (auto& f : flags) { + std::cout << ", " << f; + } + std::cout << "] expect " << (tc.valid ? "success" : "failure") << std::endl; + + tests->push_back(tc); + } +} + +#endif // PK11GTEST_JSON_H_ -- cgit v1.2.3