Skip to content

Commit

Permalink
Skip contracts using exotic parser bugs or wrongly scraped
Browse files Browse the repository at this point in the history
  • Loading branch information
Xanewok committed Mar 9, 2024
1 parent daf9289 commit 6cc963c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
3 changes: 2 additions & 1 deletion crates/solidity/testing/sanctuary/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!();

Expand Down
50 changes: 43 additions & 7 deletions crates/solidity/testing/sanctuary/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::cmp::min;
use std::path::Path;

use anyhow::Result;
use infra_utils::paths::PathExtensions;
Expand Down Expand Up @@ -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("&#39;", "\"");

let language = Language::new(version.clone())?;
let output = language.parse(RuleKind::SourceUnit, &source);
Expand Down Expand Up @@ -123,3 +138,24 @@ fn extract_compiler_version(compiler: &str) -> Option<Version> {

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))
}

0 comments on commit 6cc963c

Please sign in to comment.