wave6a/6b: elasticsearch/opensearch/solr/llvm-0004-5/linux-0005-6/gcc-0002/tokio/actix-web + love2d/raylib new defects
This commit is contained in:
parent
a4b0cf4edd
commit
3eebda37e1
38 changed files with 3651 additions and 0 deletions
233
defects/tokio/unit/AnyDelimiterCodecTest.java
Normal file
233
defects/tokio/unit/AnyDelimiterCodecTest.java
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for tokio-0001: CWE-407 in AnyDelimiterCodec.
|
||||
*
|
||||
* tokio-0001 (HIGH):
|
||||
* File: tokio-util/src/codec/any_delimiter_codec.rs:146
|
||||
* Symbol: AnyDelimiterCodec::decode — Vec<u8>::contains() called per buffer byte
|
||||
* Defect: For each byte in the receive buffer (N bytes), the codec calls
|
||||
* seek_delimiters.contains(b) which is a linear scan over D delimiter
|
||||
* bytes: O(D) per byte, O(N×D) total per decode call.
|
||||
* Fix: At construction time, convert seek_delimiters into a [bool; 256]
|
||||
* lookup table. Each check becomes delimiter_table[b as usize]: O(1).
|
||||
*
|
||||
* Modeled here in Java:
|
||||
* Rust Vec<u8>::contains() ≡ boolean[] linear scan (defective)
|
||||
* Rust [bool; 256] indexing ≡ boolean[] direct index (fixed)
|
||||
* Comparison counts tracked at the membership-test site.
|
||||
*
|
||||
* Expected at N=4096 bytes, D=16 delimiters:
|
||||
* defective comparisons = N × D = 65,536
|
||||
* fixed comparisons = N = 4,096
|
||||
* ratio = 16×
|
||||
*/
|
||||
public class AnyDelimiterCodecTest {
|
||||
|
||||
// =========================================================================
|
||||
// tokio-0001 model: per-byte delimiter check, Vec linear scan vs lookup table
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* Defective decoder: for each byte in the buffer, scan the delimiter list
|
||||
* linearly (Vec<u8>::contains).
|
||||
*
|
||||
* Returns the index of the first delimiter byte found, or -1.
|
||||
* comparisons counts every element examined during scans.
|
||||
*/
|
||||
static class DefectiveDecoder {
|
||||
final byte[] delimiters;
|
||||
long comparisons = 0;
|
||||
|
||||
DefectiveDecoder(byte[] delimiters) {
|
||||
this.delimiters = delimiters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan buf[0..len) for any delimiter byte.
|
||||
* For each byte b: linearly scan delimiters (O(D) per byte).
|
||||
*/
|
||||
int findFirstDelimiter(byte[] buf, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte b = buf[i];
|
||||
// Vec<u8>::contains(b) — O(D) linear scan
|
||||
for (int d = 0; d < delimiters.length; d++) {
|
||||
comparisons++;
|
||||
if (delimiters[d] == b) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed decoder: pre-built boolean[256] lookup table at construction time.
|
||||
* For each byte b: delimiter_table[b & 0xFF] — O(1).
|
||||
* comparisons counts one operation per byte checked.
|
||||
*/
|
||||
static class FixedDecoder {
|
||||
final boolean[] delimiterTable = new boolean[256];
|
||||
long comparisons = 0;
|
||||
|
||||
FixedDecoder(byte[] delimiters) {
|
||||
for (byte d : delimiters) {
|
||||
delimiterTable[d & 0xFF] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan buf[0..len) for any delimiter byte using the lookup table.
|
||||
*/
|
||||
int findFirstDelimiter(byte[] buf, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
comparisons++; // one array-index lookup per byte
|
||||
if (delimiterTable[buf[i] & 0xFF]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Tests
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* Test 1 — Correctness: defective and fixed decoders agree on first delimiter position.
|
||||
*
|
||||
* Buffer: bytes 0..127 sequentially. Delimiters: {10, 44, 59} (\n , ;).
|
||||
* First delimiter in the buffer should be byte value 10 at position 10.
|
||||
*/
|
||||
static void testCorrectnessMatch() {
|
||||
byte[] delimiters = {10, 44, 59}; // \n , ;
|
||||
byte[] buf = new byte[128];
|
||||
for (int i = 0; i < 128; i++) buf[i] = (byte) i;
|
||||
|
||||
DefectiveDecoder def = new DefectiveDecoder(delimiters);
|
||||
FixedDecoder fix = new FixedDecoder(delimiters);
|
||||
|
||||
int defPos = def.findFirstDelimiter(buf, buf.length);
|
||||
int fixPos = fix.findFirstDelimiter(buf, buf.length);
|
||||
|
||||
assert defPos == fixPos
|
||||
: "position mismatch: defective=" + defPos + " fixed=" + fixPos;
|
||||
assert defPos == 10
|
||||
: "expected delimiter at position 10 (\\n); got " + defPos;
|
||||
|
||||
System.out.println("PASS testCorrectnessMatch");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 2 — No delimiter: both decoders return -1 when no delimiter present.
|
||||
*
|
||||
* Buffer filled with 0xFF (non-delimiter). Delimiters: {10, 44, 59}.
|
||||
*/
|
||||
static void testNoDelimiterFound() {
|
||||
byte[] delimiters = {10, 44, 59};
|
||||
int N = 1024;
|
||||
byte[] buf = new byte[N];
|
||||
Arrays.fill(buf, (byte) 0xFF);
|
||||
|
||||
DefectiveDecoder def = new DefectiveDecoder(delimiters);
|
||||
FixedDecoder fix = new FixedDecoder(delimiters);
|
||||
|
||||
int defPos = def.findFirstDelimiter(buf, N);
|
||||
int fixPos = fix.findFirstDelimiter(buf, N);
|
||||
|
||||
assert defPos == -1 : "defective should return -1; got " + defPos;
|
||||
assert fixPos == -1 : "fixed should return -1; got " + fixPos;
|
||||
|
||||
// Defective scanned all N×D pairs; fixed scanned N
|
||||
assert def.comparisons == (long) N * delimiters.length
|
||||
: "defective comparisons should be N*D=" + (long) N * delimiters.length
|
||||
+ "; got " + def.comparisons;
|
||||
assert fix.comparisons == N
|
||||
: "fixed comparisons should be N=" + N + "; got " + fix.comparisons;
|
||||
|
||||
System.out.println("PASS testNoDelimiterFound");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 3 — tokio-0001: O(N×D) vs O(N) ratio at N=4096, D=16.
|
||||
*
|
||||
* Worst-case: buffer contains no delimiter bytes (full scan).
|
||||
* Defective: 4096 × 16 = 65,536 comparisons.
|
||||
* Fixed: 4,096 comparisons.
|
||||
* Ratio: 16×.
|
||||
*/
|
||||
static void testRatioAtScale() {
|
||||
int N = 4096;
|
||||
int D = 16;
|
||||
byte[] delimiters = new byte[D];
|
||||
// Use bytes 128..143 as delimiters — none appear in the buffer (filled with 0)
|
||||
for (int i = 0; i < D; i++) delimiters[i] = (byte) (128 + i);
|
||||
|
||||
byte[] buf = new byte[N]; // all zeros — no delimiter matches
|
||||
|
||||
DefectiveDecoder def = new DefectiveDecoder(delimiters);
|
||||
FixedDecoder fix = new FixedDecoder(delimiters);
|
||||
|
||||
def.findFirstDelimiter(buf, N);
|
||||
fix.findFirstDelimiter(buf, N);
|
||||
|
||||
long expectedDef = (long) N * D;
|
||||
long expectedFix = N;
|
||||
|
||||
assert def.comparisons == expectedDef
|
||||
: "defective comparisons should be N*D=" + expectedDef
|
||||
+ "; got " + def.comparisons;
|
||||
assert fix.comparisons == expectedFix
|
||||
: "fixed comparisons should be N=" + expectedFix
|
||||
+ "; got " + fix.comparisons;
|
||||
|
||||
double ratio = (double) def.comparisons / fix.comparisons;
|
||||
assert ratio >= D
|
||||
: "ratio should be >= D=" + D + "; got " + ratio;
|
||||
|
||||
System.out.printf(
|
||||
"PASS testRatioAtScale (N=%d D=%d defective=%d fixed=%d ratio=%.1fx)%n",
|
||||
N, D, def.comparisons, fix.comparisons, ratio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 4 — Delimiter at start: both return position 0 immediately.
|
||||
*
|
||||
* Buffer starts with a delimiter byte.
|
||||
*/
|
||||
static void testDelimiterAtStart() {
|
||||
byte[] delimiters = {(byte) 0xAB};
|
||||
byte[] buf = {(byte) 0xAB, 0, 1, 2, 3};
|
||||
|
||||
DefectiveDecoder def = new DefectiveDecoder(delimiters);
|
||||
FixedDecoder fix = new FixedDecoder(delimiters);
|
||||
|
||||
assert def.findFirstDelimiter(buf, buf.length) == 0
|
||||
: "defective should find delimiter at position 0";
|
||||
assert fix.findFirstDelimiter(buf, buf.length) == 0
|
||||
: "fixed should find delimiter at position 0";
|
||||
|
||||
// Defective: 1 comparison (found on first byte, first delimiter)
|
||||
assert def.comparisons == 1
|
||||
: "defective should make 1 comparison; got " + def.comparisons;
|
||||
// Fixed: 1 lookup
|
||||
assert fix.comparisons == 1
|
||||
: "fixed should make 1 comparison; got " + fix.comparisons;
|
||||
|
||||
System.out.println("PASS testDelimiterAtStart");
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
testCorrectnessMatch();
|
||||
testNoDelimiterFound();
|
||||
testRatioAtScale();
|
||||
testDelimiterAtStart();
|
||||
System.out.println("4/4 PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue