Establish native Linux ARM64 Android CI and verification gates (#94)
Android ARM verification / android (push) Canceled after 0s
Android ARM verification / rust (push) Canceled after 12m1s

This commit is contained in:
hugo committed 2026-10-08 18:30:05 +02:00
1 parent 1abd75282e
commit 6679361d47
28 files changed
+1631 -53

No files matched your search

+17 -1
View File
@@ -59,6 +59,17 @@ fn harden_source(source: &str) -> Result<String, Box<dyn Error>> {
if !source.contains(internal) || source.matches(callback).count() != 2 {
return Err("UniFFI unexpected-error template changed; review secret redaction".into());
}
let initializer = "public fun uniffiEnsureInitialized() {";
if source.matches(initializer).count() != 1 {
return Err(
"UniFFI initialization template changed; review eager contract initialization".into(),
);
}
// Object references deliberately trigger Kotlin initialization and integrity guards.
let source = source.replace(
initializer,
"@Suppress(\"UNUSED_EXPRESSION\")\npublic fun uniffiEnsureInitialized() {",
);
let source = source.replace(internal, "class InternalException(@Suppress(\"UNUSED_PARAMETER\") message: String) : kotlin.Exception(\"Native Rust failure ([REDACTED])\")")
.replace(callback, "val err = \"Native callback failed ([REDACTED])\"");
// Callback results are operation-owned; erase plaintext after copying into the wire buffer.
@@ -121,11 +132,16 @@ fn harden_source(source: &str) -> Result<String, Box<dyn Error>> {
mod tests {
use super::*;
const SOURCE: &str = "data class Secret (\n val value: String\n)\n{\n companion object\n}\nclass Failure {\n override val message\n get() = \"value=${value}\"\n}\nif (bindings_contract_version != scaffolding_contract_version) { throw RuntimeException(\"UniFFI contract version mismatch: try cleaning and rebuilding your project\") }\nif (lib.checksum() != 1234) { throw RuntimeException(\"UniFFI API checksum mismatch: try cleaning and rebuilding your project\") }\nclass InternalException(message: String) : kotlin.Exception(message)\nval err = try { e.stackTraceToString() } catch(_: Throwable) { \"\" }\nval err = try { e.stackTraceToString() } catch(_: Throwable) { \"\" }\n";
const SOURCE: &str = "public fun uniffiEnsureInitialized() {\n IntegrityCheckingUniffiLib\n UniffiLib\n}\ndata class Secret (\n val value: String\n)\n{\n companion object\n}\nclass Failure {\n override val message\n get() = \"value=${value}\"\n}\nif (bindings_contract_version != scaffolding_contract_version) { throw RuntimeException(\"UniFFI contract version mismatch: try cleaning and rebuilding your project\") }\nif (lib.checksum() != 1234) { throw RuntimeException(\"UniFFI API checksum mismatch: try cleaning and rebuilding your project\") }\nclass InternalException(message: String) : kotlin.Exception(message)\nval err = try { e.stackTraceToString() } catch(_: Throwable) { \"\" }\nval err = try { e.stackTraceToString() } catch(_: Throwable) { \"\" }\n";
#[test]
fn redacts_record_and_error_diagnostics_without_changing_fields_or_checksums() {
let hardened = harden_source(SOURCE).unwrap();
assert!(
hardened
.contains("@Suppress(\"UNUSED_EXPRESSION\")\npublic fun uniffiEnsureInitialized()")
);
assert!(hardened.contains(" IntegrityCheckingUniffiLib\n"));
assert!(hardened.contains("val value: String"));
assert!(hardened.contains("Secret([REDACTED])"));
assert!(!hardened.contains("get() = \"value="));