Spaces:
Runtime error
Runtime error
Lars Talian commited on
Commit ·
e8df2e1
1
Parent(s): 4c52b20
Harden TemplateOnlyBuilder difficulty bounds
Browse files- Clamp malformed min/max vulns to safe bounds
- Preserve at least one selected vulnerability
- Add regression coverage for non-schema difficulty envelopes
- src/open_range/builder/builder.py +8 -3
- tests/test_builder.py +16 -0
src/open_range/builder/builder.py
CHANGED
|
@@ -963,9 +963,14 @@ class TemplateOnlyBuilder:
|
|
| 963 |
avg_extra = 4
|
| 964 |
tier_max_vulns = max(1, 1 + (max_steps_hi - avg_first) // avg_extra)
|
| 965 |
|
| 966 |
-
|
| 967 |
-
|
| 968 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 969 |
effective_min = min(min_vulns, effective_max)
|
| 970 |
count = rng.randint(effective_min, effective_max)
|
| 971 |
chosen = rng.sample(candidates, count)
|
|
|
|
| 963 |
avg_extra = 4
|
| 964 |
tier_max_vulns = max(1, 1 + (max_steps_hi - avg_first) // avg_extra)
|
| 965 |
|
| 966 |
+
max_v_raw = manifest.get("difficulty", {}).get("max_vulns", 2)
|
| 967 |
+
min_v_raw = manifest.get("difficulty", {}).get("min_vulns", 1)
|
| 968 |
+
max_vulns = max(1, int(max_v_raw))
|
| 969 |
+
min_vulns = max(1, int(min_v_raw))
|
| 970 |
+
if min_vulns > max_vulns:
|
| 971 |
+
min_vulns = max_vulns
|
| 972 |
+
|
| 973 |
+
effective_max = max(1, min(max_vulns, tier_max_vulns, len(candidates)))
|
| 974 |
effective_min = min(min_vulns, effective_max)
|
| 975 |
count = rng.randint(effective_min, effective_max)
|
| 976 |
chosen = rng.sample(candidates, count)
|
tests/test_builder.py
CHANGED
|
@@ -82,6 +82,22 @@ async def test_template_builder_clamps_min_vulns_to_candidate_pool(tier1_manifes
|
|
| 82 |
assert all(v.type == "sqli" for v in spec.truth_graph.vulns)
|
| 83 |
|
| 84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
@pytest.mark.asyncio
|
| 86 |
async def test_template_builder_avoids_previous_vulns(tier1_manifest):
|
| 87 |
from open_range.builder.builder import TemplateOnlyBuilder
|
|
|
|
| 82 |
assert all(v.type == "sqli" for v in spec.truth_graph.vulns)
|
| 83 |
|
| 84 |
|
| 85 |
+
@pytest.mark.asyncio
|
| 86 |
+
async def test_template_builder_handles_non_schema_difficulty_bounds(tier1_manifest):
|
| 87 |
+
from open_range.builder.builder import TemplateOnlyBuilder
|
| 88 |
+
|
| 89 |
+
builder = TemplateOnlyBuilder()
|
| 90 |
+
manifest = {
|
| 91 |
+
**tier1_manifest,
|
| 92 |
+
"bug_families": ["sqli"],
|
| 93 |
+
"difficulty": {**tier1_manifest.get("difficulty", {}), "min_vulns": -2, "max_vulns": 0},
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
spec = await builder.build(manifest, BuildContext(seed=9, tier=1))
|
| 97 |
+
assert len(spec.truth_graph.vulns) == 1
|
| 98 |
+
assert spec.truth_graph.vulns[0].type == "sqli"
|
| 99 |
+
|
| 100 |
+
|
| 101 |
@pytest.mark.asyncio
|
| 102 |
async def test_template_builder_avoids_previous_vulns(tier1_manifest):
|
| 103 |
from open_range.builder.builder import TemplateOnlyBuilder
|