Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/NitroValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,17 @@ contract NitroValidator {
// be present (do not silently stop at the payload end on a missing break), and stop
// exclusively on it.
require(current.end() < end, "missing break marker");
if (uint8(attestationTbs[current.end()]) == 0xff) break;
if (uint8(attestationTbs[current.end()]) == 0xff) {
require(current.end() + 1 == end, "trailing payload bytes");
break;
}
} else {
// A definite-length map ends after exactly `entryCount` entries; a stray 0xFF must
// not terminate it early (it would be parsed as a key and rejected as a non-string).
if (entry == entryCount) break;
if (entry == entryCount) {
require(current.end() == end, "trailing payload bytes");
break;
}
}
current = attestationTbs.nextTextString(current);
bytes32 keyHash = attestationTbs.keccak(current);
Expand Down
16 changes: 16 additions & 0 deletions test/IndefiniteLengthCbor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,22 @@ contract NitroValidatorIndefiniteLengthTest is Test {
validator.parseAttestation(tbs);
}

/// @dev Definite-length outer maps must consume the whole payload byte string; trailing bytes
/// after the declared entries are malformed, even if the declared prefix parses cleanly.
function test_neg_definiteOuterMapTrailingBytes_reverts() public {
bytes memory tbs = _buildTbs(abi.encodePacked(hex"a2", _partialEntries(), hex"00"));
vm.expectRevert("trailing payload bytes");
validator.parseAttestation(tbs);
}

/// @dev Indefinite-length outer maps must end immediately after their 0xFF break marker; bytes
/// after the break are not silently ignored.
function test_neg_indefiniteOuterMapTrailingBytesAfterBreak_reverts() public {
bytes memory tbs = _buildTbs(abi.encodePacked(CBOR_MAP_INDEFINITE, _partialEntries(), CBOR_BREAK, hex"00"));
vm.expectRevert("trailing payload bytes");
validator.parseAttestation(tbs);
}

/// @dev Empty indefinite-length inner cabundle array ([0x9F, 0xFF]) parses as an
/// empty cabundle and the outer loop continues.
function test_nestedIndefiniteEmptyArray_parses() public view {
Expand Down
Loading