app
SOLIDWORKS Bridge
Public Made by Adomby adom
Launch, model and quit SOLIDWORKS from any Adom container. Nothing is ever lost.
main
Drew Owens
0.6.9 source: launch resilience, honest counts, ownership persistence, drain, quit ladder — 21 adversary passes, 303 te…
cf16621
1mo ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
//! ADVERSARIAL REVIEW OF 0.5.8 — final pass.
//!
//! The third outcome is right: `close_outcome_unknown` sets
//! `outcome:"undetermined"`, names the victim's title and path and the pre-close
//! count, says in words that it cannot be told whether nothing closed or another
//! document did, and BREAKS. It never makes the benign claim. Every count read in
//! the drain goes through the one `Self::document_count` seam, so the mock can
//! make it unreadable everywhere at once.
//!
//! The remaining finding is in the write gate, and it is data loss.
mod common;
use common::Bridge;
use serde_json::{json, Value};
use std::os::unix::fs::PermissionsExt;
fn s(v: &Value) -> String {
serde_json::to_string_pretty(v).unwrap_or_default()
}
/// THE DESTINATION TEST CANNOT TELL "ABSENT" FROM "COULD NOT LOOK".
///
/// The choke point's second condition is:
///
/// ```text
/// let clobbers = destination
/// .map(|d| !d.is_empty() && std::path::Path::new(d).exists())
/// .unwrap_or(false);
/// ```
///
/// `Path::exists()` is `fs::metadata(p).is_ok()` — it returns **false** for a
/// path that does not exist AND for one the process could not stat: permission
/// denied on a parent, a UNC share the bridge has no token for, a device not
/// ready, a path over the length limit. All of those become "the destination is
/// free", and a bridge-created document is then written there in the DEFAULT
/// posture with no opt-in, no `confirm` and no reason.
///
/// The bridge and SOLIDWORKS do not always have the same view of the filesystem.
/// The com host is a child of ab; SOLIDWORKS runs in the user's interactive
/// session with their network token. `\\server\share\part.sldprt` that the bridge
/// cannot stat is one SOLIDWORKS can open and overwrite — and the gate has
/// already said yes.
///
/// This is the one rule in the bridge that decides whether somebody's file
/// survives, and it is the only place left where an unanswerable question is
/// read as permission. `fs::try_exists` returns `io::Result<bool>` and
/// distinguishes the three cases; an `Err` must refuse.
#[test]
fn a_destination_the_bridge_cannot_stat_is_not_treated_as_free() {
let base = std::path::PathBuf::from("/tmp/adv12-unreadable-dest");
let _ = std::fs::remove_dir_all(&base);
std::fs::create_dir_all(base.join("share")).unwrap();
// The user's file. It is really there.
std::fs::write(base.join("share/user-part.SLDPRT"), b"the user's only copy").unwrap();
// ...behind a parent the bridge cannot traverse, which is what an
// unreachable UNC share or a permission-denied path looks like to `exists()`.
std::fs::set_permissions(base.join("share"), std::fs::Permissions::from_mode(0o000)).unwrap();
let dest = base.join("share/user-part.SLDPRT");
assert!(
!dest.exists(),
"precondition: Path::exists() reports FALSE for a file that is really there"
);
let b = Bridge::start(); // DEFAULT posture: no SWX_ALLOW_USER_WRITES
b.call("swx_start", json!({"reason": "modelling"}));
let made = b.call("swx_new_document", json!({"type": "part"}));
let title = made["created"]["title"].as_str().unwrap_or("Part1").to_string();
let r = b.call(
"swx_save_as",
json!({"targetDocument": title, "out": dest.to_string_lossy()}),
);
// Restore before asserting, so a failure cannot leave an unreadable dir behind.
let _ = std::fs::set_permissions(base.join("share"), std::fs::Permissions::from_mode(0o755));
let code = r["errorCode"].as_str().unwrap_or("");
assert!(
// `destination_unverifiable` is the code 0.5.9 shipped for this refusal —
// added to this list, not substituted for it: the assertion is still
// "the gate REFUSED, with a refusal code", and the list was written
// before the name existed. Nothing that means "allowed" is in it.
matches!(
code,
"destination_exists"
| "user_writes_disabled"
| "destination_unreadable"
| "destination_unverifiable"
),
"the write gate GRANTED a save into a destination it could not stat — a file the user \
owns is sitting at that exact path. The call then failed only because this test's \
filesystem refused it; on Windows, where SOLIDWORKS holds the user's token and the \
bridge may not, the host would have written and the user's file would be gone. \
`Path::exists()` cannot tell 'absent' from 'could not look', and the choke point reads \
the second as permission.\nerrorCode: {code:?}\n{}",
s(&r)
);
}
/// The rest of the destination rule, pinned. These pass and must keep passing:
/// an existing file blocks the write in the default posture, and a genuinely new
/// path under a readable directory is allowed without any opt-in (the
/// choke-point rule the drain gate depends on).
#[test]
fn the_destination_rule_still_holds_where_the_answer_is_knowable() {
let base = std::path::PathBuf::from("/tmp/adv12-knowable");
let _ = std::fs::remove_dir_all(&base);
std::fs::create_dir_all(&base).unwrap();
std::fs::write(base.join("taken.SLDPRT"), b"the user's file").unwrap();
let b = Bridge::start();
b.call("swx_start", json!({"reason": "modelling"}));
let made = b.call("swx_new_document", json!({"type": "part"}));
let title = made["created"]["title"].as_str().unwrap_or("Part1").to_string();
// An OCCUPIED destination is refused without the opt-in.
let over = b.call(
"swx_save_as",
json!({"targetDocument": title, "out": base.join("taken.SLDPRT").to_string_lossy()}),
);
assert!(
over["success"] != true,
"an existing user file was overwritten in the default posture: {}",
s(&over)
);
// A NEW path is allowed with no opt-in at all — bridge-created document,
// destination that does not exist.
let fresh = b.call(
"swx_save_as",
json!({"targetDocument": title, "out": base.join("fresh.SLDPRT").to_string_lossy()}),
);
assert!(
fresh["success"] == true,
"the choke-point rule should allow a bridge-created document to a NEW path without an \
opt-in; this is the case tools/drain-gate.py depends on: {}",
s(&fresh)
);
}