From 6cc963ccd37f3ad40c46dcc0a5cae305dcfad87d Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sat, 9 Mar 2024 16:12:18 +0100 Subject: [PATCH] Skip contracts using exotic parser bugs or wrongly scraped --- crates/solidity/testing/sanctuary/src/main.rs | 3 +- .../solidity/testing/sanctuary/src/tests.rs | 50 ++++++++++++++++--- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/crates/solidity/testing/sanctuary/src/main.rs b/crates/solidity/testing/sanctuary/src/main.rs index 2834694e6f..362e8dc606 100644 --- a/crates/solidity/testing/sanctuary/src/main.rs +++ b/crates/solidity/testing/sanctuary/src/main.rs @@ -92,7 +92,8 @@ fn main() -> Result<()> { if failure_count > 0 { println!(); println!( - "Found '{failure_count}' failures. Please check the logs above for more information." + "Found {failure_count} failure{suffix}. Please check the logs above for more information.", + suffix = if failure_count == 1 { "" } else { "s" }, ); println!(); diff --git a/crates/solidity/testing/sanctuary/src/tests.rs b/crates/solidity/testing/sanctuary/src/tests.rs index a516ac5c9a..db866af619 100644 --- a/crates/solidity/testing/sanctuary/src/tests.rs +++ b/crates/solidity/testing/sanctuary/src/tests.rs @@ -1,4 +1,5 @@ use std::cmp::min; +use std::path::Path; use anyhow::Result; use infra_utils::paths::PathExtensions; @@ -59,26 +60,40 @@ pub(crate) fn select_tests<'d>( } pub fn run_test(file: &SourceFile, events: &Events) -> Result<()> { + if !file.path.exists() { + // Index can be out of date: + events.test(TestOutcome::NotFound); + return Ok(()); + } + + // Ignore contracts that rely on obvious, exotic parser bugs fixed in later versions: + if uses_exotic_parser_bug(&file.path) { + events.test(TestOutcome::Incompatible); + return Ok(()); + } + let Some(version) = extract_compiler_version(&file.compiler) else { events.test(TestOutcome::Incompatible); return Ok(()); }; - if !file.path.exists() { - // Index can be out of date: - events.test(TestOutcome::NotFound); + let source = file.path.read_to_string()?; + // Heuristic: ignore wrongly scraped sanctuary files that + // contain HTML with a Cloudflare email obfuscation attribute: + if source.contains("data-cfemail=") { + events.test(TestOutcome::Incompatible); return Ok(()); } - let source = file - .path - .read_to_string()? + let source = source // Some files are null terminated. Remove the null character: // https://github.com/tintinweb/smart-contract-sanctuary/issues/30 .trim_end_matches('\0') // Remove unicode character inserted by sanctuary (illegal in Solidity): // https://github.com/tintinweb/smart-contract-sanctuary/issues/31 - .replace("[email protected]", "[email-protected]"); + .replace("[email protected]", "[email-protected]") + // Select contracts from Sanctuary were probably incorrectly web-scraped: + .replace("'", "\""); let language = Language::new(version.clone())?; let output = language.parse(RuleKind::SourceUnit, &source); @@ -123,3 +138,24 @@ fn extract_compiler_version(compiler: &str) -> Option { Some(version) } + +fn uses_exotic_parser_bug(file: &Path) -> bool { + static CONTRACTS_WITH_EXOTIC_PARSER_BUGS: &[&str] = &[ + // 0.4.24: // Accepts malformed `* /` in multi-line comments: + // Fixed in 0.4.25: https://github.com/ethereum/solidity/pull/4937 + "ethereum/contracts/mainnet/79/79bb6f4492d5cb13fad8ca0ecfbccd9e2c26ac42_Gateway.sol", + // 0.4.18: // Accepts unfinished multi-line comments at the end of the file: + // Fixed in 0.4.25: https://github.com/ethereum/solidity/pull/4937 + "ethereum/contracts/mainnet/7d/7d81c361d6ac60634117dd81ab1b01b8dc795a9d_LILITHCOIN.sol", + // 0.8.15: Relies on invalidly accepting `indexed indexed` in the event declaration: + // Fixed in 0.8.18: https://github.com/ethereum/solidity/pull/13816 + "ethereum/contracts/mainnet/da/d4559E5F507eD935F19208A5D50637898c192Ab3_Factory.sol", + // 0.4.24: Relies on silently ignoring invalid `\`-escapes in string literals: + // Fixed in 0.4.25: https://github.com/ethereum/solidity/pull/4937 + "ethereum/contracts/mainnet/e0/e0b1bfe763b2cd43c652471bf126f5a577a81567_ExchangeProvider.sol", + ]; + + CONTRACTS_WITH_EXOTIC_PARSER_BUGS + .iter() + .any(|path| file.ends_with(path)) +}