style(all): reformat long lines across files for improved code readability and alignment of nested structures

This commit is contained in:
elipeter 2026-06-01 19:54:28 -05:00
parent e64fb25dae
commit 9914d26bdf
20 changed files with 229 additions and 182 deletions

View file

@ -216,13 +216,6 @@ jobs:
rust-stable-test-linux-with-docker:
name: rust-stable-test / linux-with-docker
runs-on: ubuntu-latest
services:
docker:
image: docker:dind
options: --privileged
env:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
steps:
- uses: actions/checkout@v6
@ -253,13 +246,6 @@ jobs:
escape-positive-control:
name: escape-positive-control
runs-on: ubuntu-latest
services:
docker:
image: docker:dind
options: --privileged
env:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
steps:
- uses: actions/checkout@v6
@ -364,16 +350,18 @@ jobs:
cache: true
cache-key: benchmark-gate-release
- uses: taiki-e/install-action@nextest
- name: Build benchmark + perf test binaries
run: cargo test --release --all-features --test benchmark_test --test perf_tests --no-run
run: cargo nextest run --release --all-features --test benchmark_test --test perf_tests --no-run
- name: Accuracy regression gate (P/R/F1)
run: cargo test --release --all-features --test benchmark_test -- --ignored --nocapture benchmark_evaluation
run: cargo nextest run --release --all-features --test benchmark_test --run-ignored only --no-capture benchmark_evaluation
- name: Performance regression gate
env:
NYX_CI_BENCH: "1"
run: cargo test --release --all-features --test perf_tests -- --nocapture
run: cargo nextest run --release --all-features --test perf_tests --no-capture
- name: Upload benchmark results
if: always()
@ -404,6 +392,8 @@ jobs:
toolchain: stable
cache: true
- uses: taiki-e/install-action@nextest
- name: Corpus unit tests (no_marker_collisions, all_payloads_have_fixture_paths)
run: cargo nextest run --lib -p nyx-scanner dynamic::corpus
env:

View file

@ -111,18 +111,18 @@ jobs:
body_file=$(mktemp)
cat > "$body_file" <<'PREAMBLE'
## Corpus Promotion Proposal
## Corpus Promotion Proposal
This PR was generated automatically by the weekly corpus-promote workflow.
It does **not** auto-merge — a human reviewer must approve each candidate
before it can land in `src/dynamic/corpus.rs` (§16.4).
This PR was generated automatically by the weekly corpus-promote workflow.
It does **not** auto-merge — a human reviewer must approve each candidate
before it can land in `src/dynamic/corpus.rs` (§16.4).
### Candidates
### Candidates
The following payloads were discovered by the internal mutation fuzzer and
confirmed via `sink_hit && oracle_fired` against instrumented fixtures:
The following payloads were discovered by the internal mutation fuzzer and
confirmed via `sink_hit && oracle_fired` against instrumented fixtures:
PREAMBLE
PREAMBLE
for f in $CANDIDATE_FILES; do
sidecar="${f}.json"
@ -136,16 +136,16 @@ PREAMBLE
cat >> "$body_file" <<'CHECKLIST'
### Review checklist
### Review checklist
- [ ] Bytes are a genuine attack vector, not a fixture artifact
- [ ] Oracle marker is unique (no collision with other caps)
- [ ] `fixture_paths` updated in `src/dynamic/corpus.rs`
- [ ] `since_corpus_version` set to next version
- [ ] `CORPUS_VERSION` bumped and bump history updated
- [ ] Bytes are a genuine attack vector, not a fixture artifact
- [ ] Oracle marker is unique (no collision with other caps)
- [ ] `fixture_paths` updated in `src/dynamic/corpus.rs`
- [ ] `since_corpus_version` set to next version
- [ ] `CORPUS_VERSION` bumped and bump history updated
_Generated by corpus_promote.yml — do not auto-merge._
CHECKLIST
_Generated by corpus_promote.yml — do not auto-merge._
CHECKLIST
git add fuzz-discovered/ || true
git diff --cached --quiet || git commit -m "chore: add ${CANDIDATE_COUNT} fuzzer-discovered corpus candidates"

View file

@ -13,7 +13,7 @@
# chroot-leg of the escape suite skips silently
# (Phase 20 follow-up #4 in deferred.md).
#
# linux-with-docker — Ubuntu host with docker-in-docker. Exercises
# linux-with-docker — Ubuntu host with the runner Docker daemon. Exercises
# the docker backend (Phase 19) and the
# differential-confirmation parity tests.
#
@ -79,13 +79,6 @@ jobs:
linux-with-docker:
name: dynamic / linux-with-docker
runs-on: ubuntu-latest
services:
docker:
image: docker:dind
options: --privileged
env:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
steps:
- uses: actions/checkout@v6

View file

@ -44,8 +44,8 @@
<h2>Overview of licenses:</h2>
<ul class="licenses-overview">
<li><a href="#Apache-2.0">Apache License 2.0</a> (156)</li>
<li><a href="#MIT">MIT License</a> (70)</li>
<li><a href="#Apache-2.0">Apache License 2.0</a> (160)</li>
<li><a href="#MIT">MIT License</a> (71)</li>
<li><a href="#Zlib">zlib License</a> (2)</li>
<li><a href="#BSD-2-Clause">BSD 2-Clause &quot;Simplified&quot; License</a> (1)</li>
<li><a href="#BSD-3-Clause">BSD 3-Clause &quot;New&quot; or &quot;Revised&quot; License</a> (1)</li>
@ -2638,6 +2638,7 @@ limitations under the License.</pre>
<li><a href=" https://github.com/smol-rs/fastrand ">fastrand 2.4.1</a></li>
<li><a href=" https://github.com/rust-lang/cc-rs ">find-msvc-tools 0.1.9</a></li>
<li><a href=" https://github.com/petgraph/fixedbitset ">fixedbitset 0.5.7</a></li>
<li><a href=" https://github.com/servo/rust-fnv ">fnv 1.0.7</a></li>
<li><a href=" https://github.com/servo/rust-url ">form_urlencoded 1.2.2</a></li>
<li><a href=" https://github.com/rust-lang/glob ">glob 0.3.3</a></li>
<li><a href=" https://github.com/rust-lang/hashbrown ">hashbrown 0.14.5</a></li>
@ -2661,6 +2662,8 @@ limitations under the License.</pre>
<li><a href=" https://github.com/servo/rust-url/ ">percent-encoding 2.3.2</a></li>
<li><a href=" https://github.com/petgraph/petgraph ">petgraph 0.8.3</a></li>
<li><a href=" https://github.com/rust-lang/pkg-config-rs ">pkg-config 0.3.33</a></li>
<li><a href=" https://github.com/tokio-rs/prost ">prost-derive 0.14.3</a></li>
<li><a href=" https://github.com/tokio-rs/prost ">prost 0.14.3</a></li>
<li><a href=" https://github.com/rayon-rs/rayon ">rayon-core 1.13.0</a></li>
<li><a href=" https://github.com/rayon-rs/rayon ">rayon 1.12.0</a></li>
<li><a href=" https://github.com/rust-lang/regex ">regex-automata 0.4.14</a></li>
@ -4127,6 +4130,7 @@ limitations under the License.
<h4>Used by:</h4>
<ul class="license-used-by">
<li><a href=" https://github.com/zrzka/anes-rs ">anes 0.1.6</a></li>
<li><a href=" https://github.com/dtolnay/anyhow ">anyhow 1.0.102</a></li>
<li><a href=" https://github.com/BLAKE3-team/BLAKE3 ">blake3 1.8.5</a></li>
<li><a href=" https://github.com/cesarb/constant_time_eq ">constant_time_eq 0.4.2</a></li>
<li><a href=" https://github.com/soc/directories-rs ">directories 6.0.0</a></li>
@ -4557,7 +4561,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<h3 id="GPL-3.0">GNU General Public License v3.0 only</h3>
<h4>Used by:</h4>
<ul class="license-used-by">
<li><a href=" https://github.com/elicpeter/nyx ">nyx-scanner 0.7.0</a></li>
<li><a href=" https://github.com/elicpeter/nyx ">nyx-scanner 0.8.0</a></li>
</ul>
<pre class="license-text">
GNU GENERAL PUBLIC LICENSE
@ -4894,6 +4898,39 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</pre>
</li>
<li class="license">
<h3 id="MIT">MIT License</h3>
<h4>Used by:</h4>
<ul class="license-used-by">
<li><a href=" https://github.com/hyperium/h2 ">h2 0.4.14</a></li>
</ul>
<pre class="license-text">Copyright (c) 2017 h2 authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the &quot;Software&quot;), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</pre>
</li>
<li class="license">

View file

@ -12,7 +12,8 @@ export function useTargets() {
export function useAddTarget() {
const qc = useQueryClient();
return useMutation({
mutationFn: (body: { path: string }) => apiPost<TargetView>('/targets', body),
mutationFn: (body: { path: string }) =>
apiPost<TargetView>('/targets', body),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['targets'] });
},

View file

@ -25,7 +25,9 @@ function verdictTooltip(verdict: VerifyResult): string {
? `Not confirmed after ${verdict.attempts?.length ?? 0} payload attempt(s)`
: 'Not confirmed';
case 'Unsupported':
return reason ? `Unsupported: ${reason}` : 'Dynamic verification not supported';
return reason
? `Unsupported: ${reason}`
: 'Dynamic verification not supported';
case 'Inconclusive':
return inconclusive_reason
? `Inconclusive: ${inconclusive_reason}${detail ? `: ${detail}` : ''}`

View file

@ -55,7 +55,9 @@ export function adaptSurfaceMap(data: SurfaceMap): GraphModel {
const detail = nodeDetail(node);
const searchText = [title, detail, loc.file].join(' ').toLowerCase();
const authBadge =
node.node === 'entry_point' && node.auth_required ? ['auth'] : undefined;
node.node === 'entry_point' && node.auth_required
? ['auth']
: undefined;
return {
key: String(index),
rawId: index,

View file

@ -195,10 +195,7 @@ function cfgNodeStyle(
}
}
function surfaceNodeStyle(
type: string,
palette: GraphThemePalette,
): NodeStyle {
function surfaceNodeStyle(type: string, palette: GraphThemePalette): NodeStyle {
switch (type) {
case 'EntryPoint':
return {
@ -261,7 +258,11 @@ function surfaceNodeStyle(
function surfaceEdgeStyle(type: string, palette: GraphThemePalette): EdgeStyle {
switch (type) {
case 'calls':
return { color: withAlpha(palette.textSecondary, 0.78), width: 1.4, dash: [] };
return {
color: withAlpha(palette.textSecondary, 0.78),
width: 1.4,
dash: [],
};
case 'reads_from':
return { color: palette.success, width: 1.5, dash: [] };
case 'writes_to':

View file

@ -733,7 +733,9 @@ export function DynamicVerdictSection({ verdict }: { verdict: VerifyResult }) {
className="dynamic-toolchain-match"
title={`Toolchain match: ${verdict.toolchain_match}`}
>
{verdict.toolchain_match === 'exact' ? 'exact toolchain' : 'approximate toolchain'}
{verdict.toolchain_match === 'exact'
? 'exact toolchain'
: 'approximate toolchain'}
</span>
)}
</div>
@ -763,7 +765,8 @@ export function DynamicVerdictSection({ verdict }: { verdict: VerifyResult }) {
)}
{verdict.inconclusive_reason && (
<div>
<strong>Inconclusive reason:</strong> {verdict.inconclusive_reason}
<strong>Inconclusive reason:</strong>{' '}
{verdict.inconclusive_reason}
</div>
)}
{verdict.detail && (
@ -777,7 +780,10 @@ export function DynamicVerdictSection({ verdict }: { verdict: VerifyResult }) {
<strong>Payload attempts:</strong>
<ul className="dynamic-attempt-list">
{attempts.map((a, i) => (
<li key={i} className={`attempt-row ${a.triggered ? 'triggered' : ''}`}>
<li
key={i}
className={`attempt-row ${a.triggered ? 'triggered' : ''}`}
>
<code>{a.payload_label}</code>
<span className="attempt-outcome">
{a.triggered

View file

@ -781,7 +781,9 @@ export function FindingsPage() {
</td>
<td>
<VerdictBadge
verdict={f.dynamic_verdict ?? f.evidence?.dynamic_verdict}
verdict={
f.dynamic_verdict ?? f.evidence?.dynamic_verdict
}
compact
/>
</td>

View file

@ -307,8 +307,11 @@ function VerdictDiffSection({ data }: { data: CompareResponse }) {
const entries = data.verdict_diff;
if (!entries || entries.length === 0) {
return (
<div style={{ color: 'var(--text-secondary)', padding: 'var(--space-4)' }}>
No verdict-level transitions. Both scans share no findings with stable hashes.
<div
style={{ color: 'var(--text-secondary)', padding: 'var(--space-4)' }}
>
No verdict-level transitions. Both scans share no findings with stable
hashes.
</div>
);
}
@ -333,11 +336,16 @@ function VerdictDiffSection({ data }: { data: CompareResponse }) {
<>
<span
className={`compare-finding-row ${TRANSITION_ROW_CLS[t]}`}
style={{ padding: '0 var(--space-2)', borderRadius: 'var(--radius-sm)' }}
style={{
padding: '0 var(--space-2)',
borderRadius: 'var(--radius-sm)',
}}
>
{TRANSITION_LABELS[t]}
</span>
<span style={{ marginLeft: 'var(--space-2)' }}>({items.length})</span>
<span style={{ marginLeft: 'var(--space-2)' }}>
({items.length})
</span>
</>
}
>
@ -345,7 +353,10 @@ function VerdictDiffSection({ data }: { data: CompareResponse }) {
<div
key={i}
className={`compare-finding-row ${TRANSITION_ROW_CLS[t]}`}
style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)' }}
style={{
fontFamily: 'var(--font-mono)',
fontSize: 'var(--text-xs)',
}}
>
<span style={{ color: 'var(--text-tertiary)' }}>
{e.path}:{e.line}

View file

@ -56,7 +56,8 @@ function nodeSubtitle(node: SurfaceNode): string {
}
function nodeLocation(node: SurfaceNode): string {
const loc = node.node === 'entry_point' ? node.handler_location : node.location;
const loc =
node.node === 'entry_point' ? node.handler_location : node.location;
return `${loc.file}:${loc.line}`;
}
@ -158,9 +159,12 @@ function NeighborList({
{EDGE_KIND_LABELS[e.kind]}
</span>
<span>
{direction === 'in' ? '←' : '→'} <strong>{nodeTitle(other)}</strong>
{direction === 'in' ? '←' : '→'}{' '}
<strong>{nodeTitle(other)}</strong>
</span>
<code className="surface-neighbor-edge-loc">{nodeLocation(other)}</code>
<code className="surface-neighbor-edge-loc">
{nodeLocation(other)}
</code>
</li>
);
})}
@ -250,7 +254,11 @@ export function SurfacePage() {
<option value="external_service">External services</option>
<option value="dangerous_local">Dangerous locals</option>
</select>
<div className="surface-view-toggle" role="tablist" aria-label="Surface view">
<div
className="surface-view-toggle"
role="tablist"
aria-label="Surface view"
>
<button
type="button"
role="tab"

View file

@ -39,7 +39,8 @@ describe('VerdictBadge', () => {
render(
<VerdictBadge
verdict={makeVerdict('PartiallyConfirmed', {
detail: 'sink-reachability probe fired but the oracle marker was not observed',
detail:
'sink-reachability probe fired but the oracle marker was not observed',
})}
/>,
);

View file

@ -102,10 +102,10 @@ impl JavacPool {
// If a prior call torched the worker, try one re-spawn here so
// the caller doesn't see consecutive failures from a transient
// JVM crash.
if guard.is_none() {
if let Ok(w) = spawn_worker(&self.bootstrap_dir) {
*guard = Some(w);
}
if guard.is_none()
&& let Ok(w) = spawn_worker(&self.bootstrap_dir)
{
*guard = Some(w);
}
let worker = match guard.as_mut() {
Some(w) => w,
@ -419,8 +419,7 @@ fn decode_b64(s: &str) -> Option<String> {
}
let bytes: Vec<u8> = s.bytes().filter(|b| !b.is_ascii_whitespace()).collect();
let mut out = Vec::with_capacity(bytes.len() / 4 * 3);
let mut iter = bytes.chunks(4);
while let Some(chunk) = iter.next() {
for chunk in bytes.chunks(4) {
if chunk.len() < 2 {
return None;
}

View file

@ -53,14 +53,14 @@ impl BuildPool for RubyPool {
let start = Instant::now();
// `bundle check` short-circuits when the host already has every gem.
if let Ok(o) = self.bundle(workdir).arg("check").output() {
if o.status.success() {
return PoolCompileResult {
success: true,
stderr: String::new(),
duration: start.elapsed(),
};
}
if let Ok(o) = self.bundle(workdir).arg("check").output()
&& o.status.success()
{
return PoolCompileResult {
success: true,
stderr: String::new(),
duration: start.elapsed(),
};
}
// The install target is pinned to a writable vendor dir via

View file

@ -100,16 +100,16 @@ pub fn prepare_rust(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, B
/// healthy pool is surfaced verbatim (no legacy re-run — it would fail the
/// same way).
fn build_rust_binary(workdir: &Path, binary_dest: &Path) -> Result<(), String> {
if is_pool_enabled("rust") {
if let Ok(pool) = RustPool::try_new() {
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("rust")
&& let Ok(pool) = RustPool::try_new()
{
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_build_rust_binary(workdir, binary_dest)
@ -496,15 +496,15 @@ pub fn prepare_ruby(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, B
/// Route Bundler through [`RubyPool`] (shared Bootsnap cache) when enabled,
/// else the legacy `bundle check`/`install` path.
fn bundle_install(workdir: &Path) -> Result<(), String> {
if is_pool_enabled("ruby") {
if let Ok(pool) = RubyPool::try_new() {
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("ruby")
&& let Ok(pool) = RubyPool::try_new()
{
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_bundle_install(workdir)
@ -672,15 +672,15 @@ pub fn prepare_node(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, B
/// Route `npm install` through [`NodePool`] (shared npm download cache) when
/// enabled, else the legacy direct-spawn path.
fn npm_install(workdir: &Path) -> Result<(), String> {
if is_pool_enabled("node") {
if let Ok(pool) = NodePool::try_new() {
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("node")
&& let Ok(pool) = NodePool::try_new()
{
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_npm_install(workdir)
@ -804,16 +804,16 @@ pub fn prepare_go(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, Bui
/// `GOMODCACHE`, `-trimpath -buildvcs=false`) when enabled, else the legacy
/// per-workdir-cache path.
fn build_go_binary(workdir: &Path, binary_dest: &Path) -> Result<(), String> {
if is_pool_enabled("go") {
if let Ok(pool) = GoPool::try_new() {
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("go")
&& let Ok(pool) = GoPool::try_new()
{
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_build_go_binary(workdir, binary_dest)
@ -1115,22 +1115,22 @@ fn try_compile_java_with_toolchain(
// the direct-spawn legacy path so an operator with a broken JDK
// install still gets a deterministic build error from `javac`
// itself rather than from the pool wrapper.
if is_pool_enabled("java") {
if let Some(pool) = javac_pool_for(toolchain_id) {
let result = pool.compile_batch(workdir, &args);
if result.success {
return finalize_java_compile(workdir, cache_path, lib_on_cp);
}
if pool.is_healthy() {
// The compile itself failed (real source error) -- surface
// the worker's stderr verbatim.
return Err(result.stderr);
}
// Worker crashed: drop the cached pool so the next call
// re-spawns it, then fall through to the legacy direct-spawn
// path so this build still has a chance to succeed.
drop_javac_pool(toolchain_id);
if is_pool_enabled("java")
&& let Some(pool) = javac_pool_for(toolchain_id)
{
let result = pool.compile_batch(workdir, &args);
if result.success {
return finalize_java_compile(workdir, cache_path, lib_on_cp);
}
if pool.is_healthy() {
// The compile itself failed (real source error) -- surface
// the worker's stderr verbatim.
return Err(result.stderr);
}
// Worker crashed: drop the cached pool so the next call
// re-spawns it, then fall through to the legacy direct-spawn
// path so this build still has a chance to succeed.
drop_javac_pool(toolchain_id);
}
let javac = std::env::var("NYX_JAVAC_BIN").unwrap_or_else(|_| "javac".to_owned());
@ -1372,15 +1372,15 @@ pub fn prepare_php(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, Bu
/// Route Composer through [`PhpPool`] (shared download cache + opcache
/// file-cache warm) when enabled, else the legacy direct-spawn path.
fn composer_install(workdir: &Path) -> Result<(), String> {
if is_pool_enabled("php") {
if let Ok(pool) = PhpPool::try_new() {
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("php")
&& let Ok(pool) = PhpPool::try_new()
{
let res = pool.compile_batch(workdir, &[]);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_composer_install(workdir)
@ -1486,19 +1486,19 @@ pub fn prepare_c(
/// static-link toggle is forwarded so the pool can reproduce the
/// Strict-profile `-static` fallback.
fn build_c_binary(workdir: &Path, binary_dest: &Path, static_link: bool) -> Result<(), String> {
if is_pool_enabled("c") {
if let Ok(pool) = CPool::try_new() {
let pool_args = [
binary_dest.to_string_lossy().into_owned(),
if static_link { "static" } else { "dynamic" }.to_owned(),
];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("c")
&& let Ok(pool) = CPool::try_new()
{
let pool_args = [
binary_dest.to_string_lossy().into_owned(),
if static_link { "static" } else { "dynamic" }.to_owned(),
];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_build_c_binary(workdir, binary_dest, static_link)
@ -1654,16 +1654,16 @@ pub fn prepare_cpp(spec: &HarnessSpec, workdir: &Path) -> Result<BuildResult, Bu
/// Route the C++ harness build through [`CppPool`] (`ccache` + shared object
/// cache) when enabled, else the legacy direct-spawn `c++` path.
fn build_cpp_binary(workdir: &Path, binary_dest: &Path) -> Result<(), String> {
if is_pool_enabled("cpp") {
if let Ok(pool) = CppPool::try_new() {
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
if is_pool_enabled("cpp")
&& let Ok(pool) = CppPool::try_new()
{
let pool_args = [binary_dest.to_string_lossy().into_owned()];
let res = pool.compile_batch(workdir, &pool_args);
if res.success {
return Ok(());
}
if pool.is_healthy() {
return Err(res.stderr);
}
}
try_build_cpp_binary(workdir, binary_dest)

View file

@ -27,10 +27,10 @@ use super::super::{CuratedPayload, Oracle, PayloadProvenance, PayloadRef};
/// `../nyx_pt_canary` traversal resolves.
pub const CANARY_FILENAME: &str = "nyx_pt_canary";
/// Canary file CONTENT — the collision-resistant FILE_IO marker. Alphanumeric
/// + underscore so a faithful HTML/URL escaper leaves it intact when the
/// fixture writes the read bytes to the response. NOT a substring of any
/// payload path.
/// Canary file content for the collision-resistant FILE_IO marker. It uses
/// alphanumeric characters plus underscore, so a faithful HTML/URL escaper
/// leaves it intact when the fixture writes the read bytes to the response.
/// NOT a substring of any payload path.
pub const CANARY_MARKER: &str = "NYX_PATHTRAVERSAL_R34D_a7f3c1d8";
pub const PAYLOADS: &[CuratedPayload] = &[

View file

@ -2021,7 +2021,7 @@ mod tests {
.all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase()),
"render must be lowercase hex: {r}",
);
assert!(Canary::ENTROPY_BITS >= 128);
const { assert!(Canary::ENTROPY_BITS >= 128) };
assert!(
r.len() * 4 >= 128,
"rendered canary clears the 128-bit floor"

View file

@ -287,7 +287,7 @@ unsafe extern "C" {
target: *const i8,
fstype: *const i8,
flags: u64,
data: *const i8,
data: *const core::ffi::c_void,
) -> i32;
fn write(fd: i32, buf: *const u8, count: usize) -> isize;
fn __errno_location() -> *mut i32;
@ -319,10 +319,6 @@ fn apply_no_new_privs() -> PrimitiveStatus {
}
}
fn apply_unshare() -> PrimitiveStatus {
apply_unshare_with_flags(CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS)
}
fn apply_unshare_with_flags(flags: i32) -> PrimitiveStatus {
// CLONE_NEWUSER must come first on most modern kernels so the
// unprivileged caller can map uid/gid; CLONE_NEWPID + CLONE_NEWNS
@ -388,9 +384,10 @@ struct BindMount {
/// the [`HardeningOutcome`] wire record, so callers that care about the
/// bind-mount succeeding gate on whether the harness produced output.
///
/// Called in pre_exec between [`apply_unshare`] and [`apply_chroot`] so
/// the new mount namespace is private to the child + grandchildren and
/// the workdir is still reachable at its host-side absolute path.
/// Called in pre_exec after [`apply_unshare_with_flags`] and before
/// [`apply_chroot`] so the new mount namespace is private to the child +
/// grandchildren and the workdir is still reachable at its host-side absolute
/// path.
fn apply_bind_mounts(mounts: &[BindMount]) {
let none = b"none\0";
for m in mounts {

View file

@ -130,10 +130,7 @@ fn corpus_canaries_use_placeholder_and_are_substitutable() {
/// once for the oracle — and the two must agree).
#[test]
fn canary_entropy_and_determinism() {
assert!(
Canary::ENTROPY_BITS >= 128,
"Canary::ENTROPY_BITS must clear the 128-bit floor",
);
const { assert!(Canary::ENTROPY_BITS >= 128) };
let bytes = Canary::generate("spec-hash-under-audit");
assert_eq!(bytes.len(), 32, "canary is 256 bits of BLAKE3 output");