# HG changeset patch # User Arseniy Alekseyev # Date 1712657544 -3600 # Node ID 68929cf3c0c67c05861943613afb087dfcaa0676 # Parent ea3343104f07904104fb280f0b9f1168c7214562 match: avoid rust fast path if the matcher was tampered with Otherwise the fast path does not respect the modifications made by the extension (concretely largefiles, but other extensions can start using that too) diff -r ea3343104f07 -r 68929cf3c0c6 rust/hg-cpython/src/dirstate/status.rs --- a/rust/hg-cpython/src/dirstate/status.rs Tue Apr 09 11:00:52 2024 +0100 +++ b/rust/hg-cpython/src/dirstate/status.rs Tue Apr 09 11:12:24 2024 +0100 @@ -11,7 +11,7 @@ use crate::{dirstate::DirstateMap, exceptions::FallbackError}; use cpython::{ - exc::ValueError, ObjectProtocol, PyBytes, PyErr, PyList, PyObject, + exc::ValueError, ObjectProtocol, PyBool, PyBytes, PyErr, PyList, PyObject, PyResult, PyTuple, Python, PythonObject, ToPyObject, }; use hg::dirstate::status::StatusPath; @@ -26,8 +26,8 @@ files::{get_bytes_from_path, get_path_from_bytes}, hg_path::{HgPath, HgPathBuf}, }, - BadMatch, DirstateStatus, IgnorePattern, PatternFileWarning, StatusError, - StatusOptions, + BadMatch, DirstateStatus, IgnorePattern, PatternError, PatternFileWarning, + StatusError, StatusOptions, }; use std::borrow::Borrow; @@ -158,6 +158,18 @@ py: Python, matcher: PyObject, ) -> PyResult> { + let tampered = matcher + .call_method(py, "was_tampered_with", PyTuple::empty(py), None)? + .extract::(py)? + .is_true(); + if tampered { + return Err(handle_fallback( + py, + StatusError::Pattern(PatternError::UnsupportedSyntax( + "Pattern matcher was tampered with!".to_string(), + )), + )); + }; match matcher.get_type(py).name(py).borrow() { "alwaysmatcher" => Ok(Box::new(AlwaysMatcher)), "nevermatcher" => Ok(Box::new(NeverMatcher)),