From 4ba4033a4841db26953c05aadb5d23fec93f682b Mon Sep 17 00:00:00 2001 From: Valentyn Sobol <8640896+Saloed@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:33:06 +0300 Subject: [PATCH 1/3] Fix #158 --- .../ap/ifds/trace/MethodTraceResolver.kt | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/core/opentaint-dataflow-core/opentaint-dataflow/src/main/kotlin/org/opentaint/dataflow/ap/ifds/trace/MethodTraceResolver.kt b/core/opentaint-dataflow-core/opentaint-dataflow/src/main/kotlin/org/opentaint/dataflow/ap/ifds/trace/MethodTraceResolver.kt index 12a0970db..156a112a9 100644 --- a/core/opentaint-dataflow-core/opentaint-dataflow/src/main/kotlin/org/opentaint/dataflow/ap/ifds/trace/MethodTraceResolver.kt +++ b/core/opentaint-dataflow-core/opentaint-dataflow/src/main/kotlin/org/opentaint/dataflow/ap/ifds/trace/MethodTraceResolver.kt @@ -19,6 +19,7 @@ import org.opentaint.dataflow.ap.ifds.access.InitialFactAp import org.opentaint.dataflow.ap.ifds.analysis.AnalysisManager import org.opentaint.dataflow.ap.ifds.analysis.MethodAnalysisContext import org.opentaint.dataflow.ap.ifds.analysis.MethodCallFactMapper +import org.opentaint.dataflow.ap.ifds.analysis.MethodCallResolver.MethodCallResolutionResult import org.opentaint.dataflow.ap.ifds.trace.MethodCallPrecondition.CallPrecondition import org.opentaint.dataflow.ap.ifds.trace.MethodCallPrecondition.CallPreconditionFact import org.opentaint.dataflow.ap.ifds.trace.MethodSequentPrecondition.SequentPrecondition @@ -39,6 +40,7 @@ import org.opentaint.dataflow.configuration.CommonTaintAssignAction import org.opentaint.dataflow.configuration.CommonTaintConfigurationItem import org.opentaint.dataflow.configuration.CommonTaintConfigurationSource import org.opentaint.dataflow.graph.MethodInstGraph +import org.opentaint.dataflow.util.Cancellation import org.opentaint.dataflow.util.CompactIntSet import org.opentaint.dataflow.util.ConcurrentReadSafeObject2IntMap import org.opentaint.dataflow.util.ConcurrentReadSafeObject2IntMap.NO_VALUE @@ -56,9 +58,6 @@ import org.opentaint.ir.api.common.cfg.CommonValue import java.util.BitSet import java.util.LinkedList import java.util.Objects -import org.opentaint.dataflow.ap.ifds.analysis.MethodCallResolver.MethodCallResolutionResult -import org.opentaint.dataflow.util.Cancellation -import kotlin.collections.plusAssign class MethodTraceResolver( private val runner: AnalysisRunner, @@ -1025,12 +1024,32 @@ class MethodTraceResolver( val mergedRules = mergeCallRules(rules) - val mergedCallSummaries = mergeCallSummaries(summary, unresolvedSkips, resolveMethodCallees()) - ?: return listOf(PartialCallEdgeCombination(unchanged, primary = null, mergedRules)) + if (summary.isEmpty()) { + if (unresolvedSkips.isEmpty()) { + return listOf(PartialCallEdgeCombination(unchanged, primary = null, mergedRules)) + } - return mergedCallSummaries.map { - PartialCallEdgeCombination(unchanged, it, mergedRules) + val skippedEdges = unresolvedSkips.mapTo(hashSetOf()) { it.currentEdge } + val primary = MergedPrimaryUnresolvedCallSkip(UnresolvedCallSkip(skippedEdges, skippedEdges)) + return listOf(PartialCallEdgeCombination(unchanged, primary, mergedRules)) } + + if (unresolvedSkips.isNotEmpty()) { + // note: we have a summary (i.e. call resolved) and an unresolved call + return emptyList() + } + + val callees = resolveMethodCallees() + + val result = mutableListOf() + callees.forEach { callee -> + methodEntryPoints(callee).forEach { + val primary = MergedPrimaryCall2StartAction(it, summary) + result += PartialCallEdgeCombination(unchanged, primary, mergedRules) + } + } + + return result } private fun mergeCallRules(callRules: HashSet): Set { @@ -1070,25 +1089,6 @@ class MethodTraceResolver( return result } - private fun mergeCallSummaries( - callSummaries: Set, - unresolvedCallSkips: Set, - callees: List, - ): Set? = buildSet { - if (callSummaries.isNotEmpty()) { - callees.forEach { callee -> - methodEntryPoints(callee).forEach { - this += MergedPrimaryCall2StartAction(it, callSummaries) - } - } - } - - if (unresolvedCallSkips.isNotEmpty()) { - val skippedEdges = unresolvedCallSkips.mapTo(hashSetOf()) { it.currentEdge } - this += MergedPrimaryUnresolvedCallSkip(UnresolvedCallSkip(skippedEdges, skippedEdges)) - } - }.ifEmpty { null } - private sealed interface PartiallyResolvedCallAction { data class CallRule( val currentEdge: TraceEdge, From cf6bb4bfaad4adfd0a599de3838cdeb160b0bb0d Mon Sep 17 00:00:00 2001 From: Valentyn Sobol <8640896+Saloed@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:14:51 +0300 Subject: [PATCH 2/3] Fix #157 --- .../example/RuleWithConcretePlaceholder.java | 35 +++++++++++++++++++ .../example/RuleWithConcretePlaceholder.yaml | 19 ++++++++++ .../src/main/antlr/JavaLexer.g4 | 3 +- .../semgrep/pattern/SemgrepJavaPattern.kt | 5 +++ .../pattern/SemgrepJavaPatternMatcher.kt | 3 ++ .../pattern/SemgrepJavaPatternParser.kt | 3 +- .../pattern/conversion/AddExprRewriter.kt | 4 ++- .../conversion/CatchStatementRewriter.kt | 4 ++- .../pattern/conversion/PatternRewriter.kt | 3 ++ .../PatternToActionListConverter.kt | 13 ++++++- .../pattern/conversion/PatternUtils.kt | 4 ++- .../conversion/TypeNameWithMetaVarRewriter.kt | 3 ++ .../org/opentaint/semgrep/ExampleTest.kt | 3 ++ 13 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 core/opentaint-java-querylang/samples/src/main/java/example/RuleWithConcretePlaceholder.java create mode 100644 core/opentaint-java-querylang/samples/src/main/resources/example/RuleWithConcretePlaceholder.yaml diff --git a/core/opentaint-java-querylang/samples/src/main/java/example/RuleWithConcretePlaceholder.java b/core/opentaint-java-querylang/samples/src/main/java/example/RuleWithConcretePlaceholder.java new file mode 100644 index 000000000..f180ac16a --- /dev/null +++ b/core/opentaint-java-querylang/samples/src/main/java/example/RuleWithConcretePlaceholder.java @@ -0,0 +1,35 @@ +package example; + +import base.RuleSample; +import base.RuleSet; + +@RuleSet("example/RuleWithConcretePlaceholder.yaml") +public abstract class RuleWithConcretePlaceholder implements RuleSample { + public static String source() { + return "tainted"; + } + + static class Engine { + public void foo(String a, String b, Context data, String d) { + + } + } + + static class Context { + void put(String a, String data) { + } + } + + static class PositiveFoo extends RuleWithConcretePlaceholder { + @Override + public void entrypoint() { + Context context = new Context(); + Engine engine = new Engine(); + + String data = source(); + context.put("data", data); + engine.foo("a", "b", context, "d"); + } + } + +} diff --git a/core/opentaint-java-querylang/samples/src/main/resources/example/RuleWithConcretePlaceholder.yaml b/core/opentaint-java-querylang/samples/src/main/resources/example/RuleWithConcretePlaceholder.yaml new file mode 100644 index 000000000..014b93b73 --- /dev/null +++ b/core/opentaint-java-querylang/samples/src/main/resources/example/RuleWithConcretePlaceholder.yaml @@ -0,0 +1,19 @@ +rules: + - id: example-Rule + languages: + - java + severity: ERROR + message: match example/Rule + mode: taint + pattern-sources: + - patterns: + - pattern: $DATA = source(); + focus-metavariable: $DATA + pattern-sinks: + - patterns: + - pattern: $CTX.put($_, $UNTRUSTED) + - pattern-either: + - pattern-inside: | + ... + (example.RuleWithConcretePlaceholder.Engine $E).foo($_, $_, $CTX, ...); + - focus-metavariable: $UNTRUSTED \ No newline at end of file diff --git a/core/opentaint-java-querylang/src/main/antlr/JavaLexer.g4 b/core/opentaint-java-querylang/src/main/antlr/JavaLexer.g4 index 27decccce..fea4795ea 100644 --- a/core/opentaint-java-querylang/src/main/antlr/JavaLexer.g4 +++ b/core/opentaint-java-querylang/src/main/antlr/JavaLexer.g4 @@ -212,7 +212,7 @@ LINE_COMMENT : '//' ~[\r\n]* -> channel(HIDDEN); IDENTIFIER: LetterNoDollar LetterOrDigit*; -METAVAR: [$] MetavarLetter+; +METAVAR: [$] MetavarFirstLetter MetavarLetter*; ANONYMOUS_METAVAR: [$] '_'; @@ -252,4 +252,5 @@ fragment LetterNoDollar: | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF ; +fragment MetavarFirstLetter: [A-Z] | [0-9]; fragment MetavarLetter: [A-Z_] | [0-9]; diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPattern.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPattern.kt index b466775b2..6491ad5f9 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPattern.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPattern.kt @@ -4,6 +4,10 @@ sealed interface SemgrepJavaPattern { val children: List } +data object AnonymousMetavar : SemgrepJavaPattern { + override val children: List = emptyList() +} + data class Metavar(val name: String) : SemgrepJavaPattern { override val children: List = emptyList() } @@ -186,6 +190,7 @@ sealed interface Name data class ConcreteName(val name: String) : Name data class MetavarName(val metavarName: String) : Name +data object AnonymousName: Name sealed interface TypeName { data class SimpleTypeName( diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternMatcher.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternMatcher.kt index 88adc811d..0dc9d267d 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternMatcher.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternMatcher.kt @@ -420,6 +420,7 @@ class SemgrepJavaPatternMatcher( } pattern } + is AnonymousName -> TODO() } if (acc.isEmpty()) cur else "$acc\\.$cur" } @@ -801,5 +802,7 @@ class SemgrepJavaPatternMatcher( ) ) } + + AnonymousName -> TODO() } } diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternParser.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternParser.kt index c1bd03896..24df8f9a6 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternParser.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/SemgrepJavaPatternParser.kt @@ -123,7 +123,7 @@ class SemgrepJavaPatternParser { private fun IdentifierContext.parseName(): Name = withRule { tryRule(IdentifierContext::METAVAR) { return MetavarName(it.text) } - tryRule(IdentifierContext::ANONYMOUS_METAVAR) { this@parseName.todo() } + tryRule(IdentifierContext::ANONYMOUS_METAVAR) { return AnonymousName } return ConcreteName(text) } @@ -644,6 +644,7 @@ private class SemgrepJavaPatternParserVisitor : JavaParserBaseVisitor Identifier(name.name) is MetavarName -> Metavar(name.metavarName) + is AnonymousName -> AnonymousMetavar } } diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/AddExprRewriter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/AddExprRewriter.kt index 45a78760d..e3fd42849 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/AddExprRewriter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/AddExprRewriter.kt @@ -1,5 +1,6 @@ package org.opentaint.semgrep.pattern.conversion +import org.opentaint.semgrep.pattern.AnonymousName import org.opentaint.semgrep.pattern.ConcreteName import org.opentaint.semgrep.pattern.MetavarName import org.opentaint.semgrep.pattern.MethodInvocation @@ -38,7 +39,8 @@ private fun flatStringConcat(pattern: SemgrepJavaPattern): List {} + is MetavarName, + is AnonymousName -> {} } return listOf(pattern) diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/CatchStatementRewriter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/CatchStatementRewriter.kt index 4815db081..41a4c9e89 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/CatchStatementRewriter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/CatchStatementRewriter.kt @@ -1,5 +1,6 @@ package org.opentaint.semgrep.pattern.conversion +import org.opentaint.semgrep.pattern.AnonymousName import org.opentaint.semgrep.pattern.ConcreteName import org.opentaint.semgrep.pattern.Ellipsis import org.opentaint.semgrep.pattern.Metavar @@ -19,7 +20,8 @@ fun rewriteCatchStatement(rule: NormalizedSemgrepRule): List handlerBlock: SemgrepJavaPattern ): List { val exceptionMetaVarName = when (exceptionVariable) { - is ConcreteName -> return super.createCatchStatement(exceptionTypes, exceptionVariable, handlerBlock) + is ConcreteName, + is AnonymousName -> return super.createCatchStatement(exceptionTypes, exceptionVariable, handlerBlock) is MetavarName -> exceptionVariable.metavarName } diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternRewriter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternRewriter.kt index af5e914a0..76e83a085 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternRewriter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternRewriter.kt @@ -2,6 +2,7 @@ package org.opentaint.semgrep.pattern.conversion import org.opentaint.semgrep.pattern.AddExpr import org.opentaint.semgrep.pattern.Annotation +import org.opentaint.semgrep.pattern.AnonymousMetavar import org.opentaint.semgrep.pattern.ArrayAccess import org.opentaint.semgrep.pattern.BoolConstant import org.opentaint.semgrep.pattern.CatchStatement @@ -75,6 +76,7 @@ interface PatternRewriter { is CatchStatement -> rewriteCatchStatement() is DeepExpr -> rewriteDeepExpr() is EllipsisMetavar -> rewriteEllipsisMetavar() + is AnonymousMetavar -> rewriteAnonymousMetavar() } fun AddExpr.rewriteAddExpr(): List { @@ -254,6 +256,7 @@ interface PatternRewriter { fun Identifier.rewriteIdentifier(): List = listOf(this) fun Metavar.rewriteMetavar(): List = listOf(this) fun EllipsisMetavar.rewriteEllipsisMetavar(): List = listOf(this) + fun AnonymousMetavar.rewriteAnonymousMetavar(): List = listOf(this) fun rewriteEllipsis(): List = listOf(Ellipsis) fun rewriteStringEllipsis(): List = listOf(StringEllipsis) fun rewriteThisExpr(): List = listOf(ThisExpr) diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt index e082cdef2..4dff315db 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt @@ -2,6 +2,8 @@ package org.opentaint.semgrep.pattern.conversion import org.opentaint.semgrep.pattern.AddExpr import org.opentaint.semgrep.pattern.Annotation +import org.opentaint.semgrep.pattern.AnonymousMetavar +import org.opentaint.semgrep.pattern.AnonymousName import org.opentaint.semgrep.pattern.ArrayAccess import org.opentaint.semgrep.pattern.BoolConstant import org.opentaint.semgrep.pattern.CatchStatement @@ -116,6 +118,7 @@ class PatternToActionListConverter: ActionListBuilder { is CatchStatement, is DeepExpr, is EllipsisMetavar, + is AnonymousMetavar, is IntLiteral -> { val messagePrefix = if (isRootPattern) "Root pattern is: " else "" transformationFailed("$messagePrefix${pattern::class.java.simpleName}") @@ -131,6 +134,7 @@ class PatternToActionListConverter: ActionListBuilder { is StringLiteral -> when (val value = pattern.content) { is ConcreteName -> SpecificStringValue(value.name) is MetavarName -> StringValueMetaVar(MetavarAtom.create(value.metavarName)) + is AnonymousName -> ParamCondition.AnyStringLiteral } is StringEllipsis -> { @@ -141,6 +145,10 @@ class PatternToActionListConverter: ActionListBuilder { IsMetavar(MetavarAtom.create(pattern.name)) } + is AnonymousMetavar -> { + ParamCondition.True + } + is TypedMetavar -> { if (isGeneratedMethodInvocationObjMetaVar(pattern.name)) { return ParamCondition.True @@ -163,7 +171,7 @@ class PatternToActionListConverter: ActionListBuilder { ParamCondition.SpecificStaticFieldValue(fn.name, type) } - is MetavarName -> { + is MetavarName, is AnonymousName -> { transformationFailed("Static field name is metavar") } } @@ -317,6 +325,7 @@ class PatternToActionListConverter: ActionListBuilder { val methodName = when (val name = pattern.methodName) { is ConcreteName -> SignatureName.Concrete(name.name) is MetavarName -> SignatureName.MetaVar(name.metavarName) + is AnonymousName -> transformationFailed("Method name is anonymous") } val actionList = mutableListOf() @@ -557,6 +566,7 @@ class PatternToActionListConverter: ActionListBuilder { val methodName = when (val name = pattern.name) { is ConcreteName -> SignatureName.Concrete(name.name) is MetavarName -> SignatureName.MetaVar(name.metavarName) + is AnonymousName -> transformationFailed("Method name is anonymous") } val returnTypePattern: TypeConstraint? = pattern.returnType?.let { transformTypeName(it) } @@ -658,6 +668,7 @@ class PatternToActionListConverter: ActionListBuilder { } is ConcreteName -> SignatureModifierValue.StringValue(paramName, value.name) + is AnonymousName -> SignatureModifierValue.AnyValue } } diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternUtils.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternUtils.kt index 068596def..a4987a211 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternUtils.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternUtils.kt @@ -1,5 +1,6 @@ package org.opentaint.semgrep.pattern.conversion +import org.opentaint.semgrep.pattern.AnonymousName import org.opentaint.semgrep.pattern.ConcreteName import org.opentaint.semgrep.pattern.FieldAccess import org.opentaint.semgrep.pattern.Identifier @@ -34,7 +35,8 @@ fun tryExtractConcreteNames(names: List): List? { names.forEach { name -> when (name) { is ConcreteName -> result.add(name.name) - is MetavarName -> return null + is MetavarName, + is AnonymousName -> return null } } return result diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/TypeNameWithMetaVarRewriter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/TypeNameWithMetaVarRewriter.kt index 8fd9e594d..da3be1c1f 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/TypeNameWithMetaVarRewriter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/TypeNameWithMetaVarRewriter.kt @@ -1,5 +1,6 @@ package org.opentaint.semgrep.pattern.conversion +import org.opentaint.semgrep.pattern.AnonymousName import org.opentaint.semgrep.pattern.ConcreteName import org.opentaint.semgrep.pattern.MetaVarConstraint import org.opentaint.semgrep.pattern.MetaVarConstraintFormula @@ -98,5 +99,7 @@ private fun MetaVarConstraintFormula>.transformNext( } } } + + is AnonymousName -> TODO("TypeName metavar is anonymous") } } diff --git a/core/opentaint-java-querylang/src/test/kotlin/org/opentaint/semgrep/ExampleTest.kt b/core/opentaint-java-querylang/src/test/kotlin/org/opentaint/semgrep/ExampleTest.kt index 9a874949f..e70580bd9 100644 --- a/core/opentaint-java-querylang/src/test/kotlin/org/opentaint/semgrep/ExampleTest.kt +++ b/core/opentaint-java-querylang/src/test/kotlin/org/opentaint/semgrep/ExampleTest.kt @@ -204,6 +204,9 @@ class ExampleTest : SampleBasedTest() { @Test fun `test object mapper pattern-not ellipsis`() = runTest() + @Test + fun `test concrete placeholder`() = runTest() + @AfterAll fun close() { closeRunner() From 38180d41663d321d8b3267f9b98aa5e01ce888f6 Mon Sep 17 00:00:00 2001 From: Valentyn Sobol <8640896+Saloed@users.noreply.github.com> Date: Thu, 18 Jun 2026 17:32:01 +0300 Subject: [PATCH 3/3] Fix --- .../PatternToActionListConverter.kt | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt index 4dff315db..2630c0e70 100644 --- a/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt +++ b/core/opentaint-java-querylang/src/main/kotlin/org/opentaint/semgrep/pattern/conversion/PatternToActionListConverter.kt @@ -577,13 +577,15 @@ class PatternToActionListConverter: ActionListBuilder { for ((i, param) in params.withIndex()) { when (param) { is FormalArgument -> { - val paramName = (param.name as? MetavarName)?.metavarName - ?: transformationFailed("MethodDeclaration_param_name_not_metavar") - val position = if (idxIsConcrete) { ParamPosition.Concrete(i) } else { - ParamPosition.Any(paramClassifier = paramName) + val positionName = when (val name = param.name) { + is ConcreteName -> name.name + is MetavarName -> name.metavarName + is AnonymousName -> "*" + } + ParamPosition.Any(paramClassifier = positionName) } val paramModifiers = param.modifiers.map { transformModifier(it) } @@ -591,7 +593,16 @@ class PatternToActionListConverter: ActionListBuilder { ParamPattern(position, ParamCondition.ParamModifier(modifier)) } - paramConditions += ParamPattern(position, IsMetavar(MetavarAtom.create(paramName))) + when(val name = param.name){ + is MetavarName -> { + paramConditions += ParamPattern( + position, + IsMetavar(MetavarAtom.create(name.metavarName)) + ) + } + is AnonymousName -> {} + is ConcreteName -> transformationFailed("MethodDeclaration_param_name_not_metavar") + } val paramType = transformTypeName(param.type) paramConditions += ParamPattern(position, ParamCondition.TypeIs(paramType))