diff --git a/src/core/jsonschema/known_resolver.cmake b/src/core/jsonschema/known_resolver.cmake index 7ffe0dd31..5f0a06904 100644 --- a/src/core/jsonschema/known_resolver.cmake +++ b/src/core/jsonschema/known_resolver.cmake @@ -96,9 +96,23 @@ file(READ "${OPENAPI_3_1_DIR}/meta/2024-10-25" OPENAPI_OAS_3_1_META_2024_10_25) file(READ "${OPENAPI_3_1_DIR}/dialect/2024-10-25" OPENAPI_OAS_3_1_DIALECT_2024_10_25) # OpenAPI v3.0 +# The Schema Object is only published as a definition of the document schema, +# so a dialect for it has to carry that definition along with the ones it +# reaches. Taking those alone leaves behind a document schema that is longer +# than what the strictest compiler allows a single string literal to be set(OPENAPI_3_0_DIR "${PROJECT_SOURCE_DIR}/vendor/openapi/oas/3.0") -file(READ "${OPENAPI_3_0_DIR}/schema/2024-10-18" OPENAPI_OAS_3_0_SCHEMA_2024_10_18) -file(READ "${OPENAPI_3_0_DIR}/schema/2021-09-28" OPENAPI_OAS_3_0_SCHEMA_2021_09_28) +file(READ "${OPENAPI_3_0_DIR}/schema/2024-10-18" OPENAPI_OAS_3_0_DOCUMENT) +string(JSON OPENAPI_OAS_3_0_SCHEMA_2024_10_18 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Schema) +string(JSON OPENAPI_OAS_3_0_REFERENCE_2024_10_18 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Reference) +string(JSON OPENAPI_OAS_3_0_DISCRIMINATOR_2024_10_18 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Discriminator) +string(JSON OPENAPI_OAS_3_0_EXTERNAL_DOCUMENTATION_2024_10_18 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions ExternalDocumentation) +string(JSON OPENAPI_OAS_3_0_XML_2024_10_18 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions XML) +file(READ "${OPENAPI_3_0_DIR}/schema/2021-09-28" OPENAPI_OAS_3_0_DOCUMENT) +string(JSON OPENAPI_OAS_3_0_SCHEMA_2021_09_28 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Schema) +string(JSON OPENAPI_OAS_3_0_REFERENCE_2021_09_28 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Reference) +string(JSON OPENAPI_OAS_3_0_DISCRIMINATOR_2021_09_28 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions Discriminator) +string(JSON OPENAPI_OAS_3_0_EXTERNAL_DOCUMENTATION_2021_09_28 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions ExternalDocumentation) +string(JSON OPENAPI_OAS_3_0_XML_2021_09_28 GET "${OPENAPI_OAS_3_0_DOCUMENT}" definitions XML) if(NOT KNOWN_RESOLVER_INPUT) message(FATAL_ERROR "Missing KNOWN_RESOLVER_INPUT") diff --git a/src/core/jsonschema/known_resolver.in.cc b/src/core/jsonschema/known_resolver.in.cc index f490756bc..cd5b48456 100644 --- a/src/core/jsonschema/known_resolver.in.cc +++ b/src/core/jsonschema/known_resolver.in.cc @@ -767,11 +767,11 @@ auto sourcemeta::core::schema_resolver(const std::string_view identifier) return SCHEMA; } // The published document schema describes the Schema Object as one of its - // definitions rather than on its own, and nothing else of it is of use - // here, so it is carried within the dialect instead of being exposed. The - // identifier it declares has to stay for the references it makes to - // itself to keep resolving against its own scope. Note a schema of this - // dialect is either a Schema Object or a Reference Object + // definitions rather than on its own, so the dialect carries that + // definition and the ones it reaches instead of the document being + // exposed. They stay under the identifier the document declares, as that + // is the scope the references between them resolve against. Note a schema + // of this dialect is either a Schema Object or a Reference Object case KnownSchema::OAS_3_0_DIALECT_2024_10_18: { static const auto SCHEMA{sourcemeta::core::parse_json(R"EOF({ "id": "tag:spec.openapis.org,2024-10-18:oas/3.0/dialect", @@ -782,7 +782,17 @@ auto sourcemeta::core::schema_resolver(const std::string_view identifier) { "$ref": "#/definitions/openapi/definitions/Reference" } ], "definitions": { - "openapi": @OPENAPI_OAS_3_0_SCHEMA_2024_10_18@ + "openapi": { + "id": "https://spec.openapis.org/oas/3.0/schema/2024-10-18", + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "Schema": @OPENAPI_OAS_3_0_SCHEMA_2024_10_18@, + "Reference": @OPENAPI_OAS_3_0_REFERENCE_2024_10_18@, + "Discriminator": @OPENAPI_OAS_3_0_DISCRIMINATOR_2024_10_18@, + "ExternalDocumentation": @OPENAPI_OAS_3_0_EXTERNAL_DOCUMENTATION_2024_10_18@, + "XML": @OPENAPI_OAS_3_0_XML_2024_10_18@ + } + } } })EOF")}; return SCHEMA; @@ -797,7 +807,17 @@ auto sourcemeta::core::schema_resolver(const std::string_view identifier) { "$ref": "#/definitions/openapi/definitions/Reference" } ], "definitions": { - "openapi": @OPENAPI_OAS_3_0_SCHEMA_2021_09_28@ + "openapi": { + "id": "https://spec.openapis.org/oas/3.0/schema/2021-09-28", + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "Schema": @OPENAPI_OAS_3_0_SCHEMA_2021_09_28@, + "Reference": @OPENAPI_OAS_3_0_REFERENCE_2021_09_28@, + "Discriminator": @OPENAPI_OAS_3_0_DISCRIMINATOR_2021_09_28@, + "ExternalDocumentation": @OPENAPI_OAS_3_0_EXTERNAL_DOCUMENTATION_2021_09_28@, + "XML": @OPENAPI_OAS_3_0_XML_2021_09_28@ + } + } } })EOF")}; return SCHEMA; diff --git a/src/lang/numeric/big_coefficient.h b/src/lang/numeric/big_coefficient.h index 1817e44b6..76263d35e 100644 --- a/src/lang/numeric/big_coefficient.h +++ b/src/lang/numeric/big_coefficient.h @@ -110,7 +110,10 @@ constexpr std::int64_t COMPACT_MAX = class BigCoefficient { static constexpr std::uint32_t INLINE_CAPACITY = 4; - std::array inline_words_; + // Every limb of the store stays written, and the ones at or past the length + // stay zero, which is what lets a value of fewer limbs than the store holds + // be read a limb at a time without reaching for one that was never written + std::array inline_words_{}; [[nodiscard]] auto is_inline() const -> bool { return this->capacity <= INLINE_CAPACITY; @@ -129,7 +132,6 @@ class BigCoefficient { if (requested_capacity <= INLINE_CAPACITY) { this->words = this->inline_words_.data(); this->capacity = INLINE_CAPACITY; - this->inline_words_.fill(0); } else { this->words = new std::uint64_t[requested_capacity](); this->capacity = requested_capacity; @@ -145,15 +147,14 @@ class BigCoefficient { BigCoefficient(BigCoefficient &&other) noexcept : length{other.length}, capacity{other.capacity} { if (other.is_inline()) { - std::copy(other.inline_words_.data(), - other.inline_words_.data() + other.length, - this->inline_words_.data()); + this->inline_words_ = other.inline_words_; this->words = this->inline_words_.data(); } else { this->words = other.words; other.words = other.inline_words_.data(); } + other.inline_words_.fill(0); other.length = 0; other.capacity = INLINE_CAPACITY; } @@ -167,15 +168,14 @@ class BigCoefficient { this->length = other.length; this->capacity = other.capacity; if (other.is_inline()) { - std::copy(other.inline_words_.data(), - other.inline_words_.data() + other.length, - this->inline_words_.data()); + this->inline_words_ = other.inline_words_; this->words = this->inline_words_.data(); } else { this->words = other.words; other.words = other.inline_words_.data(); } + other.inline_words_.fill(0); other.length = 0; other.capacity = INLINE_CAPACITY; } @@ -260,6 +260,9 @@ class BigCoefficient { std::copy(this->words + zero_words, this->words + this->length, this->words); this->length -= zero_words; + // What the shift leaves behind is no longer part of the value + std::fill(this->words + this->length, + this->words + this->length + zero_words, 0ULL); total_stripped += static_cast(zero_words) * BASE_DIGITS; }