|
57 | 57 | * <p>Set {@link #SAVE_GENERATED_FILES} to true to enable file preservation under |
58 | 58 | * {@code parquet-variant/target/test-hardened-reader}; return it to false to |
59 | 59 | * restore cleanup. Each file will be saved with the name of the test. |
60 | | - * . |
61 | 60 | */ |
62 | 61 | public class TestHardenedReader { |
63 | 62 |
|
@@ -109,6 +108,33 @@ public void testOutOfRangeChildOffset() throws IOException { |
109 | 108 | expectRoundTripRaisesIllegalArgument(EMPTY_METADATA, value, "child offset"); |
110 | 109 | } |
111 | 110 |
|
| 111 | + /** |
| 112 | + * A zero-length child element is not a valid encoded Variant value. The spec requires every |
| 113 | + * array/object element to carry a mandatory 1-byte value header (value_data may be empty, but the |
| 114 | + * header may not). An offset that leaves no bytes for the child has no header to read, so the |
| 115 | + * top-level array constructs, but materializing the empty element fails to parse. |
| 116 | + */ |
| 117 | + @Test |
| 118 | + public void testEmptyChildElement() { |
| 119 | + // Array, numElements=1, offsets [0, 0], empty data region. |
| 120 | + // [0] 0b0011 arrayHeader(largeSize=false, offsetSize=1) |
| 121 | + // [1] 0x01 numElements = 1 |
| 122 | + // [2] 0x00 offset[0] = 0 |
| 123 | + // [3] 0x00 offset[1] = 0 (terminator: data region length = 0) |
| 124 | + // The single element points at offset 0 of a zero-length data region: no header byte exists. |
| 125 | + byte[] value = {0b0011, 0x01, 0x00, 0x00}; |
| 126 | + Variant top = new Variant(ByteBuffer.wrap(value), ByteBuffer.wrap(EMPTY_METADATA)); |
| 127 | + |
| 128 | + // The container itself is well-formed and constructs. |
| 129 | + assertThat(top.getType()).isEqualTo(Variant.Type.ARRAY); |
| 130 | + assertThat(top.numArrayElements()).isEqualTo(1); |
| 131 | + |
| 132 | + // Materializing the empty element fails: there is no value header to read. |
| 133 | + assertThatThrownBy(() -> top.getElementAtIndex(0)) |
| 134 | + .isInstanceOf(IllegalArgumentException.class) |
| 135 | + .hasMessageContaining("variant value is empty"); |
| 136 | + } |
| 137 | + |
112 | 138 | /** |
113 | 139 | * Reject numElements larger than the surrounding buffer. |
114 | 140 | */ |
|
0 commit comments