Tighten RSBK package-format validation for review remediation
Reject NUL/control bytes and Windows-hostile names in entry names, relax the over-broad ".." substring ban to component-only, close the trailing-garbage gap on empty manifests, and relocate the package CMake subdirectory to its ladder home.
This commit is contained in:
@@ -102,13 +102,14 @@ static void testEmptyManifestRoundTrips() {
|
||||
// --- forward compatibility ---------------------------------------------------
|
||||
|
||||
static void testUnknownKeysSkippedAtEveryLevel() {
|
||||
// A future additive manifest: unknown keys at the root and inside an entry.
|
||||
// A future additive manifest: unknown keys at the root, inside an entry,
|
||||
// and inside the nested index blob itself.
|
||||
const std::string json =
|
||||
"{\"bankName\":\"B\",\"exported\":7,"
|
||||
"\"instrumentState\":{\"nested\":[1,2,{\"x\":\"y\"}]},"
|
||||
"\"entries\":[{\"name\":\"a.wav\",\"length\":10,\"hash\":\"h\","
|
||||
"\"futureField\":\"ignored\","
|
||||
"\"index\":{\"version\":1,\"samples\":[{\"id\":\"s1\","
|
||||
"\"index\":{\"version\":1,\"futureIndexField\":42,\"samples\":[{\"id\":\"s1\","
|
||||
"\"relativePath\":\"bank/a.wav\"}]}}],"
|
||||
"\"slots\":[],\"trailingUnknown\":null}";
|
||||
auto m = deserializeManifest(json);
|
||||
@@ -159,6 +160,17 @@ static void testDuplicateEntryNamesRejectedBothWays() {
|
||||
CHECK(!deserializeManifest(dup).has_value());
|
||||
}
|
||||
|
||||
static void testDuplicateEntriesKeyRejected() {
|
||||
// A repeated "entries" key must not accumulate into two arrays' worth of
|
||||
// entries — reject rather than silently union them.
|
||||
const std::string json =
|
||||
"{\"entries\":[{\"name\":\"a.wav\",\"length\":1,\"hash\":\"h\","
|
||||
"\"index\":{\"version\":1,\"samples\":[{\"id\":\"s1\",\"relativePath\":\"p\"}]}}],"
|
||||
"\"entries\":[{\"name\":\"b.wav\",\"length\":1,\"hash\":\"h\","
|
||||
"\"index\":{\"version\":1,\"samples\":[{\"id\":\"s2\",\"relativePath\":\"q\"}]}}]}";
|
||||
CHECK(!deserializeManifest(json).has_value());
|
||||
}
|
||||
|
||||
// --- rejection: structural ---------------------------------------------------
|
||||
|
||||
static void testEncodeRejectsUnrepresentableSample() {
|
||||
@@ -223,6 +235,10 @@ static void testDecodeRejectsMalformedShapes() {
|
||||
auto json = serializeManifest(fixture());
|
||||
CHECK(json.has_value());
|
||||
CHECK(!deserializeManifest(*json + "x").has_value());
|
||||
// Trailing garbage after the EMPTY-object shortcut specifically: this path
|
||||
// returned early before reaching the eof check, so "{}JUNK" parsed valid.
|
||||
CHECK(!deserializeManifest("{}JUNK").has_value());
|
||||
CHECK(deserializeManifest("{}").has_value());
|
||||
// Truncation at a few JSON-level offsets (byte-level truncation of the whole
|
||||
// package is bank_package's suite).
|
||||
CHECK(!deserializeManifest(json->substr(0, json->size() / 2)).has_value());
|
||||
@@ -236,6 +252,7 @@ int main() {
|
||||
testEncodeRejectsBadEntryName();
|
||||
testDecodeRejectsBadEntryName();
|
||||
testDuplicateEntryNamesRejectedBothWays();
|
||||
testDuplicateEntriesKeyRejected();
|
||||
testEncodeRejectsUnrepresentableSample();
|
||||
testDecodeRejectsMalformedShapes();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user