Added .with[Optional]NamedParameter and tests - #527
Open
san-zrl wants to merge 1 commit into
Open
Conversation
Signed-off-by: san-zrl <san@zurich.ibm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add
with[Optional]NamedMethodParameterto the detection rule DSLEngine · Python · keyword-argument-aware parameter matching
Motivation
Python callers routinely pass arguments out of order using keyword syntax, and routinely omit optional parameters entirely:
The existing
withMethodParameter(type)method is purely positional: it reads argument n for parameter n and requires an exact argument count enforced byMethodMatcher. It cannot handle reordered arguments, omitted optional parameters, or the keyword-argument call style that is idiomatic in Python cryptography APIs.Description
Add support for named and optional named method parameters in detection rules for the Python engine.
New builder methods
Two new methods are added to the
DetectionRuleBuilderfluent API:withNamedMethodParameter(String name, String type)withOptionalNamedMethodParameter(String name, String type)The pre-existing
withMethodParameterandwithMethodParameterMatchExactTypeare fully backward-compatible: rules that use only positional parameters are unaffected — the builder takes the same code path as before and theMethodMatcheris constructed with the same type list as it always was. The only addition is a guard that throwsIllegalStateExceptionif a positional-parameter call is made after a named-parameter call, enforcing Python's calling-convention order at construction time.Ordering constraints (enforced at construction time):
withMethodParameter/withMethodParameterMatchExactTypecalls must precede anywithNamedMethodParameter/withOptionalNamedMethodParametercall. Violating this throwsIllegalStateException.withNamedMethodParameter) must precede optional ones (withOptionalNamedMethodParameter). Violating this also throwsIllegalStateException.Example rule definition:
Engine changes (
PythonDetectionEngine)When a rule contains at least one named parameter:
MethodMatcheris constructed without a type list so the matcher accepts any arity call and delegates structural validation to the extraction loop.*args/**kwargsarguments whose contents cannot be statically inspected.arguments.size() < minArgs(minArgs= positional params + required named params).findArgumentByKeyword(name, positionalIndex, arguments)resolves each named parameter: keyword-name match first, positional fallback second (only when the argument at that index carries no keyword marker itself).processParameterExpressionto avoid duplication between the positional and named paths.checkSymbolTraceStateis extracted fromcheckCurrentIndexStateso the symbol-trace check can be reused on the named-parameter path without re-running the arity guard.Test:
NamedParametersTestLocated at
python/src/test/java/com/ibm/plugin/rules/detection/NamedParametersTest.java.The test rule models
test.module.Foo.f(a: str, b: int, c: str = …)— one positional-required, one named-required, one named-optional parameter.The optional parameter
c(typestr) is captured as anAlgorithmParameterchild so each test can assert whether it was resolved.Tests where the rule fires
cchild capturedtestAllPositionalf("hello", 42, "yes")aat index 0,bvia positional fallback at index 1,cvia positional fallback at index 2testCByKeywordf("hello", 42, c="yes")a/bpositional,cmatched by keyword name"c"testBCByKeywordCanonicalOrderf("hello", b=42, c="yes")apositional,bandcmatched by keyword name in declaration ordertestBCByKeywordReorderedf("hello", c="yes", b=42)apositional,bandcmatched by keyword name regardless of physical argument ordertestAllByKeywordf(a="hello", b=42, c="yes")ais a positional rule parameter — engine readsarguments.get(0)=a="hello"and unwraps"hello";bandcby keyword nametestExtraUnknownKwargf("hello", 42, "yes", d=0)d=0at index 3 is never referenced and silently ignoredtestCAbsentPositionalf("hello", 42)aandbsatisfied;cis optional and absent — rule still fires, nocchildtestCAbsentBByKeywordf("hello", b=42)apositional,bby keyword;cis optional and absent — rule still fires, nocchildtestCAbsentAllKeywordf(a="hello", b=42)aat index 0,bby keyword;cis optional and absent — rule still fires, nocchildTests where the rule does NOT fire
testNegativeBAbsentf("hello")arguments.size() = 1 < minArgs = 2— arity gate rejects before any type checktestNegativeWrongTypeAf(42, 42)arguments[0]asint, rejects against declared type"str"testNegativeWrongTypeBf("hello", "42")bfound via positional fallback at index 1; named-parameter type check resolves"42"asstr, rejects against"int"; becausebis required the rule returns earlytestNegativeAAbsentf(b=42)arguments.size() = 1 < minArgs = 2— arity gate rejects (the single argument is keywordb, leaving the positional slot foraempty)testNegativeDictUnpackf("hello", **d)RegularArgumentand rejects the call immediatelyAdditional test:
DetectionRuleBuilderParameterOrderTestLocated at
engine/src/test/java/com/ibm/engine/rule/builder/DetectionRuleBuilderParameterOrderTest.java.Verifies that the ordering constraints are enforced at construction time (
positionalAfterNamedThrows,requiredNamedAfterOptionalNamedThrows,requiredBeforeOptionalNamedIsValid) and that a named parameter's keyword name is not silently dropped when.addDependingDetectionRules()is chained (namedParameterWithDependingRulesRetainsKeywordName).