diff --git a/README.md b/README.md index 96cdacf39..6e8aacea2 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,11 @@ It is part of **the [CBOMKit](https://github.com/cbomkit) toolset**. | Python | [pyca/cryptography](https://cryptography.io/en/latest/) | 100% | | Go | [crypto](https://pkg.go.dev/crypto) (*standard library*) | 100%[^2] | | | [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) | Partial[^3] | -| C# | [System.Security.Cryptography](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography) | In development[^4] | [^1]: We only cover the BouncyCastle *light-weight API* according to [this specification](https://javadoc.io/static/org.bouncycastle/bctls-jdk14/1.80/specifications.html) [^2]: All packages under [`crypto`](https://pkg.go.dev/crypto@go1.25.6#section-directories) are covered except `crypto/x509` [^3]: Covers `golang.org/x/crypto/hkdf`, `golang.org/x/crypto/pbkdf2`, and `golang.org/x/crypto/sha3` -[^4]: C# support uses an [ANTLR v7 grammar](https://github.com/antlr/grammars-v4/tree/master/csharp) to parse source files directly. The current csharp support only covers the language support and does not contain detection rules other than the rules used for verifying the detection engine. **This is not yet meant for active usage!** **Known limitations of the detection engine:** no cross-method variable tracking (only single-method scope), only works for c# v7, string-based matching (no type resolution) > [!NOTE] > The plugin is designed in a modular way so that it can be extended to support additional languages and recognition rules to support more libraries. diff --git a/csharp/pom.xml b/csharp/pom.xml deleted file mode 100755 index cb77bb3c1..000000000 --- a/csharp/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - 4.0.0 - - com.ibm - sonar-cryptography - 2.0.0-SNAPSHOT - - - csharp - - - 17 - 17 - UTF-8 - - - - - com.ibm - engine - 2.0.0-SNAPSHOT - - - com.ibm - output - 2.0.0-SNAPSHOT - - - com.ibm - enricher - 2.0.0-SNAPSHOT - - - com.ibm - rules - 2.0.0-SNAPSHOT - compile - - - - org.sonarsource.analyzer-commons - sonar-analyzer-test-commons - 2.18.0.3393 - test - - - - diff --git a/csharp/src/main/java/com/ibm/plugin/CSharpAggregator.java b/csharp/src/main/java/com/ibm/plugin/CSharpAggregator.java deleted file mode 100755 index f31dfe9bb..000000000 --- a/csharp/src/main/java/com/ibm/plugin/CSharpAggregator.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import com.ibm.engine.language.ILanguageSupport; -import com.ibm.engine.language.LanguageSupporter; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.mapper.model.INode; -import com.ibm.output.IAggregator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; - -/** Static accumulator for C# cryptographic detection results. Mirrors {@code GoAggregator}. */ -public final class CSharpAggregator implements IAggregator { - - private static ILanguageSupport - csharpLanguageSupport = LanguageSupporter.csharpLanguageSupporter(); - - private static List detectedNodes = new ArrayList<>(); - - private CSharpAggregator() { - // nothing - } - - @Nonnull - public static ILanguageSupport - getLanguageSupport() { - return csharpLanguageSupport; - } - - @Nonnull - public static List getDetectedNodes() { - return Collections.unmodifiableList(detectedNodes); - } - - public static void addNodes(@Nonnull List newNodes) { - detectedNodes.addAll(newNodes); - IAggregator.log(newNodes); - } - - public static void reset() { - csharpLanguageSupport = LanguageSupporter.csharpLanguageSupporter(); - detectedNodes = new ArrayList<>(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/CSharpParserErrorListener.java b/csharp/src/main/java/com/ibm/plugin/CSharpParserErrorListener.java deleted file mode 100644 index 3625e515f..000000000 --- a/csharp/src/main/java/com/ibm/plugin/CSharpParserErrorListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.fs.InputFile; - -/** - * ANTLR error listener that logs parse errors at WARN level instead of silently discarding them. - * - *

Malformed C# files will still be partially scanned (the parser recovers where possible), but - * any syntax errors encountered are surfaced as warnings so users know that analysis may be - * incomplete for those files. - */ -public final class CSharpParserErrorListener extends BaseErrorListener { - - private static final Logger LOG = LoggerFactory.getLogger(CSharpParserErrorListener.class); - - @Nonnull private final InputFile inputFile; - - public CSharpParserErrorListener(@Nonnull InputFile inputFile) { - this.inputFile = inputFile; - } - - @Override - public void syntaxError( - @Nonnull Recognizer recognizer, - @Nullable Object offendingSymbol, - int line, - int charPositionInLine, - @Nonnull String msg, - @Nullable RecognitionException e) { - LOG.warn("Parse error in {}: line {}:{} — {}", inputFile, line, charPositionInLine, msg); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/CSharpRuleList.java b/csharp/src/main/java/com/ibm/plugin/CSharpRuleList.java deleted file mode 100755 index a63d42bfe..000000000 --- a/csharp/src/main/java/com/ibm/plugin/CSharpRuleList.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import com.ibm.plugin.rules.CSharpInventoryRule; -import java.util.List; - -/** Lists all C# check classes registered in the rule repository. */ -public final class CSharpRuleList { - - private CSharpRuleList() { - // nothing - } - - public static List> getChecks() { - return List.of(CSharpInventoryRule.class); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/CSharpScannerRuleDefinition.java b/csharp/src/main/java/com/ibm/plugin/CSharpScannerRuleDefinition.java deleted file mode 100755 index 76e5762bf..000000000 --- a/csharp/src/main/java/com/ibm/plugin/CSharpScannerRuleDefinition.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import java.util.Collections; -import java.util.Objects; -import java.util.Set; -import org.sonar.api.SonarRuntime; -import org.sonar.api.server.rule.RulesDefinition; -import org.sonarsource.analyzer.commons.RuleMetadataLoader; - -/** SonarQube rule repository definition for C# cryptographic rules. */ -public class CSharpScannerRuleDefinition implements RulesDefinition { - - public static final String REPOSITORY_KEY = "sonar-cs-crypto"; - public static final String REPOSITORY_NAME = "Sonar Cryptography"; - - private static final Set RULE_TEMPLATES_KEY = Collections.emptySet(); - private static final String RESOURCE_BASE_PATH = "/org/sonar/l10n/cs/rules/cs"; - - private final SonarRuntime sonarRuntime; - - public CSharpScannerRuleDefinition(SonarRuntime sonarRuntime) { - this.sonarRuntime = sonarRuntime; - } - - @Override - public void define(Context context) { - NewRepository repository = - context.createRepository(REPOSITORY_KEY, "cs").setName(REPOSITORY_NAME); - - RuleMetadataLoader ruleMetadataLoader = - new RuleMetadataLoader(RESOURCE_BASE_PATH, sonarRuntime); - ruleMetadataLoader.addRulesByAnnotatedClass(repository, CSharpRuleList.getChecks()); - setTemplates(repository); - - repository.done(); - } - - private static void setTemplates(NewRepository repository) { - RULE_TEMPLATES_KEY.stream() - .map(repository::rule) - .filter(Objects::nonNull) - .forEach(rule -> rule.setTemplate(true)); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/CryptoCSharpSensor.java b/csharp/src/main/java/com/ibm/plugin/CryptoCSharpSensor.java deleted file mode 100755 index 2970209f9..000000000 --- a/csharp/src/main/java/com/ibm/plugin/CryptoCSharpSensor.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpTreeConverter; -import com.ibm.engine.language.csharp.antlr.CSharpLexer; -import com.ibm.engine.language.csharp.antlr.CSharpParser; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.rule.CheckFactory; -import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.SensorDescriptor; - -/** - * Custom sensor for executing cryptography detection rules on C# source files. - * - *

Unlike Java/Python (which use SonarQube's {@code CheckRegistrar}) and Go (which reuses the - * sonar-go {@code ChecksVisitor}), C# requires a fully custom sensor because sonar-csharp exposes - * no public custom rule API. Each .cs file is parsed independently with the ANTLR4-based - * CSharpLexer/CSharpParser, and detection checks are invoked directly for every method body found. - */ -public class CryptoCSharpSensor implements Sensor { - - private static final Logger LOG = LoggerFactory.getLogger(CryptoCSharpSensor.class); - - private final Collection checks; - - public CryptoCSharpSensor(@Nonnull CheckFactory checkFactory) { - this.checks = - checkFactory - .create(CSharpScannerRuleDefinition.REPOSITORY_KEY) - .addAnnotatedChecks(CSharpRuleList.getChecks()) - .all(); - } - - @Override - public void describe(@Nonnull SensorDescriptor descriptor) { - descriptor.onlyOnLanguage("cs").name("Cryptography for C#"); - } - - @Override - public void execute(@Nonnull SensorContext context) { - execute(context, checks); - } - - public static void execute( - @Nonnull SensorContext context, @Nonnull Collection checks) { - if (checks.isEmpty()) { - return; - } - - FileSystem fs = context.fileSystem(); - Iterable csFiles = - fs.inputFiles( - fs.predicates() - .and( - fs.predicates().hasLanguage("cs"), - fs.predicates().hasType(InputFile.Type.MAIN))); - - for (InputFile inputFile : csFiles) { - if (context.isCancelled()) { - return; - } - analyzeFile(context, checks, inputFile); - } - } - - private static void analyzeFile( - @Nonnull SensorContext context, - @Nonnull Collection checks, - @Nonnull InputFile inputFile) { - String content; - try { - content = inputFile.contents(); - } catch (IOException e) { - LOG.warn("Unable to read file: {}", inputFile, e); - return; - } - - CSharpParser.Compilation_unitContext parseTree = parseContent(content, inputFile); - if (parseTree == null) { - return; - } - - CSharpTreeConverter converter = new CSharpTreeConverter(); - List methodBodies = converter.extractMethodBodies(parseTree); - if (methodBodies.isEmpty()) { - return; - } - - CSharpScanContext scanContext = - new CSharpScanContext( - context, inputFile, CSharpScannerRuleDefinition.REPOSITORY_KEY); - - for (CSharpBlockTree blockTree : methodBodies) { - for (CSharpCheck check : checks) { - try { - check.scan(scanContext, blockTree); - } catch (RuntimeException e) { - LOG.warn( - "Error running check {} on {}: {}", - check.getClass().getSimpleName(), - inputFile, - e.getMessage(), - e); - } - } - } - } - - @Nullable private static CSharpParser.Compilation_unitContext parseContent( - @Nonnull String content, @Nonnull InputFile inputFile) { - try { - CSharpLexer lexer = - new CSharpLexer(CharStreams.fromString(content, inputFile.toString())); - lexer.removeErrorListeners(); - lexer.addErrorListener(new CSharpParserErrorListener(inputFile)); - - CommonTokenStream tokens = new CommonTokenStream(lexer); - CSharpParser parser = new CSharpParser(tokens); - parser.removeErrorListeners(); - parser.addErrorListener(new CSharpParserErrorListener(inputFile)); - - return parser.compilation_unit(); - } catch (RuntimeException e) { - LOG.warn("Unable to parse file: {}", inputFile, e); - return null; - } - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/CSharpInventoryRule.java b/csharp/src/main/java/com/ibm/plugin/rules/CSharpInventoryRule.java deleted file mode 100755 index 89f04d607..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/CSharpInventoryRule.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.mapper.model.INode; -import com.ibm.plugin.rules.detection.CSharpBaseDetectionRule; -import com.ibm.plugin.rules.detection.CSharpDetectionRules; -import com.ibm.plugin.translation.reorganizer.CSharpReorganizerRules; -import com.ibm.rules.InventoryRule; -import com.ibm.rules.issue.Issue; -import java.util.List; -import javax.annotation.Nonnull; -import org.sonar.check.Rule; -import org.sonar.java.annotations.VisibleForTesting; - -/** The single C# cryptographic inventory rule — detects all known crypto API usage. */ -@Rule(key = "Inventory") -public class CSharpInventoryRule extends CSharpBaseDetectionRule { - - public CSharpInventoryRule() { - super(true, CSharpDetectionRules.rules(), CSharpReorganizerRules.rules()); - } - - @VisibleForTesting - protected CSharpInventoryRule(@Nonnull List> detectionRules) { - super(true, detectionRules, CSharpReorganizerRules.rules()); - } - - @Override - public @Nonnull List> report( - @Nonnull CSharpTree markerTree, @Nonnull List translatedNodes) { - return new InventoryRule().report(markerTree, translatedNodes); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpBaseDetectionRule.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpBaseDetectionRule.java deleted file mode 100755 index bbe34499b..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpBaseDetectionRule.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection; - -import com.ibm.common.IObserver; -import com.ibm.engine.detection.Finding; -import com.ibm.engine.executive.DetectionExecutive; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.reorganizer.IReorganizerRule; -import com.ibm.plugin.CSharpAggregator; -import com.ibm.plugin.translation.CSharpTranslationProcess; -import com.ibm.plugin.translation.reorganizer.CSharpReorganizerRules; -import com.ibm.rules.IReportableDetectionRule; -import com.ibm.rules.issue.Issue; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Abstract base class for C# cryptographic detection rules. - * - *

Mirrors {@code GoBaseDetectionRule}: holds a set of {@link IDetectionRule}s, runs them for - * every method body via {@link CSharpCheck#scan}, and translates findings to {@link INode} objects. - */ -public abstract class CSharpBaseDetectionRule - implements CSharpCheck, - IObserver>, - IReportableDetectionRule { - - private final boolean isInventory; - @Nonnull protected final CSharpTranslationProcess csharpTranslationProcess; - @Nonnull protected final List> detectionRules; - - protected CSharpBaseDetectionRule() { - this.isInventory = false; - this.detectionRules = CSharpDetectionRules.rules(); - this.csharpTranslationProcess = - new CSharpTranslationProcess(CSharpReorganizerRules.rules()); - } - - protected CSharpBaseDetectionRule( - final boolean isInventory, - @Nonnull List> detectionRules, - @Nonnull List reorganizerRules) { - this.isInventory = isInventory; - this.detectionRules = detectionRules; - this.csharpTranslationProcess = new CSharpTranslationProcess(reorganizerRules); - } - - @Override - public void scan(@Nonnull CSharpScanContext scanContext, @Nonnull CSharpBlockTree blockTree) { - detectionRules.forEach( - rule -> { - DetectionExecutive - detectionExecutive = - CSharpAggregator.getLanguageSupport() - .createDetectionExecutive(blockTree, rule, scanContext); - detectionExecutive.subscribe(this); - detectionExecutive.start(); - }); - } - - @Override - public void update( - @Nonnull Finding finding) { - List nodes = csharpTranslationProcess.initiate(finding.detectionStore()); - if (isInventory) { - CSharpAggregator.addNodes(nodes); - } - this.report(finding.getMarkerTree(), nodes) - .forEach( - issue -> - finding.detectionStore() - .getScanContext() - .reportIssue(this, issue.tree(), issue.message())); - } - - @Override - @Nonnull - public List> report( - @Nonnull CSharpTree markerTree, @Nonnull List translatedNodes) { - return Collections.emptyList(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpDetectionRules.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpDetectionRules.java deleted file mode 100755 index 92576f65a..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/CSharpDetectionRules.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.plugin.rules.detection.dotnet.DotNetAES; -import com.ibm.plugin.rules.detection.dotnet.DotNetDES; -import com.ibm.plugin.rules.detection.dotnet.DotNetDSA; -import com.ibm.plugin.rules.detection.dotnet.DotNetECDiffieHellman; -import com.ibm.plugin.rules.detection.dotnet.DotNetECDsa; -import com.ibm.plugin.rules.detection.dotnet.DotNetHMAC; -import com.ibm.plugin.rules.detection.dotnet.DotNetRC2; -import com.ibm.plugin.rules.detection.dotnet.DotNetRSA; -import com.ibm.plugin.rules.detection.dotnet.DotNetRfc2898DeriveBytes; -import com.ibm.plugin.rules.detection.dotnet.DotNetSHA; -import com.ibm.plugin.rules.detection.dotnet.DotNetTripleDES; -import java.util.List; -import java.util.stream.Stream; -import javax.annotation.Nonnull; - -/** Aggregates all C# detection rule lists. */ -public final class CSharpDetectionRules { - - private CSharpDetectionRules() { - // nothing - } - - @Nonnull - public static List> rules() { - return Stream.of( - DotNetAES.rules().stream(), - DotNetDES.rules().stream(), - DotNetTripleDES.rules().stream(), - DotNetRC2.rules().stream(), - DotNetRSA.rules().stream(), - DotNetECDsa.rules().stream(), - DotNetECDiffieHellman.rules().stream(), - DotNetDSA.rules().stream(), - DotNetSHA.rules().stream(), - DotNetHMAC.rules().stream(), - DotNetRfc2898DeriveBytes.rules().stream()) - .flatMap(i -> i) - .toList(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetAES.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetAES.java deleted file mode 100755 index f750ea4e0..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetAES.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.detection.MethodMatcher; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.Size; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.engine.model.factory.KeySizeFactory; -import com.ibm.engine.model.factory.ModeFactory; -import com.ibm.engine.model.factory.PaddingFactory; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for AES usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code Aes.Create()} — factory method on abstract base class - *
  • {@code new AesManaged()} — legacy concrete class (deprecated in .NET 6+) - *
  • {@code new AesGcm(key)} — authenticated encryption with GCM mode - *
  • {@code new AesCcm(key)} — authenticated encryption with CCM mode - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetAES { - - private DotNetAES() { - // nothing - } - - // aes.Mode = CipherMode.CBC → synthetic set_Mode(CipherMode.CBC) - private static final IDetectionRule AES_SET_MODE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes(MethodMatcher.ANY) - .forMethods("set_Mode") - .withMethodParameter(MethodMatcher.ANY) - .shouldBeDetectedAs(new ModeFactory<>()) - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withoutDependingDetectionRules(); - - // aes.KeySize = 256 → synthetic set_KeySize(256) - private static final IDetectionRule AES_SET_KEY_SIZE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes(MethodMatcher.ANY) - .forMethods("set_KeySize") - .withMethodParameter(MethodMatcher.ANY) - .shouldBeDetectedAs(new KeySizeFactory<>(Size.UnitType.BIT)) - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withoutDependingDetectionRules(); - - // aes.Padding = PaddingMode.PKCS7 → synthetic set_Padding(PaddingMode.PKCS7) - private static final IDetectionRule AES_SET_PADDING = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes(MethodMatcher.ANY) - .forMethods("set_Padding") - .withMethodParameter(MethodMatcher.ANY) - .shouldBeDetectedAs(new PaddingFactory<>()) - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withoutDependingDetectionRules(); - - private static final List> PROPERTY_SETTER_RULES = - List.of(AES_SET_MODE, AES_SET_KEY_SIZE, AES_SET_PADDING); - - // Aes.Create() — abstract factory - private static final IDetectionRule AES_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("Aes") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("AES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(PROPERTY_SETTER_RULES); - - // new AesManaged() — legacy concrete class - private static final IDetectionRule AES_MANAGED = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("AesManaged") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("AES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(PROPERTY_SETTER_RULES); - - // new AesCng() — CNG-backed implementation - private static final IDetectionRule AES_CNG = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("AesCng") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("AES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(PROPERTY_SETTER_RULES); - - // new AesGcm(key) — GCM authenticated encryption - // TODO: capture key parameter (byte[] key) to extract key length as a known gap - private static final IDetectionRule AES_GCM = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("AesGcm") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("AES")) - .withAnyParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - // new AesCcm(key) — CCM authenticated encryption - // TODO: capture key parameter (byte[] key) to extract key length as a known gap - private static final IDetectionRule AES_CCM = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("AesCcm") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("AES")) - .withAnyParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(AES_CREATE, AES_MANAGED, AES_CNG, AES_GCM, AES_CCM); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDES.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDES.java deleted file mode 100755 index f4384f7f7..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDES.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for DES usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code DES.Create()} — abstract factory (deprecated in .NET 5+) - *
  • {@code new DESCryptoServiceProvider()} — CAPI-backed (deprecated) - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetDES { - - private DotNetDES() { - // nothing - } - - private static final IDetectionRule DES_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("DES") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("DES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule DES_CSP = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("DESCryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("DES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(DES_CREATE, DES_CSP); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSA.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSA.java deleted file mode 100755 index 30fdd70fc..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSA.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - -/** - * Detection rules for DSA usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code DSA.Create()} — abstract factory - *
  • {@code new DSACryptoServiceProvider()} — CAPI-backed implementation - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetDSA { - - private DotNetDSA() { - // nothing - } - - private static final IDetectionRule DSA_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("DSA") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("DSA")) - .withoutParameters() - .buildForContext(new KeyContext(Map.of("kind", "DSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule DSA_CSP = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("DSACryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("DSA")) - .withoutParameters() - .buildForContext(new KeyContext(Map.of("kind", "DSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(DSA_CREATE, DSA_CSP); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellman.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellman.java deleted file mode 100755 index 79ea96196..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellman.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - -/** - * Detection rules for ECDH usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code ECDiffieHellman.Create()} — abstract factory - *
  • {@code ECDiffieHellman.Create(curve)} — factory with ECCurve - *
  • {@code new ECDiffieHellmanCng()} — CNG-backed implementation - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetECDiffieHellman { - - private DotNetECDiffieHellman() { - // nothing - } - - private static final IDetectionRule ECDH_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("ECDiffieHellman") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("ECDH")) - .withAnyParameters() - .buildForContext(new KeyContext(Map.of("kind", "ECDH"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule ECDH_CNG = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("ECDiffieHellmanCng") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("ECDH")) - .withoutParameters() - .buildForContext(new KeyContext(Map.of("kind", "ECDH"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(ECDH_CREATE, ECDH_CNG); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsa.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsa.java deleted file mode 100755 index 5c9fb5f54..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsa.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - -/** - * Detection rules for ECDSA usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code ECDsa.Create()} — factory without curve - *
  • {@code ECDsa.Create(curve)} — factory with ECCurve parameter - *
  • {@code new ECDsaCng()} — CNG-backed implementation - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetECDsa { - - private DotNetECDsa() { - // nothing - } - - private static final IDetectionRule ECDSA_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("ECDsa") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("ECDSA")) - .withAnyParameters() - .buildForContext(new KeyContext(Map.of("kind", "ECDSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule ECDSA_CNG = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("ECDsaCng") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("ECDSA")) - .withoutParameters() - .buildForContext(new KeyContext(Map.of("kind", "ECDSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(ECDSA_CREATE, ECDSA_CNG); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMAC.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMAC.java deleted file mode 100755 index 073cfdf08..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMAC.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.MacContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for HMAC algorithms in System.Security.Cryptography. - * - *

Detects constructor calls for all concrete HMAC implementations. The detected value encodes - * the full class name (e.g., {@code "HMACSHA256"}) so the translator can resolve the inner hash. - */ -@SuppressWarnings("java:S1192") -public final class DotNetHMAC { - - private DotNetHMAC() { - // nothing - } - - private static IDetectionRule hmacRule(String className) { - return new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes(className) - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>(className.toUpperCase())) - .withAnyParameters() - .buildForContext(new MacContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - } - - @Nonnull - public static List> rules() { - return List.of( - hmacRule("HMACSHA1"), - hmacRule("HMACSHA256"), - hmacRule("HMACSHA384"), - hmacRule("HMACSHA512"), - hmacRule("HMACMD5")); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2.java deleted file mode 100755 index 5c73f7ada..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for RC2 usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code RC2.Create()} — abstract factory (weak cipher) - *
  • {@code new RC2CryptoServiceProvider()} — CAPI-backed (weak cipher) - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetRC2 { - - private DotNetRC2() { - // nothing - } - - private static final IDetectionRule RC2_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("RC2") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("RC2")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule RC2_CSP = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("RC2CryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("RC2")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(RC2_CREATE, RC2_CSP); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSA.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSA.java deleted file mode 100755 index 43cb3f561..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSA.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - -/** - * Detection rules for RSA usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code RSA.Create()} — abstract factory, no key size - *
  • {@code RSA.Create(2048)} — factory with key size - *
  • {@code new RSACryptoServiceProvider()} — CAPI-backed, no key size - *
  • {@code new RSACryptoServiceProvider(2048)} — CAPI-backed with key size - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetRSA { - - private DotNetRSA() { - // nothing - } - - private static final IDetectionRule RSA_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("RSA") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("RSA")) - .withAnyParameters() - .buildForContext(new KeyContext(Map.of("kind", "RSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule RSA_CRYPTO_SERVICE_PROVIDER = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("RSACryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("RSA")) - .withAnyParameters() - .buildForContext(new KeyContext(Map.of("kind", "RSA"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(RSA_CREATE, RSA_CRYPTO_SERVICE_PROVIDER); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytes.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytes.java deleted file mode 100755 index 0bb0822ed..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytes.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; - -/** - * Detection rules for PBKDF2 via {@code Rfc2898DeriveBytes} in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code new Rfc2898DeriveBytes(password, salt, iterations)} — SHA-1 default - *
  • {@code new Rfc2898DeriveBytes(password, salt, iterations, hashAlgorithm)} — explicit hash - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetRfc2898DeriveBytes { - - private DotNetRfc2898DeriveBytes() { - // nothing - } - - private static final IDetectionRule RFC2898 = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("Rfc2898DeriveBytes") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("PBKDF2")) - .withAnyParameters() - .buildForContext(new KeyContext(Map.of("kind", "KDF"))) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(RFC2898); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHA.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHA.java deleted file mode 100755 index 5911f9c64..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHA.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.DigestContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for SHA hash algorithms in System.Security.Cryptography. - * - *

Detects factory methods and concrete class constructors for SHA-1, SHA-256, SHA-384, and - * SHA-512 (and their {@code Managed} concrete variants). - */ -@SuppressWarnings("java:S1192") -public final class DotNetSHA { - - private DotNetSHA() { - // nothing - } - - // SHA1 - private static final IDetectionRule SHA1_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA1") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA1")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule SHA1_MANAGED = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA1Managed") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA1")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - // SHA256 - private static final IDetectionRule SHA256_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA256") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA256")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule SHA256_MANAGED = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA256Managed") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA256")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - // SHA384 - private static final IDetectionRule SHA384_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA384") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA384")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule SHA384_MANAGED = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA384Managed") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA384")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - // SHA512 - private static final IDetectionRule SHA512_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA512") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA512")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule SHA512_MANAGED = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("SHA512Managed") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("SHA512")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - // MD5 - private static final IDetectionRule MD5_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("MD5") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("MD5")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule MD5_CSP = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("MD5CryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("MD5")) - .withoutParameters() - .buildForContext(new DigestContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of( - SHA1_CREATE, - SHA1_MANAGED, - SHA256_CREATE, - SHA256_MANAGED, - SHA384_CREATE, - SHA384_MANAGED, - SHA512_CREATE, - SHA512_MANAGED, - MD5_CREATE, - MD5_CSP); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDES.java b/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDES.java deleted file mode 100755 index 2f1892e4d..000000000 --- a/csharp/src/main/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDES.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.engine.model.factory.ValueActionFactory; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.rule.builder.DetectionRuleBuilder; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Detection rules for Triple DES usage in System.Security.Cryptography. - * - *

Detects: - * - *

    - *
  • {@code TripleDES.Create()} — abstract factory - *
  • {@code new TripleDESCryptoServiceProvider()} — CAPI-backed (deprecated) - *
- */ -@SuppressWarnings("java:S1192") -public final class DotNetTripleDES { - - private DotNetTripleDES() { - // nothing - } - - private static final IDetectionRule TRIPLE_DES_CREATE = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("TripleDES") - .forMethods("Create") - .shouldBeDetectedAs(new ValueActionFactory<>("TRIPLEDES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - private static final IDetectionRule TRIPLE_DES_CSP = - new DetectionRuleBuilder() - .createDetectionRule() - .forObjectTypes("TripleDESCryptoServiceProvider") - .forMethods("") - .shouldBeDetectedAs(new ValueActionFactory<>("TRIPLEDES")) - .withoutParameters() - .buildForContext(new CipherContext()) - .inBundle(() -> "DotNet") - .withDependingDetectionRules(List.of()); - - @Nonnull - public static List> rules() { - return List.of(TRIPLE_DES_CREATE, TRIPLE_DES_CSP); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/CSharpTranslationProcess.java b/csharp/src/main/java/com/ibm/plugin/translation/CSharpTranslationProcess.java deleted file mode 100755 index 05b093c8d..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/CSharpTranslationProcess.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.enricher.Enricher; -import com.ibm.mapper.ITranslationProcess; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.reorganizer.IReorganizerRule; -import com.ibm.mapper.reorganizer.Reorganizer; -import com.ibm.mapper.utils.Utils; -import com.ibm.plugin.translation.translator.CSharpTranslator; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; - -/** Three-stage translation pipeline for C#: translate → reorganize → enrich. */ -public final class CSharpTranslationProcess - extends ITranslationProcess { - - public CSharpTranslationProcess(@Nonnull List reorganizerRules) { - super(reorganizerRules); - } - - @Nonnull - @Override - public List initiate( - @Nonnull - DetectionStore - rootDetectionStore) { - // 1. Translate - final CSharpTranslator csharpTranslator = new CSharpTranslator(); - final List translatedValues = csharpTranslator.translate(rootDetectionStore); - Utils.printNodeTree(" translated ", translatedValues); - - // 2. Reorganize - final Reorganizer reorganizer = new Reorganizer(reorganizerRules); - final List reorganizedValues = reorganizer.reorganize(translatedValues); - Utils.printNodeTree("reorganised ", reorganizedValues); - - // 3. Enrich - final List enrichedValues = Enricher.enrich(reorganizedValues).stream().toList(); - Utils.printNodeTree(" enriched ", enrichedValues); - - return Collections.unmodifiableCollection(enrichedValues).stream().toList(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/reorganizer/CSharpReorganizerRules.java b/csharp/src/main/java/com/ibm/plugin/translation/reorganizer/CSharpReorganizerRules.java deleted file mode 100755 index 0b75dd550..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/reorganizer/CSharpReorganizerRules.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.reorganizer; - -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.MessageDigest; -import com.ibm.mapper.reorganizer.IReorganizerRule; -import com.ibm.mapper.reorganizer.rules.CipherSuiteReorganizer; -import com.ibm.mapper.reorganizer.rules.KeyDerivationReorganizer; -import com.ibm.mapper.reorganizer.rules.PaddingReorganizer; -import com.ibm.mapper.reorganizer.rules.SignatureReorganizer; -import java.util.List; -import java.util.stream.Stream; -import javax.annotation.Nonnull; - -/** Reorganizer rules for the C# translation pipeline. Delegates to existing shared rules. */ -public final class CSharpReorganizerRules { - - private CSharpReorganizerRules() { - // nothing - } - - @Nonnull - public static List rules() { - return Stream.of( - SignatureReorganizer.MERGE_SIGNATURE_PARENT_AND_CHILD, - KeyDerivationReorganizer.moveModeFromParentToNode(BlockCipher.class), - KeyDerivationReorganizer.moveModeFromParentToNode(MessageDigest.class), - CipherSuiteReorganizer.REPLACE_TLS_WITH_VERSIONED_CHILD, - PaddingReorganizer.MOVE_OAEP_UNDER_ALGORITHM) - .toList(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/translator/CSharpTranslator.java b/csharp/src/main/java/com/ibm/plugin/translation/translator/CSharpTranslator.java deleted file mode 100755 index 793796b3f..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/translator/CSharpTranslator.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.translator; - -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.engine.model.context.DigestContext; -import com.ibm.engine.model.context.IDetectionContext; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.engine.model.context.MacContext; -import com.ibm.engine.model.context.PRNGContext; -import com.ibm.engine.model.context.ProtocolContext; -import com.ibm.engine.model.context.SignatureContext; -import com.ibm.engine.rule.IBundle; -import com.ibm.mapper.ITranslator; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.utils.DetectionLocation; -import com.ibm.plugin.translation.translator.contexts.CSharpCipherContextTranslator; -import com.ibm.plugin.translation.translator.contexts.CSharpDigestContextTranslator; -import com.ibm.plugin.translation.translator.contexts.CSharpKeyContextTranslator; -import com.ibm.plugin.translation.translator.contexts.CSharpMacContextTranslator; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** Translator for C# cryptographic detections. Dispatches to context-specific translators. */ -public class CSharpTranslator - extends ITranslator { - - public CSharpTranslator() { - // nothing - } - - @Nonnull - @Override - public Optional translate( - @Nonnull final IBundle bundleIdentifier, - @Nonnull final IValue value, - @Nonnull final IDetectionContext detectionValueContext, - @Nonnull final String filePath) { - DetectionLocation detectionLocation = - getDetectionContextFrom(value.getLocation(), bundleIdentifier, filePath); - if (detectionLocation == null) { - return Optional.empty(); - } - - if (detectionValueContext.is(CipherContext.class)) { - return new CSharpCipherContextTranslator() - .translate(bundleIdentifier, value, detectionValueContext, detectionLocation); - } - - if (detectionValueContext.is(DigestContext.class)) { - return new CSharpDigestContextTranslator() - .translate(bundleIdentifier, value, detectionValueContext, detectionLocation); - } - - if (detectionValueContext.is(MacContext.class)) { - return new CSharpMacContextTranslator() - .translate(bundleIdentifier, value, detectionValueContext, detectionLocation); - } - - if (detectionValueContext.is(KeyContext.class)) { - return new CSharpKeyContextTranslator() - .translate(bundleIdentifier, value, detectionValueContext, detectionLocation); - } - - if (detectionValueContext.is(PRNGContext.class) - || detectionValueContext.is(SignatureContext.class) - || detectionValueContext.is(ProtocolContext.class)) { - return Optional.empty(); - } - - return Optional.empty(); - } - - @Override - @Nullable protected DetectionLocation getDetectionContextFrom( - @Nonnull CSharpTree location, @Nonnull IBundle bundle, @Nonnull String filePath) { - int lineNumber = location.getLine(); - int offset = location.getColumn(); - - List keywords = List.of(); - if (location instanceof CSharpMethodInvocationTree invocation) { - keywords = List.of(invocation.getMethodName()); - } else if (location instanceof CSharpObjectCreationTree creation) { - keywords = List.of(creation.getTypeName()); - } - - return new DetectionLocation(filePath, lineNumber, offset, keywords, bundle); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpCipherContextTranslator.java b/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpCipherContextTranslator.java deleted file mode 100755 index 4fa746e89..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpCipherContextTranslator.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.translator.contexts; - -import com.ibm.engine.model.BlockSize; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.KeySize; -import com.ibm.engine.model.Mode; -import com.ibm.engine.model.OperationMode; -import com.ibm.engine.model.Padding; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.IDetectionContext; -import com.ibm.engine.rule.IBundle; -import com.ibm.mapper.IContextTranslation; -import com.ibm.mapper.mapper.jca.JcaCipherOperationModeMapper; -import com.ibm.mapper.mapper.jca.JcaModeMapper; -import com.ibm.mapper.mapper.jca.JcaPaddingMapper; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.KeyLength; -import com.ibm.mapper.model.algorithms.AES; -import com.ibm.mapper.model.algorithms.DES; -import com.ibm.mapper.model.algorithms.DESede; -import com.ibm.mapper.model.algorithms.RC2; -import com.ibm.mapper.model.algorithms.RSA; -import com.ibm.mapper.utils.DetectionLocation; -import java.util.Optional; -import javax.annotation.Nonnull; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -/** Translates {@link com.ibm.engine.model.context.CipherContext} detections for .NET APIs. */ -public final class CSharpCipherContextTranslator - implements IContextTranslation { - - private static final Logger LOG = Loggers.get(CSharpCipherContextTranslator.class); - - @Override - public @Nonnull Optional translate( - @Nonnull IBundle bundleIdentifier, - @Nonnull IValue value, - @Nonnull IDetectionContext detectionContext, - @Nonnull DetectionLocation detectionLocation) { - - if (value instanceof ValueAction) { - String valueStr = value.asString().toUpperCase().trim(); - Optional result = - switch (valueStr) { - case "AES" -> Optional.of(new AES(detectionLocation)); - case "DES" -> Optional.of(new DES(detectionLocation)); - case "3DES", "DESEDE", "TRIPLEDES" -> - Optional.of(new DESede(detectionLocation)); - case "RSA" -> Optional.of(new RSA(detectionLocation)); - case "RC2" -> Optional.of(new RC2(detectionLocation)); - default -> Optional.empty(); - }; - if (result.isPresent()) { - return result; - } - // Try operation mode - JcaCipherOperationModeMapper modeMapper = new JcaCipherOperationModeMapper(); - return modeMapper.parse(valueStr, detectionLocation).map(mode -> mode); - } else if (value instanceof BlockSize blockSize) { - return Optional.of( - new com.ibm.mapper.model.BlockSize(blockSize.getValue(), detectionLocation)); - } else if (value instanceof KeySize keySize) { - return Optional.of(new KeyLength(keySize.getValue(), detectionLocation)); - } else if (value instanceof OperationMode operationMode) { - JcaCipherOperationModeMapper operationModeMapper = new JcaCipherOperationModeMapper(); - return operationModeMapper - .parse(operationMode.asString(), detectionLocation) - .map(f -> f); - } else if (value instanceof Mode mode) { - // From set_Mode property setter: CipherMode.CBC → "CBC" - JcaModeMapper modeMapper = new JcaModeMapper(); - return modeMapper.parse(mode.asString(), detectionLocation).map(m -> m); - } else if (value instanceof Padding padding) { - // From set_Padding property setter: PaddingMode.PKCS7 → "PKCS7" - JcaPaddingMapper paddingMapper = new JcaPaddingMapper(); - return paddingMapper.parse(padding.asString(), detectionLocation).map(p -> p); - } - - return Optional.empty(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpDigestContextTranslator.java b/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpDigestContextTranslator.java deleted file mode 100755 index 121acad2b..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpDigestContextTranslator.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.translator.contexts; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.IDetectionContext; -import com.ibm.engine.rule.IBundle; -import com.ibm.mapper.IContextTranslation; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.algorithms.MD5; -import com.ibm.mapper.model.algorithms.SHA; -import com.ibm.mapper.model.algorithms.SHA2; -import com.ibm.mapper.utils.DetectionLocation; -import java.util.Optional; -import javax.annotation.Nonnull; - -/** Translates {@link com.ibm.engine.model.context.DigestContext} detections for .NET APIs. */ -public final class CSharpDigestContextTranslator implements IContextTranslation { - - @Override - public @Nonnull Optional translate( - @Nonnull IBundle bundleIdentifier, - @Nonnull IValue value, - @Nonnull IDetectionContext detectionContext, - @Nonnull DetectionLocation detectionLocation) { - - if (value instanceof ValueAction) { - return switch (value.asString().toUpperCase().trim()) { - case "SHA1" -> Optional.of(new SHA(detectionLocation)); - case "SHA256" -> Optional.of(new SHA2(256, detectionLocation)); - case "SHA384" -> Optional.of(new SHA2(384, detectionLocation)); - case "SHA512" -> Optional.of(new SHA2(512, detectionLocation)); - case "MD5" -> Optional.of(new MD5(detectionLocation)); - default -> Optional.empty(); - }; - } - - return Optional.empty(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpKeyContextTranslator.java b/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpKeyContextTranslator.java deleted file mode 100755 index 6b50ce83c..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpKeyContextTranslator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.translator.contexts; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.KeySize; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.DetectionContext; -import com.ibm.engine.model.context.IDetectionContext; -import com.ibm.engine.rule.IBundle; -import com.ibm.mapper.IContextTranslation; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.KeyLength; -import com.ibm.mapper.model.algorithms.DSA; -import com.ibm.mapper.model.algorithms.ECDH; -import com.ibm.mapper.model.algorithms.ECDSA; -import com.ibm.mapper.model.algorithms.PBKDF2; -import com.ibm.mapper.model.algorithms.RSA; -import com.ibm.mapper.utils.DetectionLocation; -import java.util.Optional; -import javax.annotation.Nonnull; - -/** Translates {@link com.ibm.engine.model.context.KeyContext} detections for .NET APIs. */ -public final class CSharpKeyContextTranslator implements IContextTranslation { - - @Override - public @Nonnull Optional translate( - @Nonnull IBundle bundleIdentifier, - @Nonnull IValue value, - @Nonnull IDetectionContext detectionContext, - @Nonnull DetectionLocation detectionLocation) { - - if (value instanceof ValueAction - && detectionContext instanceof DetectionContext context) { - String kind = context.get("kind").orElse(""); - return switch (kind) { - case "RSA" -> Optional.of(new RSA(detectionLocation)); - case "ECDSA" -> Optional.of(new ECDSA(detectionLocation)); - case "ECDH" -> Optional.of(new ECDH(detectionLocation)); - case "DSA" -> Optional.of(new DSA(detectionLocation)); - case "KDF" -> Optional.of(new PBKDF2(detectionLocation)); - default -> Optional.empty(); - }; - } else if (value instanceof KeySize keySize) { - return Optional.of(new KeyLength(keySize.getValue(), detectionLocation)); - } - - return Optional.empty(); - } -} diff --git a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpMacContextTranslator.java b/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpMacContextTranslator.java deleted file mode 100755 index c0e0ddd68..000000000 --- a/csharp/src/main/java/com/ibm/plugin/translation/translator/contexts/CSharpMacContextTranslator.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.translation.translator.contexts; - -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.IDetectionContext; -import com.ibm.engine.rule.IBundle; -import com.ibm.mapper.IContextTranslation; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.algorithms.HMAC; -import com.ibm.mapper.model.algorithms.MD5; -import com.ibm.mapper.model.algorithms.SHA; -import com.ibm.mapper.model.algorithms.SHA2; -import com.ibm.mapper.utils.DetectionLocation; -import java.util.Optional; -import javax.annotation.Nonnull; - -/** Translates {@link com.ibm.engine.model.context.MacContext} detections for .NET APIs. */ -public final class CSharpMacContextTranslator implements IContextTranslation { - - @Override - public @Nonnull Optional translate( - @Nonnull IBundle bundleIdentifier, - @Nonnull IValue value, - @Nonnull IDetectionContext detectionContext, - @Nonnull DetectionLocation detectionLocation) { - - if (value instanceof ValueAction) { - return switch (value.asString().toUpperCase().trim()) { - case "HMACSHA1" -> Optional.of(new HMAC(new SHA(detectionLocation))); - case "HMACSHA256" -> Optional.of(new HMAC(new SHA2(256, detectionLocation))); - case "HMACSHA384" -> Optional.of(new HMAC(new SHA2(384, detectionLocation))); - case "HMACSHA512" -> Optional.of(new HMAC(new SHA2(512, detectionLocation))); - case "HMACMD5" -> Optional.of(new HMAC(new MD5(detectionLocation))); - default -> Optional.empty(); - }; - } - - return Optional.empty(); - } -} diff --git a/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.html b/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.html deleted file mode 100755 index b625f8385..000000000 --- a/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.html +++ /dev/null @@ -1,9 +0,0 @@ -

Cryptography Usage: Be careful

- -

Cryptography is a critical component of modern digital security, protecting sensitive data and communications - from unauthorized access. However, implementing cryptographic systems correctly is notoriously challenging, - even for experienced developers. Therefore, caution is necessary when writing code related to - cryptography.

- -

It is important that you read the documentation for the cryptographic library you are using and strictly - adhere to the specified implementation guidelines.

diff --git a/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.json b/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.json deleted file mode 100755 index 43c59154c..000000000 --- a/csharp/src/main/resources/org/sonar/l10n/cs/rules/cs/Inventory.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "title": "Cryptographic Inventory (CBOM)", - "type": "CODE_SMELL", - "status": "ready", - "remediation": { - "func": "Constant\/Issue", - "constantCost": "5min" - }, - "tags": [ - "cryptography", - "cbom", - "cwe" - ], - "defaultSeverity": "Minor", - "scope": "Main", - "sqKey": "Inventory" -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetAESPropertyTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetAESPropertyTestFile.cs deleted file mode 100644 index a97e1add3..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetAESPropertyTestFile.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Security.Cryptography; - -public class DotNetAESPropertyTest -{ - public void TestAesWithProperties() - { - var aes = Aes.Create(); - aes.Mode = CipherMode.CBC; - aes.KeySize = 256; - aes.Padding = PaddingMode.PKCS7; - } - - public void TestAesManagedWithMode() - { - var aes = new AesManaged(); - aes.Mode = CipherMode.ECB; - aes.KeySize = 128; - } -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetAESTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetAESTestFile.cs deleted file mode 100755 index 6f242273f..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetAESTestFile.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Security.Cryptography; - -public class DotNetAESTest -{ - public void TestAesCreate() - { - var aes = Aes.Create(); // Noncompliant - } - - public void TestAesManaged() - { - var aes = new AesManaged(); // Noncompliant - } -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetDESTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetDESTestFile.cs deleted file mode 100755 index 7e53f088e..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetDESTestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetDESTest { - public void TestDesCreate() { var des = DES.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetDSATestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetDSATestFile.cs deleted file mode 100755 index 63e24c9bf..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetDSATestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetDSATest { - public void TestDsaCreate() { var dsa = DSA.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetECDiffieHellmanTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetECDiffieHellmanTestFile.cs deleted file mode 100755 index 2c918535e..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetECDiffieHellmanTestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetECDiffieHellmanTest { - public void TestECDHCreate() { var ecdh = ECDiffieHellman.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetECDsaTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetECDsaTestFile.cs deleted file mode 100755 index addadc0c4..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetECDsaTestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetECDsaTest { - public void TestECDsaCreate() { var ecdsa = ECDsa.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetHMACTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetHMACTestFile.cs deleted file mode 100755 index b652359c4..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetHMACTestFile.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Security.Cryptography; -public class DotNetHMACTest { - public void TestHmacSha1() { var h = new HMACSHA1(); } // Noncompliant - public void TestHmacSha256() { var h = new HMACSHA256(); } // Noncompliant - public void TestHmacSha384() { var h = new HMACSHA384(); } // Noncompliant - public void TestHmacSha512() { var h = new HMACSHA512(); } // Noncompliant - public void TestHmacMd5() { var h = new HMACMD5(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetRC2TestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetRC2TestFile.cs deleted file mode 100755 index ac739520d..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetRC2TestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetRC2Test { - public void TestRc2Create() { var rc2 = RC2.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetRSATestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetRSATestFile.cs deleted file mode 100755 index 147848228..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetRSATestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetRSATest { - public void TestRsaCreate() { var rsa = RSA.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetRfc2898DeriveBytesTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetRfc2898DeriveBytesTestFile.cs deleted file mode 100755 index eefd47425..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetRfc2898DeriveBytesTestFile.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Security.Cryptography; -public class DotNetRfc2898DeriveBytesTest { - public void TestPbkdf2() { - var kdf = new Rfc2898DeriveBytes("password", new byte[16], 10000, HashAlgorithmName.SHA256); // Noncompliant - } -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetSHATestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetSHATestFile.cs deleted file mode 100755 index 9ab3b53cf..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetSHATestFile.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Security.Cryptography; -public class DotNetSHATest { - public void TestSha1Create() { var h = SHA1.Create(); } // Noncompliant - public void TestSha256Create() { var h = SHA256.Create(); } // Noncompliant - public void TestSha384Create() { var h = SHA384.Create(); } // Noncompliant - public void TestSha512Create() { var h = SHA512.Create(); } // Noncompliant - public void TestMd5Create() { var h = MD5.Create(); } // Noncompliant -} diff --git a/csharp/src/test/files/rules/detection/dotnet/DotNetTripleDESTestFile.cs b/csharp/src/test/files/rules/detection/dotnet/DotNetTripleDESTestFile.cs deleted file mode 100755 index 9c85d16ca..000000000 --- a/csharp/src/test/files/rules/detection/dotnet/DotNetTripleDESTestFile.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Security.Cryptography; -public class DotNetTripleDESTest { - public void TestTripleDesCreate() { var des = TripleDES.Create(); } // Noncompliant -} diff --git a/csharp/src/test/java/com/ibm/plugin/CSharpParserErrorListenerTest.java b/csharp/src/test/java/com/ibm/plugin/CSharpParserErrorListenerTest.java deleted file mode 100644 index 9e4f44938..000000000 --- a/csharp/src/test/java/com/ibm/plugin/CSharpParserErrorListenerTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import static org.assertj.core.api.Assertions.assertThat; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; -import com.ibm.engine.language.csharp.antlr.CSharpLexer; -import com.ibm.engine.language.csharp.antlr.CSharpParser; -import java.nio.charset.StandardCharsets; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; - -/** - * Verifies that {@link CSharpParserErrorListener} emits a WARN log when the ANTLR parser encounters - * a syntax error in a C# file. - */ -class CSharpParserErrorListenerTest { - - private Logger listenerLogger; - private ListAppender listAppender; - - @BeforeEach - void setUp() { - listenerLogger = (Logger) LoggerFactory.getLogger(CSharpParserErrorListener.class); - listAppender = new ListAppender<>(); - listAppender.start(); - listenerLogger.addAppender(listAppender); - } - - @AfterEach - void tearDown() { - listenerLogger.detachAppender(listAppender); - } - - @Test - void warningIsLoggedForMalformedCSharp() { - // Incomplete C# — missing closing braces triggers a parse error - String brokenCode = "class Foo { void Bar() { Aes.Create();"; - - InputFile inputFile = - TestInputFileBuilder.create("test-module", "src/Broken.cs") - .setContents(brokenCode) - .setCharset(StandardCharsets.UTF_8) - .setLanguage("cs") - .setType(InputFile.Type.MAIN) - .build(); - - CSharpLexer lexer = - new CSharpLexer(CharStreams.fromString(brokenCode, inputFile.toString())); - lexer.removeErrorListeners(); - lexer.addErrorListener(new CSharpParserErrorListener(inputFile)); - - CommonTokenStream tokens = new CommonTokenStream(lexer); - CSharpParser parser = new CSharpParser(tokens); - parser.removeErrorListeners(); - parser.addErrorListener(new CSharpParserErrorListener(inputFile)); - - parser.compilation_unit(); - - assertThat(listAppender.list) - .isNotEmpty() - .anyMatch( - event -> - event.getLevel() == Level.WARN - && event.getFormattedMessage().contains("Parse error")); - } - - @Test - void noWarningForValidCSharp() { - String validCode = - """ - class Foo { - void Bar() { - var aes = System.Security.Cryptography.Aes.Create(); - } - } - """; - - InputFile inputFile = - TestInputFileBuilder.create("test-module", "src/Valid.cs") - .setContents(validCode) - .setCharset(StandardCharsets.UTF_8) - .setLanguage("cs") - .setType(InputFile.Type.MAIN) - .build(); - - CSharpLexer lexer = - new CSharpLexer(CharStreams.fromString(validCode, inputFile.toString())); - lexer.removeErrorListeners(); - lexer.addErrorListener(new CSharpParserErrorListener(inputFile)); - - CommonTokenStream tokens = new CommonTokenStream(lexer); - CSharpParser parser = new CSharpParser(tokens); - parser.removeErrorListeners(); - parser.addErrorListener(new CSharpParserErrorListener(inputFile)); - - parser.compilation_unit(); - - assertThat(listAppender.list).noneMatch(event -> event.getLevel() == Level.WARN); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/CSharpTreeConverterTest.java b/csharp/src/test/java/com/ibm/plugin/CSharpTreeConverterTest.java deleted file mode 100644 index febb428ab..000000000 --- a/csharp/src/test/java/com/ibm/plugin/CSharpTreeConverterTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.language.csharp.CSharpTreeConverter; -import com.ibm.engine.language.csharp.antlr.CSharpLexer; -import com.ibm.engine.language.csharp.antlr.CSharpParser; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import java.util.List; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.junit.jupiter.api.Test; - -/** - * Verifies that {@link CSharpTreeConverter} correctly extracts the {@code assignedIdentifier} from - * variable declarations ({@code var x = Expr.Create()}) and leaves it null for bare expressions. - */ -class CSharpTreeConverterTest { - - private List parse(String code) { - CSharpLexer lexer = new CSharpLexer(CharStreams.fromString(code)); - lexer.removeErrorListeners(); - CommonTokenStream tokens = new CommonTokenStream(lexer); - CSharpParser parser = new CSharpParser(tokens); - parser.removeErrorListeners(); - CSharpParser.Compilation_unitContext tree = parser.compilation_unit(); - return new CSharpTreeConverter().extractMethodBodies(tree); - } - - @Test - void assignedIdentifierIsSetForVarDeclaration() { - // var aes = Aes.Create(); — result is assigned to "aes" - String code = - """ - class Foo { - void Bar() { - var aes = Aes.Create(); - } - } - """; - - List blocks = parse(code); - List statements = - blocks.stream() - .flatMap(b -> b.getStatements().stream()) - .filter(s -> s instanceof CSharpMethodInvocationTree) - .toList(); - - assertThat(statements).hasSize(1); - CSharpMethodInvocationTree invocation = (CSharpMethodInvocationTree) statements.get(0); - assertThat(invocation.getObjectTypeName()).isEqualTo("Aes"); - assertThat(invocation.getMethodName()).isEqualTo("Create"); - assertThat(invocation.getAssignedIdentifier()).isEqualTo("aes"); - } - - @Test - void assignedIdentifierIsNullForBareExpression() { - // Aes.Create(); — not assigned to any variable - String code = - """ - class Foo { - void Bar() { - Aes.Create(); - } - } - """; - - List blocks = parse(code); - List statements = - blocks.stream() - .flatMap(b -> b.getStatements().stream()) - .filter(s -> s instanceof CSharpMethodInvocationTree) - .toList(); - - assertThat(statements).hasSize(1); - CSharpMethodInvocationTree invocation = (CSharpMethodInvocationTree) statements.get(0); - assertThat(invocation.getAssignedIdentifier()).isNull(); - } - - @Test - void assignedIdentifierIsSetForConstructor() { - // var gcm = new AesGcm(key); — constructor result assigned to "gcm" - String code = - """ - class Foo { - void Bar() { - var gcm = new AesGcm(key); - } - } - """; - - List blocks = parse(code); - List statements = - blocks.stream() - .flatMap(b -> b.getStatements().stream()) - .filter(s -> s instanceof CSharpObjectCreationTree) - .toList(); - - assertThat(statements).hasSize(1); - CSharpObjectCreationTree creation = (CSharpObjectCreationTree) statements.get(0); - assertThat(creation.getTypeName()).isEqualTo("AesGcm"); - assertThat(creation.getAssignedIdentifier()).isEqualTo("gcm"); - } - - @Test - void assignedIdentifierIsNullForBareConstructor() { - // new AesGcm(key); — no assignment - String code = - """ - class Foo { - void Bar() { - new AesGcm(key); - } - } - """; - - List blocks = parse(code); - List statements = - blocks.stream() - .flatMap(b -> b.getStatements().stream()) - .filter(s -> s instanceof CSharpObjectCreationTree) - .toList(); - - assertThat(statements).hasSize(1); - CSharpObjectCreationTree creation = (CSharpObjectCreationTree) statements.get(0); - assertThat(creation.getAssignedIdentifier()).isNull(); - } - - @Test - void multipleDeclarationsGetSeparateIdentifiers() { - // Two declarations in the same block — each gets its own identifier - String code = - """ - class Foo { - void Bar() { - var aes = Aes.Create(); - var rsa = RSA.Create(2048); - } - } - """; - - List blocks = parse(code); - List invocations = - blocks.stream() - .flatMap(b -> b.getStatements().stream()) - .filter(s -> s instanceof CSharpMethodInvocationTree) - .map(s -> (CSharpMethodInvocationTree) s) - .toList(); - - assertThat(invocations).hasSize(2); - - CSharpMethodInvocationTree aesCall = - invocations.stream() - .filter(i -> "Aes".equals(i.getObjectTypeName())) - .findFirst() - .orElseThrow(); - assertThat(aesCall.getAssignedIdentifier()).isEqualTo("aes"); - - CSharpMethodInvocationTree rsaCall = - invocations.stream() - .filter(i -> "RSA".equals(i.getObjectTypeName())) - .findFirst() - .orElseThrow(); - assertThat(rsaCall.getAssignedIdentifier()).isEqualTo("rsa"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/CSharpVerifier.java b/csharp/src/test/java/com/ibm/plugin/CSharpVerifier.java deleted file mode 100755 index 4da5e6e50..000000000 --- a/csharp/src/test/java/com/ibm/plugin/CSharpVerifier.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpTreeConverter; -import com.ibm.engine.language.csharp.antlr.CSharpLexer; -import com.ibm.engine.language.csharp.antlr.CSharpParser; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import javax.annotation.Nonnull; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorContextTester; - -/** - * ANTLR-based verifier for C# detection rule tests. - * - *

Parses a {@code .cs} test file using the ANTLR4 C# grammar, extracts all method bodies, and - * runs the given {@link CSharpCheck} against each block. Findings are observed directly via the - * check's internal observer subscription — no native SonarQube binary required. - * - *

Usage: {@code CSharpVerifier.verify("rules/detection/dotnet/MyTestFile.cs", this);} where the - * path is relative to {@code src/test/files/}. - */ -public final class CSharpVerifier { - - private static final String TEST_FILES_ROOT = "src/test/files/"; - - private CSharpVerifier() { - // utility - } - - /** - * Parses the given test file and runs the check against all discovered method bodies. - * - * @param relativeTestFilePath path to the .cs file relative to {@code src/test/files/} - * @param check the check instance to run (typically a {@code TestBase} subclass) - */ - public static void verify(@Nonnull String relativeTestFilePath, @Nonnull CSharpCheck check) - throws IOException { - Path filePath = Paths.get(TEST_FILES_ROOT + relativeTestFilePath); - String content = Files.readString(filePath, StandardCharsets.UTF_8); - - CSharpLexer lexer = new CSharpLexer(CharStreams.fromString(content, filePath.toString())); - lexer.removeErrorListeners(); - CommonTokenStream tokens = new CommonTokenStream(lexer); - CSharpParser parser = new CSharpParser(tokens); - parser.removeErrorListeners(); - CSharpParser.Compilation_unitContext parseTree = parser.compilation_unit(); - - CSharpTreeConverter converter = new CSharpTreeConverter(); - List methodBodies = converter.extractMethodBodies(parseTree); - - Path moduleRoot = Paths.get(".").toAbsolutePath().normalize(); - SensorContextTester sensorContext = SensorContextTester.create(moduleRoot); - - InputFile inputFile = - TestInputFileBuilder.create("test-module", filePath.toString()) - .setContents(content) - .setCharset(StandardCharsets.UTF_8) - .setLanguage("cs") - .setType(InputFile.Type.MAIN) - .build(); - sensorContext.fileSystem().add(inputFile); - - CSharpScanContext scanContext = - new CSharpScanContext( - sensorContext, inputFile, CSharpScannerRuleDefinition.REPOSITORY_KEY); - - for (CSharpBlockTree blockTree : methodBodies) { - check.scan(scanContext, blockTree); - } - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/TestBase.java b/csharp/src/test/java/com/ibm/plugin/TestBase.java deleted file mode 100755 index 8f47d63bc..000000000 --- a/csharp/src/test/java/com/ibm/plugin/TestBase.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.detection.Finding; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.rule.IDetectionRule; -import com.ibm.engine.utils.DetectionStoreLogger; -import com.ibm.mapper.model.INode; -import com.ibm.plugin.rules.CSharpInventoryRule; -import com.ibm.plugin.rules.detection.CSharpDetectionRules; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.junit.jupiter.api.BeforeEach; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class TestBase extends CSharpInventoryRule { - - private static final Logger LOGGER = LoggerFactory.getLogger(TestBase.class); - - @Nonnull - private final DetectionStoreLogger - detectionStoreLogger = new DetectionStoreLogger<>(); - - private int findingId = 0; - - public TestBase(@Nonnull List> detectionRules) { - super(detectionRules); - } - - public TestBase() { - super(CSharpDetectionRules.rules()); - } - - @BeforeEach - public void resetState() { - CSharpAggregator.reset(); - } - - @BeforeEach - public void resetNodeTreeLog() { - try { - Path logFile = Paths.get("target/node-tree.log"); - Files.createDirectories(logFile.getParent()); - Files.writeString( - logFile, - "=== Node Tree Log: " + getClass().getSimpleName() + " ===\n", - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING); - } catch (IOException e) { - LOGGER.warn("Could not reset node-tree.log", e); - } - } - - @Override - public void update( - @Nonnull Finding finding) { - final DetectionStore - detectionStore = finding.detectionStore(); - detectionStoreLogger.print(detectionStore); - - final List nodes = csharpTranslationProcess.initiate(detectionStore); - writeNodeTree(findingId, nodes); - asserts(findingId, detectionStore, nodes); - findingId++; - this.report(finding.getMarkerTree(), nodes) - .forEach( - issue -> - finding.detectionStore() - .getScanContext() - .reportIssue(this, issue.tree(), issue.message())); - } - - public abstract void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes); - - private void writeNodeTree(int id, @Nonnull List nodes) { - try { - StringBuilder sb = new StringBuilder(); - sb.append("\n[findingId=").append(id).append("] Node tree:\n"); - nodes.forEach(node -> appendNodeTree(sb, node, 0)); - Files.writeString( - Paths.get("target/node-tree.log"), - sb.toString(), - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); - } catch (IOException e) { - LOGGER.warn("Could not write node-tree.log", e); - } - } - - private void appendNodeTree(@Nonnull StringBuilder sb, @Nonnull INode node, int depth) { - String indent = " ".repeat(depth) + (depth > 0 ? "└─ " : ""); - sb.append(indent) - .append(node.getKind().getSimpleName()) - .append(" \"") - .append(node.asString()) - .append("\" [") - .append(node.getOrigin()) - .append("]\n"); - node.getChildren().values().forEach(child -> appendNodeTree(sb, child, depth + 1)); - } - - @Nullable public DetectionStore - getStoreOfValueType( - @Nonnull Class valueType, - @Nonnull - List< - DetectionStore< - CSharpCheck, - CSharpTree, - CSharpSymbol, - CSharpScanContext>> - detectionStores) { - Optional> - relevantStore = - detectionStores.stream() - .filter( - store -> - store.getDetectionValues().stream() - .anyMatch( - value -> - value.getClass() - .equals(valueType))) - .findFirst(); - return relevantStore.orElseGet( - () -> - detectionStores.stream() - .map( - store -> - Optional.ofNullable( - getStoreOfValueType( - valueType, store.getChildren()))) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst() - .orElse(null)); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESPropertyTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESPropertyTest.java deleted file mode 100644 index babbe2772..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESPropertyTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.KeySize; -import com.ibm.engine.model.Mode; -import com.ibm.engine.model.Padding; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.KeyLength; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -/** - * Verifies that property-setter assignments on a detected AES variable are linked back to the - * primary detection via the synthetic {@code set_X} method invocation approach. - * - *

Test scenario (from DotNetAESPropertyTestFile.cs): - * - *

{@code
- * var aes = Aes.Create();
- * aes.Mode = CipherMode.CBC;    // → synthetic set_Mode(CipherMode.CBC)
- * aes.KeySize = 256;            // → synthetic set_KeySize(256)
- * aes.Padding = PaddingMode.PKCS7; // → synthetic set_Padding(PaddingMode.PKCS7)
- * }
- */ -class DotNetAESPropertyTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetAESPropertyTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - - switch (findingId) { - case 0 -> { - /* - * TestAesWithProperties: var aes = Aes.Create() + Mode/KeySize/Padding setters - */ - - // Primary detection: AES - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()) - .isInstanceOf(CipherContext.class); - IValue primaryValue = detectionStore.getDetectionValues().get(0); - assertThat(primaryValue).isInstanceOf(ValueAction.class); - assertThat(primaryValue.asString()).isEqualTo("AES"); - - // Depending rule: set_Mode detected Mode("CBC") - DetectionStore modeStore = - getStoreOfValueType(Mode.class, detectionStore.getChildren()); - assertThat(modeStore).isNotNull(); - assertThat(modeStore.getDetectionValues()).hasSize(1); - assertThat(modeStore.getDetectionValues().get(0).asString()).isEqualTo("CBC"); - - // Depending rule: set_KeySize detected KeySize(256) - DetectionStore - keySizeStore = - getStoreOfValueType(KeySize.class, detectionStore.getChildren()); - assertThat(keySizeStore).isNotNull(); - assertThat(keySizeStore.getDetectionValues()).hasSize(1); - assertThat(keySizeStore.getDetectionValues().get(0).asString()).isEqualTo("256"); - - // Depending rule: set_Padding detected Padding("PKCS7") - DetectionStore - paddingStore = - getStoreOfValueType(Padding.class, detectionStore.getChildren()); - assertThat(paddingStore).isNotNull(); - assertThat(paddingStore.getDetectionValues()).hasSize(1); - assertThat(paddingStore.getDetectionValues().get(0).asString()).isEqualTo("PKCS7"); - - // Translation: BlockCipher node with KeyLength child - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - assertThat(node.asString()).isEqualTo("AES256-CBC-PKCS7"); - INode keyLength = node.getChildren().get(KeyLength.class); - assertThat(keyLength).isNotNull(); - assertThat(keyLength.asString()).isEqualTo("256"); - } - - case 1 -> { - /* - * TestAesManagedWithMode: var aes = new AesManaged() + Mode/KeySize setters - */ - - // Primary detection: AES - assertThat(detectionStore.getDetectionValues()).hasSize(1); - IValue primaryValue = detectionStore.getDetectionValues().get(0); - assertThat(primaryValue).isInstanceOf(ValueAction.class); - assertThat(primaryValue.asString()).isEqualTo("AES"); - - // Depending rule: set_Mode detected Mode("ECB") - DetectionStore modeStore = - getStoreOfValueType(Mode.class, detectionStore.getChildren()); - assertThat(modeStore).isNotNull(); - assertThat(modeStore.getDetectionValues().get(0).asString()).isEqualTo("ECB"); - - // Depending rule: set_KeySize detected KeySize(128) - DetectionStore - keySizeStore = - getStoreOfValueType(KeySize.class, detectionStore.getChildren()); - assertThat(keySizeStore).isNotNull(); - assertThat(keySizeStore.getDetectionValues().get(0).asString()).isEqualTo("128"); - - // Translation: BlockCipher node - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - assertThat(node.asString()).isEqualTo("AES128-ECB"); - } - - default -> throw new IllegalStateException("Unexpected findingId: " + findingId); - } - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESTest.java deleted file mode 100755 index 43858ef62..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetAESTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.BlockSize; -import com.ibm.mapper.model.INode; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetAESTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetAESTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - - /* - * Detection Store - */ - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(CipherContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("AES"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - assertThat(node.asString()).isEqualTo("AES"); - - INode blockSize = node.getChildren().get(BlockSize.class); - assertThat(blockSize).isNotNull(); - assertThat(blockSize.asString()).isEqualTo("128"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDESTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDESTest.java deleted file mode 100755 index d2437244c..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDESTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.BlockSize; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.KeyLength; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetDESTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetDESTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(CipherContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("DES"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - assertThat(node.asString()).startsWith("DES"); - - // DES carries a default key length of 56 bits and block size of 64 bits - INode keyLength = node.getChildren().get(KeyLength.class); - assertThat(keyLength).isNotNull(); - assertThat(keyLength.asString()).isEqualTo("56"); - - INode blockSize = node.getChildren().get(BlockSize.class); - assertThat(blockSize).isNotNull(); - assertThat(blockSize.asString()).isEqualTo("64"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSATest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSATest.java deleted file mode 100755 index 04c43bbf4..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetDSATest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.Oid; -import com.ibm.mapper.model.Signature; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetDSATest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetDSATestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(KeyContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("DSA"); - - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(Signature.class); - assertThat(node.asString()).isEqualTo("DSA"); - - INode oid = node.getChildren().get(Oid.class); - assertThat(oid).isNotNull(); - assertThat(oid.asString()).isEqualTo("1.2.840.10040.4.1"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellmanTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellmanTest.java deleted file mode 100755 index 8b88a4d3a..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDiffieHellmanTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.KeyAgreement; -import com.ibm.mapper.model.Oid; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetECDiffieHellmanTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetECDiffieHellmanTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(KeyContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("ECDH"); - - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(KeyAgreement.class); - assertThat(node.asString()).isEqualTo("ECDH"); - - INode oid = node.getChildren().get(Oid.class); - assertThat(oid).isNotNull(); - assertThat(oid.asString()).isEqualTo("1.3.132.1.12"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsaTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsaTest.java deleted file mode 100755 index f7337a1c3..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetECDsaTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.Signature; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetECDsaTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetECDsaTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(KeyContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("ECDSA"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(Signature.class); - assertThat(node.asString()).isEqualTo("ECDSA"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMACTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMACTest.java deleted file mode 100755 index d361e9640..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetHMACTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.MacContext; -import com.ibm.mapper.model.DigestSize; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.Mac; -import com.ibm.mapper.model.MessageDigest; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetHMACTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetHMACTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - - /* - * Detection Store - */ - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(MacContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(Mac.class); - - switch (findingId) { - case 0 -> { - assertThat(value0.asString()).isEqualTo("HMACSHA1"); - assertThat(node.asString()).isEqualTo("HMAC-SHA1"); - INode digest = node.getChildren().get(MessageDigest.class); - assertThat(digest).isNotNull(); - assertThat(digest.asString()).isEqualTo("SHA1"); - INode digestSize = digest.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("160"); - } - case 1 -> { - assertThat(value0.asString()).isEqualTo("HMACSHA256"); - assertThat(node.asString()).isEqualTo("HMAC-SHA256"); - INode digest = node.getChildren().get(MessageDigest.class); - assertThat(digest).isNotNull(); - assertThat(digest.asString()).isEqualTo("SHA256"); - INode digestSize = digest.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("256"); - } - case 2 -> { - assertThat(value0.asString()).isEqualTo("HMACSHA384"); - assertThat(node.asString()).isEqualTo("HMAC-SHA384"); - INode digest = node.getChildren().get(MessageDigest.class); - assertThat(digest).isNotNull(); - assertThat(digest.asString()).isEqualTo("SHA384"); - INode digestSize = digest.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("384"); - } - case 3 -> { - assertThat(value0.asString()).isEqualTo("HMACSHA512"); - assertThat(node.asString()).isEqualTo("HMAC-SHA512"); - INode digest = node.getChildren().get(MessageDigest.class); - assertThat(digest).isNotNull(); - assertThat(digest.asString()).isEqualTo("SHA512"); - INode digestSize = digest.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("512"); - } - case 4 -> { - assertThat(value0.asString()).isEqualTo("HMACMD5"); - assertThat(node.asString()).isEqualTo("HMAC-MD5"); - INode digest = node.getChildren().get(MessageDigest.class); - assertThat(digest).isNotNull(); - assertThat(digest.asString()).isEqualTo("MD5"); - INode digestSize = digest.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("128"); - } - default -> throw new IllegalStateException("Unexpected findingId: " + findingId); - } - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2Test.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2Test.java deleted file mode 100755 index 512f9fbb4..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRC2Test.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.INode; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetRC2Test extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetRC2TestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(CipherContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("RC2"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - assertThat(node.asString()).isEqualTo("RC2"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSATest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSATest.java deleted file mode 100755 index 5336bc3e1..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRSATest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.Oid; -import com.ibm.mapper.model.PublicKeyEncryption; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetRSATest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetRSATestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore).isNotNull(); - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(KeyContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("RSA"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(PublicKeyEncryption.class); - assertThat(node.asString()).isEqualTo("RSA"); - - // RSA carries its OID as a child node - INode oid = node.getChildren().get(Oid.class); - assertThat(oid).isNotNull(); - assertThat(oid.asString()).isEqualTo("1.2.840.113549.1.1.1"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytesTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytesTest.java deleted file mode 100755 index 4cf6473a4..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetRfc2898DeriveBytesTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.KeyContext; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.PasswordBasedKeyDerivationFunction; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetRfc2898DeriveBytesTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetRfc2898DeriveBytesTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(KeyContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("PBKDF2"); - - assertThat(nodes).hasSize(1); - assertThat(nodes.get(0).getKind()).isEqualTo(PasswordBasedKeyDerivationFunction.class); - assertThat(nodes.get(0).asString()).isEqualTo("PBKDF2"); - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHATest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHATest.java deleted file mode 100755 index 4c877a4c4..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetSHATest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.DigestContext; -import com.ibm.mapper.model.DigestSize; -import com.ibm.mapper.model.INode; -import com.ibm.mapper.model.MessageDigest; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetSHATest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetSHATestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - - /* - * Detection Store - */ - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(DigestContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(MessageDigest.class); - - switch (findingId) { - case 0 -> { - assertThat(value0.asString()).isEqualTo("SHA1"); - assertThat(node.asString()).isEqualTo("SHA1"); - INode digestSize = node.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("160"); - } - case 1 -> { - assertThat(value0.asString()).isEqualTo("SHA256"); - assertThat(node.asString()).isEqualTo("SHA256"); - INode digestSize = node.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("256"); - } - case 2 -> { - assertThat(value0.asString()).isEqualTo("SHA384"); - assertThat(node.asString()).isEqualTo("SHA384"); - INode digestSize = node.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("384"); - } - case 3 -> { - assertThat(value0.asString()).isEqualTo("SHA512"); - assertThat(node.asString()).isEqualTo("SHA512"); - INode digestSize = node.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("512"); - } - case 4 -> { - assertThat(value0.asString()).isEqualTo("MD5"); - assertThat(node.asString()).isEqualTo("MD5"); - INode digestSize = node.getChildren().get(DigestSize.class); - assertThat(digestSize).isNotNull(); - assertThat(digestSize.asString()).isEqualTo("128"); - } - default -> throw new IllegalStateException("Unexpected findingId: " + findingId); - } - } -} diff --git a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDESTest.java b/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDESTest.java deleted file mode 100755 index 36904ba51..000000000 --- a/csharp/src/test/java/com/ibm/plugin/rules/detection/dotnet/DotNetTripleDESTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.plugin.rules.detection.dotnet; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.IValue; -import com.ibm.engine.model.ValueAction; -import com.ibm.engine.model.context.CipherContext; -import com.ibm.mapper.model.BlockCipher; -import com.ibm.mapper.model.BlockSize; -import com.ibm.mapper.model.INode; -import com.ibm.plugin.CSharpVerifier; -import com.ibm.plugin.TestBase; -import java.util.List; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; - -class DotNetTripleDESTest extends TestBase { - - @Test - void test() throws Exception { - CSharpVerifier.verify("rules/detection/dotnet/DotNetTripleDESTestFile.cs", this); - } - - @Override - public void asserts( - int findingId, - @Nonnull - DetectionStore - detectionStore, - @Nonnull List nodes) { - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()).isInstanceOf(CipherContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("TRIPLEDES"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - INode node = nodes.get(0); - assertThat(node.getKind()).isEqualTo(BlockCipher.class); - // DESede is the canonical name for Triple-DES in the mapper model - assertThat(node.asString()).isEqualTo("DESede"); - - // TripleDES carries a default block size of 64 bits - INode blockSize = node.getChildren().get(BlockSize.class); - assertThat(blockSize).isNotNull(); - assertThat(blockSize.asString()).isEqualTo("64"); - } -} diff --git a/engine/pom.xml b/engine/pom.xml index 20acc80fd..7495510f1 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -23,37 +23,6 @@ 2.0.0-SNAPSHOT compile - - - org.antlr - antlr4-runtime - 4.13.1 - - - - - - org.antlr - antlr4-maven-plugin - 4.13.1 - - - antlr4 - - antlr4 - - - ${project.basedir}/src/main/antlr4 - ${project.build.directory}/generated-sources/antlr4 - true - true - - - - - - - - \ No newline at end of file + diff --git a/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpLexer.g4 b/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpLexer.g4 deleted file mode 100755 index ec3c62764..000000000 --- a/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpLexer.g4 +++ /dev/null @@ -1,1066 +0,0 @@ -// EBNF following ECMA 334 Version 7 language specification. -// MIT License. - -// Eclipse Public License - v 1.0, http://www.eclipse.org/legal/epl-v10.html -// Copyright (c) 2013, Christian Wulf (chwchw@gmx.de) -// Copyright (c) 2016-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. - -// $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false -// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine -// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true - -lexer grammar CSharpLexer; - -channels { - COMMENTS_CHANNEL, - DIRECTIVE -} - -options { - superClass = CSharpLexerBase; -} - -// Insert here @header for lexer. - -BYTE_ORDER_MARK: '\u00EF\u00BB\u00BF'; - -SINGLE_LINE_DOC_COMMENT : '///' InputCharacter* -> channel(COMMENTS_CHANNEL); -EMPTY_DELIMITED_DOC_COMMENT : '/***/' -> channel(COMMENTS_CHANNEL); -DELIMITED_DOC_COMMENT : '/**' ~'/' .*? '*/' -> channel(COMMENTS_CHANNEL); -SINGLE_LINE_COMMENT : '//' InputCharacter* -> channel(COMMENTS_CHANNEL); -DELIMITED_COMMENT : '/*' .*? '*/' -> channel(COMMENTS_CHANNEL); -WHITESPACES : (Whitespace | NewLine)+ -> channel(HIDDEN); -SHARP : '#' -> mode(DIRECTIVE_MODE), skip; - -ABSTRACT : 'abstract'; -ADD : 'add'; -ALIAS : 'alias'; -ARGLIST : '__arglist'; -AS : 'as'; -ASCENDING : 'ascending'; -ASYNC : 'async'; -AWAIT : 'await'; -BASE : 'base'; -BOOL : 'bool'; -BREAK : 'break'; -BY : 'by'; -BYTE : 'byte'; -CASE : 'case'; -CATCH : 'catch'; -CHAR : 'char'; -CHECKED : 'checked'; -CLASS : 'class'; -CONST : 'const'; -CONTINUE : 'continue'; -DECIMAL : 'decimal'; -DEFAULT : 'default'; -DELEGATE : 'delegate'; -DESCENDING : 'descending'; -DO : 'do'; -DOUBLE : 'double'; -DYNAMIC : 'dynamic'; -ELSE : 'else'; -ENUM : 'enum'; -EQUALS : 'equals'; -EVENT : 'event'; -EXPLICIT : 'explicit'; -EXTERN : 'extern'; -FALSE : 'false'; -FINALLY : 'finally'; -FIXED : 'fixed'; -FLOAT : 'float'; -FOR : 'for'; -FOREACH : 'foreach'; -FROM : 'from'; -GET : 'get'; -GOTO : 'goto'; -GROUP : 'group'; -IF : 'if'; -IMPLICIT : 'implicit'; -IN : 'in'; -INT : 'int'; -INTERFACE : 'interface'; -INTERNAL : 'internal'; -INTO : 'into'; -IS : 'is'; -JOIN : 'join'; -LET : 'let'; -LOCK : 'lock'; -LONG : 'long'; -NAMEOF : 'nameof'; -NAMESPACE : 'namespace'; -NEW : 'new'; -NULL_ : 'null'; -OBJECT : 'object'; -ON : 'on'; -OPERATOR : 'operator'; -ORDERBY : 'orderby'; -OUT : 'out'; -OVERRIDE : 'override'; -PARAMS : 'params'; -PARTIAL : 'partial'; -PRIVATE : 'private'; -PROTECTED : 'protected'; -PUBLIC : 'public'; -READONLY : 'readonly'; -REF : 'ref'; -REMOVE : 'remove'; -RETURN : 'return'; -SBYTE : 'sbyte'; -SEALED : 'sealed'; -SELECT : 'select'; -SET : 'set'; -SHORT : 'short'; -SIZEOF : 'sizeof'; -STACKALLOC : 'stackalloc'; -STATIC : 'static'; -STRING : 'string'; -STRUCT : 'struct'; -SWITCH : 'switch'; -THIS : 'this'; -THROW : 'throw'; -TRUE : 'true'; -TRY : 'try'; -TYPEOF : 'typeof'; -UINT : 'uint'; -ULONG : 'ulong'; -UNCHECKED : 'unchecked'; -UNMANAGED : 'unmanaged'; -UNSAFE : 'unsafe'; -USHORT : 'ushort'; -USING : 'using'; -VAR : 'var'; -VIRTUAL : 'virtual'; -VOID : 'void'; -VOLATILE : 'volatile'; -WHEN : 'when'; -WHERE : 'where'; -WHILE : 'while'; -YIELD : 'yield'; - -//B.1.6 Identifiers -// must be defined after all keywords so the first branch (Available_identifier) does not match keywords -// https://msdn.microsoft.com/en-us/library/aa664670(v=vs.71).aspx -IDENTIFIER: '@'? IdentifierOrKeyword; - -//B.1.8 Literals -// 0.Equals() would be parsed as an invalid real (1. branch) causing a lexer error -LITERAL_ACCESS : [0-9] ('_'* [0-9])* IntegerTypeSuffix? '.' '@'? IdentifierOrKeyword; -INTEGER_LITERAL : [0-9] ('_'* [0-9])* IntegerTypeSuffix?; -HEX_INTEGER_LITERAL : '0' [xX] ('_'* HexDigit)+ IntegerTypeSuffix?; -BIN_INTEGER_LITERAL : '0' [bB] ('_'* [01])+ IntegerTypeSuffix?; -REAL_LITERAL: - ([0-9] ('_'* [0-9])*)? '.' [0-9] ('_'* [0-9])* ExponentPart? [FfDdMm]? - | [0-9] ('_'* [0-9])* ([FfDdMm] | ExponentPart [FfDdMm]?) -; - -CHARACTER_LITERAL : '\'' (~['\\\r\n\u0085\u2028\u2029] | CommonCharacter) '\''; -REGULAR_STRING : '"' (~["\\\r\n\u0085\u2028\u2029] | CommonCharacter)* '"'; -VERBATIUM_STRING : '@"' (~'"' | '""')* '"'; -INTERPOLATED_REGULAR_STRING_START: - '$"' { this.OnInterpolatedRegularStringStart(); } -> pushMode(INTERPOLATION_STRING) -; -INTERPOLATED_VERBATIUM_STRING_START: - '$@"' { this.OnInterpolatedVerbatiumStringStart(); } -> pushMode(INTERPOLATION_STRING) -; - -//B.1.9 Operators And Punctuators -OPEN_BRACE : '{' { this.OnOpenBrace(); }; -CLOSE_BRACE : '}' { this.OnCloseBrace(); }; -OPEN_BRACKET : '['; -CLOSE_BRACKET : ']'; -OPEN_PARENS : '('; -CLOSE_PARENS : ')'; -DOT : '.'; -COMMA : ','; -COLON : ':' { this.OnColon(); }; -SEMICOLON : ';'; -PLUS : '+'; -MINUS : '-'; -STAR : '*'; -DIV : '/'; -PERCENT : '%'; -AMP : '&'; -BITWISE_OR : '|'; -CARET : '^'; -BANG : '!'; -TILDE : '~'; -ASSIGNMENT : '='; -LT : '<'; -GT : '>'; -INTERR : '?'; -DOUBLE_COLON : '::'; -OP_COALESCING : '??'; -OP_INC : '++'; -OP_DEC : '--'; -OP_AND : '&&'; -OP_OR : '||'; -OP_PTR : '->'; -OP_EQ : '=='; -OP_NE : '!='; -OP_LE : '<='; -OP_GE : '>='; -OP_ADD_ASSIGNMENT : '+='; -OP_SUB_ASSIGNMENT : '-='; -OP_MULT_ASSIGNMENT : '*='; -OP_DIV_ASSIGNMENT : '/='; -OP_MOD_ASSIGNMENT : '%='; -OP_AND_ASSIGNMENT : '&='; -OP_OR_ASSIGNMENT : '|='; -OP_XOR_ASSIGNMENT : '^='; -OP_LEFT_SHIFT : '<<'; -OP_LEFT_SHIFT_ASSIGNMENT : '<<='; -OP_COALESCING_ASSIGNMENT : '??='; -OP_RANGE : '..'; - -// Emitted programmatically by CSharpLexerBase for false #if blocks; never matched from input. -SKIPPED_SECTION : '\u0000' -> channel(HIDDEN); - -// https://msdn.microsoft.com/en-us/library/dn961160.aspx -mode INTERPOLATION_STRING; - -DOUBLE_CURLY_INSIDE : '{{'; -OPEN_BRACE_INSIDE : '{' { this.OpenBraceInside(); } -> skip, pushMode(DEFAULT_MODE); -REGULAR_CHAR_INSIDE : { this.IsRegularCharInside() }? SimpleEscapeSequence; -VERBATIUM_DOUBLE_QUOTE_INSIDE : { this.IsVerbatiumDoubleQuoteInside() }? '""'; -DOUBLE_QUOTE_INSIDE : '"' { this.OnDoubleQuoteInside(); } -> popMode; -REGULAR_STRING_INSIDE : { this.IsRegularCharInside() }? ~('{' | '\\' | '"')+; -VERBATIUM_INSIDE_STRING : { this.IsVerbatiumDoubleQuoteInside() }? ~('{' | '"')+; - -mode INTERPOLATION_FORMAT; - -DOUBLE_CURLY_CLOSE_INSIDE : '}}' -> type(FORMAT_STRING); -CLOSE_BRACE_INSIDE : '}' { this.OnCloseBraceInside(); } -> skip, popMode; -FORMAT_STRING : ~'}'+; - -mode DIRECTIVE_MODE; - -DIRECTIVE_WHITESPACES : Whitespace+ -> channel(HIDDEN); -DIGITS : [0-9]+ -> channel(DIRECTIVE); -DIRECTIVE_TRUE : 'true' -> channel(DIRECTIVE), type(TRUE); -DIRECTIVE_FALSE : 'false' -> channel(DIRECTIVE), type(FALSE); -DEFINE : 'define' -> channel(DIRECTIVE); -UNDEF : 'undef' -> channel(DIRECTIVE); -DIRECTIVE_IF : 'if' -> channel(DIRECTIVE), type(IF); -ELIF : 'elif' -> channel(DIRECTIVE); -DIRECTIVE_ELSE : 'else' -> channel(DIRECTIVE), type(ELSE); -ENDIF : 'endif' -> channel(DIRECTIVE); -LINE : 'line' -> channel(DIRECTIVE); -ERROR : 'error' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -WARNING : 'warning' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -REGION : 'region' Whitespace* -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -ENDREGION : 'endregion' Whitespace* -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -PRAGMA : 'pragma' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -NULLABLE : 'nullable' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); -DIRECTIVE_DEFAULT : 'default' -> channel(DIRECTIVE), type(DEFAULT); -DIRECTIVE_HIDDEN : 'hidden' -> channel(DIRECTIVE); -DIRECTIVE_OPEN_PARENS : '(' -> channel(DIRECTIVE), type(OPEN_PARENS); -DIRECTIVE_CLOSE_PARENS : ')' -> channel(DIRECTIVE), type(CLOSE_PARENS); -DIRECTIVE_BANG : '!' -> channel(DIRECTIVE), type(BANG); -DIRECTIVE_OP_EQ : '==' -> channel(DIRECTIVE), type(OP_EQ); -DIRECTIVE_OP_NE : '!=' -> channel(DIRECTIVE), type(OP_NE); -DIRECTIVE_OP_AND : '&&' -> channel(DIRECTIVE), type(OP_AND); -DIRECTIVE_OP_OR : '||' -> channel(DIRECTIVE), type(OP_OR); -DIRECTIVE_STRING: - '"' ~('"' | [\r\n\u0085\u2028\u2029])* '"' -> channel(DIRECTIVE), type(STRING) -; -CONDITIONAL_SYMBOL: IdentifierOrKeyword -> channel(DIRECTIVE); -DIRECTIVE_SINGLE_LINE_COMMENT: - '//' ~[\r\n\u0085\u2028\u2029]* -> channel(COMMENTS_CHANNEL), type(SINGLE_LINE_COMMENT) -; -DIRECTIVE_NEW_LINE: NewLine -> channel(DIRECTIVE), mode(DEFAULT_MODE); - -mode DIRECTIVE_TEXT; - -TEXT : ~[\r\n\u0085\u2028\u2029]+ -> channel(DIRECTIVE); -TEXT_NEW_LINE : NewLine -> channel(DIRECTIVE), type(DIRECTIVE_NEW_LINE), mode(DEFAULT_MODE); - -// Fragments - -fragment InputCharacter: ~[\r\n\u0085\u2028\u2029]; - -fragment NewLineCharacter: - '\u000D' //'' - | '\u000A' //'' - | '\u0085' //'' - | '\u2028' //'' - | '\u2029' //'' -; - -fragment IntegerTypeSuffix : [lL]? [uU] | [uU]? [lL]; -fragment ExponentPart : [eE] ('+' | '-')? [0-9] ('_'* [0-9])*; - -fragment CommonCharacter: SimpleEscapeSequence | HexEscapeSequence | UnicodeEscapeSequence; - -fragment SimpleEscapeSequence: - '\\\'' - | '\\"' - | '\\\\' - | '\\0' - | '\\a' - | '\\b' - | '\\f' - | '\\n' - | '\\r' - | '\\t' - | '\\v' -; - -fragment HexEscapeSequence: - '\\x' HexDigit - | '\\x' HexDigit HexDigit - | '\\x' HexDigit HexDigit HexDigit - | '\\x' HexDigit HexDigit HexDigit HexDigit -; - -fragment NewLine: - '\r\n' - | '\r' - | '\n' - | '\u0085' // ' - | '\u2028' //'' - | '\u2029' //'' -; - -fragment Whitespace: - UnicodeClassZS //'' - | '\u0009' //'' - | '\u000B' //'' - | '\u000C' //'
' -; - -fragment UnicodeClassZS: - '\u0020' // SPACE - | '\u00A0' // NO_BREAK SPACE - | '\u1680' // OGHAM SPACE MARK - | '\u180E' // MONGOLIAN VOWEL SEPARATOR - | '\u2000' // EN QUAD - | '\u2001' // EM QUAD - | '\u2002' // EN SPACE - | '\u2003' // EM SPACE - | '\u2004' // THREE_PER_EM SPACE - | '\u2005' // FOUR_PER_EM SPACE - | '\u2006' // SIX_PER_EM SPACE - | '\u2008' // PUNCTUATION SPACE - | '\u2009' // THIN SPACE - | '\u200A' // HAIR SPACE - | '\u202F' // NARROW NO_BREAK SPACE - | '\u3000' // IDEOGRAPHIC SPACE - | '\u205F' // MEDIUM MATHEMATICAL SPACE -; - -fragment IdentifierOrKeyword: IdentifierStartCharacter IdentifierPartCharacter*; - -fragment IdentifierStartCharacter: LetterCharacter | '_'; - -fragment IdentifierPartCharacter: - LetterCharacter - | DecimalDigitCharacter - | ConnectingCharacter - | CombiningCharacter - | FormattingCharacter -; - -//'' -// WARNING: ignores UnicodeEscapeSequence -fragment LetterCharacter: - UnicodeClassLU - | UnicodeClassLL - | UnicodeClassLT - | UnicodeClassLM - | UnicodeClassLO - | UnicodeClassNL - | UnicodeEscapeSequence -; - -//'' -// WARNING: ignores UnicodeEscapeSequence -fragment DecimalDigitCharacter: UnicodeClassND | UnicodeEscapeSequence; - -//'' -// WARNING: ignores UnicodeEscapeSequence -fragment ConnectingCharacter: UnicodeClassPC | UnicodeEscapeSequence; - -//'' -// WARNING: ignores UnicodeEscapeSequence -fragment CombiningCharacter: UnicodeClassMN | UnicodeClassMC | UnicodeEscapeSequence; - -//'' -// WARNING: ignores UnicodeEscapeSequence -fragment FormattingCharacter: UnicodeClassCF | UnicodeEscapeSequence; - -//B.1.5 Unicode Character Escape Sequences -fragment UnicodeEscapeSequence: - '\\u' HexDigit HexDigit HexDigit HexDigit - | '\\U' HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit -; - -fragment HexDigit: [0-9] | [A-F] | [a-f]; - -// Unicode character classes -fragment UnicodeClassLU: - '\u0041' ..'\u005a' - | '\u00c0' ..'\u00d6' - | '\u00d8' ..'\u00de' - | '\u0100' ..'\u0136' - | '\u0139' ..'\u0147' - | '\u014a' ..'\u0178' - | '\u0179' ..'\u017d' - | '\u0181' ..'\u0182' - | '\u0184' ..'\u0186' - | '\u0187' ..'\u0189' - | '\u018a' ..'\u018b' - | '\u018e' ..'\u0191' - | '\u0193' ..'\u0194' - | '\u0196' ..'\u0198' - | '\u019c' ..'\u019d' - | '\u019f' ..'\u01a0' - | '\u01a2' ..'\u01a6' - | '\u01a7' ..'\u01a9' - | '\u01ac' ..'\u01ae' - | '\u01af' ..'\u01b1' - | '\u01b2' ..'\u01b3' - | '\u01b5' ..'\u01b7' - | '\u01b8' ..'\u01bc' - | '\u01c4' ..'\u01cd' - | '\u01cf' ..'\u01db' - | '\u01de' ..'\u01ee' - | '\u01f1' ..'\u01f4' - | '\u01f6' ..'\u01f8' - | '\u01fa' ..'\u0232' - | '\u023a' ..'\u023b' - | '\u023d' ..'\u023e' - | '\u0241' ..'\u0243' - | '\u0244' ..'\u0246' - | '\u0248' ..'\u024e' - | '\u0370' ..'\u0372' - | '\u0376' ..'\u037f' - | '\u0386' ..'\u0388' - | '\u0389' ..'\u038a' - | '\u038c' ..'\u038e' - | '\u038f' ..'\u0391' - | '\u0392' ..'\u03a1' - | '\u03a3' ..'\u03ab' - | '\u03cf' ..'\u03d2' - | '\u03d3' ..'\u03d4' - | '\u03d8' ..'\u03ee' - | '\u03f4' ..'\u03f7' - | '\u03f9' ..'\u03fa' - | '\u03fd' ..'\u042f' - | '\u0460' ..'\u0480' - | '\u048a' ..'\u04c0' - | '\u04c1' ..'\u04cd' - | '\u04d0' ..'\u052e' - | '\u0531' ..'\u0556' - | '\u10a0' ..'\u10c5' - | '\u10c7' ..'\u10cd' - | '\u1e00' ..'\u1e94' - | '\u1e9e' ..'\u1efe' - | '\u1f08' ..'\u1f0f' - | '\u1f18' ..'\u1f1d' - | '\u1f28' ..'\u1f2f' - | '\u1f38' ..'\u1f3f' - | '\u1f48' ..'\u1f4d' - | '\u1f59' ..'\u1f5f' - | '\u1f68' ..'\u1f6f' - | '\u1fb8' ..'\u1fbb' - | '\u1fc8' ..'\u1fcb' - | '\u1fd8' ..'\u1fdb' - | '\u1fe8' ..'\u1fec' - | '\u1ff8' ..'\u1ffb' - | '\u2102' ..'\u2107' - | '\u210b' ..'\u210d' - | '\u2110' ..'\u2112' - | '\u2115' ..'\u2119' - | '\u211a' ..'\u211d' - | '\u2124' ..'\u212a' - | '\u212b' ..'\u212d' - | '\u2130' ..'\u2133' - | '\u213e' ..'\u213f' - | '\u2145' ..'\u2183' - | '\u2c00' ..'\u2c2e' - | '\u2c60' ..'\u2c62' - | '\u2c63' ..'\u2c64' - | '\u2c67' ..'\u2c6d' - | '\u2c6e' ..'\u2c70' - | '\u2c72' ..'\u2c75' - | '\u2c7e' ..'\u2c80' - | '\u2c82' ..'\u2ce2' - | '\u2ceb' ..'\u2ced' - | '\u2cf2' ..'\ua640' - | '\ua642' ..'\ua66c' - | '\ua680' ..'\ua69a' - | '\ua722' ..'\ua72e' - | '\ua732' ..'\ua76e' - | '\ua779' ..'\ua77d' - | '\ua77e' ..'\ua786' - | '\ua78b' ..'\ua78d' - | '\ua790' ..'\ua792' - | '\ua796' ..'\ua7aa' - | '\ua7ab' ..'\ua7ad' - | '\ua7b0' ..'\ua7b1' - | '\uff21' ..'\uff3a' -; - -fragment UnicodeClassLL: - '\u0061' ..'\u007A' - | '\u00b5' ..'\u00df' - | '\u00e0' ..'\u00f6' - | '\u00f8' ..'\u00ff' - | '\u0101' ..'\u0137' - | '\u0138' ..'\u0148' - | '\u0149' ..'\u0177' - | '\u017a' ..'\u017e' - | '\u017f' ..'\u0180' - | '\u0183' ..'\u0185' - | '\u0188' ..'\u018c' - | '\u018d' ..'\u0192' - | '\u0195' ..'\u0199' - | '\u019a' ..'\u019b' - | '\u019e' ..'\u01a1' - | '\u01a3' ..'\u01a5' - | '\u01a8' ..'\u01aa' - | '\u01ab' ..'\u01ad' - | '\u01b0' ..'\u01b4' - | '\u01b6' ..'\u01b9' - | '\u01ba' ..'\u01bd' - | '\u01be' ..'\u01bf' - | '\u01c6' ..'\u01cc' - | '\u01ce' ..'\u01dc' - | '\u01dd' ..'\u01ef' - | '\u01f0' ..'\u01f3' - | '\u01f5' ..'\u01f9' - | '\u01fb' ..'\u0233' - | '\u0234' ..'\u0239' - | '\u023c' ..'\u023f' - | '\u0240' ..'\u0242' - | '\u0247' ..'\u024f' - | '\u0250' ..'\u0293' - | '\u0295' ..'\u02af' - | '\u0371' ..'\u0373' - | '\u0377' ..'\u037b' - | '\u037c' ..'\u037d' - | '\u0390' ..'\u03ac' - | '\u03ad' ..'\u03ce' - | '\u03d0' ..'\u03d1' - | '\u03d5' ..'\u03d7' - | '\u03d9' ..'\u03ef' - | '\u03f0' ..'\u03f3' - | '\u03f5' ..'\u03fb' - | '\u03fc' ..'\u0430' - | '\u0431' ..'\u045f' - | '\u0461' ..'\u0481' - | '\u048b' ..'\u04bf' - | '\u04c2' ..'\u04ce' - | '\u04cf' ..'\u052f' - | '\u0561' ..'\u0587' - | '\u1d00' ..'\u1d2b' - | '\u1d6b' ..'\u1d77' - | '\u1d79' ..'\u1d9a' - | '\u1e01' ..'\u1e95' - | '\u1e96' ..'\u1e9d' - | '\u1e9f' ..'\u1eff' - | '\u1f00' ..'\u1f07' - | '\u1f10' ..'\u1f15' - | '\u1f20' ..'\u1f27' - | '\u1f30' ..'\u1f37' - | '\u1f40' ..'\u1f45' - | '\u1f50' ..'\u1f57' - | '\u1f60' ..'\u1f67' - | '\u1f70' ..'\u1f7d' - | '\u1f80' ..'\u1f87' - | '\u1f90' ..'\u1f97' - | '\u1fa0' ..'\u1fa7' - | '\u1fb0' ..'\u1fb4' - | '\u1fb6' ..'\u1fb7' - | '\u1fbe' ..'\u1fc2' - | '\u1fc3' ..'\u1fc4' - | '\u1fc6' ..'\u1fc7' - | '\u1fd0' ..'\u1fd3' - | '\u1fd6' ..'\u1fd7' - | '\u1fe0' ..'\u1fe7' - | '\u1ff2' ..'\u1ff4' - | '\u1ff6' ..'\u1ff7' - | '\u210a' ..'\u210e' - | '\u210f' ..'\u2113' - | '\u212f' ..'\u2139' - | '\u213c' ..'\u213d' - | '\u2146' ..'\u2149' - | '\u214e' ..'\u2184' - | '\u2c30' ..'\u2c5e' - | '\u2c61' ..'\u2c65' - | '\u2c66' ..'\u2c6c' - | '\u2c71' ..'\u2c73' - | '\u2c74' ..'\u2c76' - | '\u2c77' ..'\u2c7b' - | '\u2c81' ..'\u2ce3' - | '\u2ce4' ..'\u2cec' - | '\u2cee' ..'\u2cf3' - | '\u2d00' ..'\u2d25' - | '\u2d27' ..'\u2d2d' - | '\ua641' ..'\ua66d' - | '\ua681' ..'\ua69b' - | '\ua723' ..'\ua72f' - | '\ua730' ..'\ua731' - | '\ua733' ..'\ua771' - | '\ua772' ..'\ua778' - | '\ua77a' ..'\ua77c' - | '\ua77f' ..'\ua787' - | '\ua78c' ..'\ua78e' - | '\ua791' ..'\ua793' - | '\ua794' ..'\ua795' - | '\ua797' ..'\ua7a9' - | '\ua7fa' ..'\uab30' - | '\uab31' ..'\uab5a' - | '\uab64' ..'\uab65' - | '\ufb00' ..'\ufb06' - | '\ufb13' ..'\ufb17' - | '\uff41' ..'\uff5a' -; - -fragment UnicodeClassLT: - '\u01c5' ..'\u01cb' - | '\u01f2' ..'\u1f88' - | '\u1f89' ..'\u1f8f' - | '\u1f98' ..'\u1f9f' - | '\u1fa8' ..'\u1faf' - | '\u1fbc' ..'\u1fcc' - | '\u1ffc' ..'\u1ffc' -; - -fragment UnicodeClassLM: - '\u02b0' ..'\u02c1' - | '\u02c6' ..'\u02d1' - | '\u02e0' ..'\u02e4' - | '\u02ec' ..'\u02ee' - | '\u0374' ..'\u037a' - | '\u0559' ..'\u0640' - | '\u06e5' ..'\u06e6' - | '\u07f4' ..'\u07f5' - | '\u07fa' ..'\u081a' - | '\u0824' ..'\u0828' - | '\u0971' ..'\u0e46' - | '\u0ec6' ..'\u10fc' - | '\u17d7' ..'\u1843' - | '\u1aa7' ..'\u1c78' - | '\u1c79' ..'\u1c7d' - | '\u1d2c' ..'\u1d6a' - | '\u1d78' ..'\u1d9b' - | '\u1d9c' ..'\u1dbf' - | '\u2071' ..'\u207f' - | '\u2090' ..'\u209c' - | '\u2c7c' ..'\u2c7d' - | '\u2d6f' ..'\u2e2f' - | '\u3005' ..'\u3031' - | '\u3032' ..'\u3035' - | '\u303b' ..'\u309d' - | '\u309e' ..'\u30fc' - | '\u30fd' ..'\u30fe' - | '\ua015' ..'\ua4f8' - | '\ua4f9' ..'\ua4fd' - | '\ua60c' ..'\ua67f' - | '\ua69c' ..'\ua69d' - | '\ua717' ..'\ua71f' - | '\ua770' ..'\ua788' - | '\ua7f8' ..'\ua7f9' - | '\ua9cf' ..'\ua9e6' - | '\uaa70' ..'\uaadd' - | '\uaaf3' ..'\uaaf4' - | '\uab5c' ..'\uab5f' - | '\uff70' ..'\uff9e' - | '\uff9f' ..'\uff9f' -; - -fragment UnicodeClassLO: - '\u00aa' ..'\u00ba' - | '\u01bb' ..'\u01c0' - | '\u01c1' ..'\u01c3' - | '\u0294' ..'\u05d0' - | '\u05d1' ..'\u05ea' - | '\u05f0' ..'\u05f2' - | '\u0620' ..'\u063f' - | '\u0641' ..'\u064a' - | '\u066e' ..'\u066f' - | '\u0671' ..'\u06d3' - | '\u06d5' ..'\u06ee' - | '\u06ef' ..'\u06fa' - | '\u06fb' ..'\u06fc' - | '\u06ff' ..'\u0710' - | '\u0712' ..'\u072f' - | '\u074d' ..'\u07a5' - | '\u07b1' ..'\u07ca' - | '\u07cb' ..'\u07ea' - | '\u0800' ..'\u0815' - | '\u0840' ..'\u0858' - | '\u08a0' ..'\u08b2' - | '\u0904' ..'\u0939' - | '\u093d' ..'\u0950' - | '\u0958' ..'\u0961' - | '\u0972' ..'\u0980' - | '\u0985' ..'\u098c' - | '\u098f' ..'\u0990' - | '\u0993' ..'\u09a8' - | '\u09aa' ..'\u09b0' - | '\u09b2' ..'\u09b6' - | '\u09b7' ..'\u09b9' - | '\u09bd' ..'\u09ce' - | '\u09dc' ..'\u09dd' - | '\u09df' ..'\u09e1' - | '\u09f0' ..'\u09f1' - | '\u0a05' ..'\u0a0a' - | '\u0a0f' ..'\u0a10' - | '\u0a13' ..'\u0a28' - | '\u0a2a' ..'\u0a30' - | '\u0a32' ..'\u0a33' - | '\u0a35' ..'\u0a36' - | '\u0a38' ..'\u0a39' - | '\u0a59' ..'\u0a5c' - | '\u0a5e' ..'\u0a72' - | '\u0a73' ..'\u0a74' - | '\u0a85' ..'\u0a8d' - | '\u0a8f' ..'\u0a91' - | '\u0a93' ..'\u0aa8' - | '\u0aaa' ..'\u0ab0' - | '\u0ab2' ..'\u0ab3' - | '\u0ab5' ..'\u0ab9' - | '\u0abd' ..'\u0ad0' - | '\u0ae0' ..'\u0ae1' - | '\u0b05' ..'\u0b0c' - | '\u0b0f' ..'\u0b10' - | '\u0b13' ..'\u0b28' - | '\u0b2a' ..'\u0b30' - | '\u0b32' ..'\u0b33' - | '\u0b35' ..'\u0b39' - | '\u0b3d' ..'\u0b5c' - | '\u0b5d' ..'\u0b5f' - | '\u0b60' ..'\u0b61' - | '\u0b71' ..'\u0b83' - | '\u0b85' ..'\u0b8a' - | '\u0b8e' ..'\u0b90' - | '\u0b92' ..'\u0b95' - | '\u0b99' ..'\u0b9a' - | '\u0b9c' ..'\u0b9e' - | '\u0b9f' ..'\u0ba3' - | '\u0ba4' ..'\u0ba8' - | '\u0ba9' ..'\u0baa' - | '\u0bae' ..'\u0bb9' - | '\u0bd0' ..'\u0c05' - | '\u0c06' ..'\u0c0c' - | '\u0c0e' ..'\u0c10' - | '\u0c12' ..'\u0c28' - | '\u0c2a' ..'\u0c39' - | '\u0c3d' ..'\u0c58' - | '\u0c59' ..'\u0c60' - | '\u0c61' ..'\u0c85' - | '\u0c86' ..'\u0c8c' - | '\u0c8e' ..'\u0c90' - | '\u0c92' ..'\u0ca8' - | '\u0caa' ..'\u0cb3' - | '\u0cb5' ..'\u0cb9' - | '\u0cbd' ..'\u0cde' - | '\u0ce0' ..'\u0ce1' - | '\u0cf1' ..'\u0cf2' - | '\u0d05' ..'\u0d0c' - | '\u0d0e' ..'\u0d10' - | '\u0d12' ..'\u0d3a' - | '\u0d3d' ..'\u0d4e' - | '\u0d60' ..'\u0d61' - | '\u0d7a' ..'\u0d7f' - | '\u0d85' ..'\u0d96' - | '\u0d9a' ..'\u0db1' - | '\u0db3' ..'\u0dbb' - | '\u0dbd' ..'\u0dc0' - | '\u0dc1' ..'\u0dc6' - | '\u0e01' ..'\u0e30' - | '\u0e32' ..'\u0e33' - | '\u0e40' ..'\u0e45' - | '\u0e81' ..'\u0e82' - | '\u0e84' ..'\u0e87' - | '\u0e88' ..'\u0e8a' - | '\u0e8d' ..'\u0e94' - | '\u0e95' ..'\u0e97' - | '\u0e99' ..'\u0e9f' - | '\u0ea1' ..'\u0ea3' - | '\u0ea5' ..'\u0ea7' - | '\u0eaa' ..'\u0eab' - | '\u0ead' ..'\u0eb0' - | '\u0eb2' ..'\u0eb3' - | '\u0ebd' ..'\u0ec0' - | '\u0ec1' ..'\u0ec4' - | '\u0edc' ..'\u0edf' - | '\u0f00' ..'\u0f40' - | '\u0f41' ..'\u0f47' - | '\u0f49' ..'\u0f6c' - | '\u0f88' ..'\u0f8c' - | '\u1000' ..'\u102a' - | '\u103f' ..'\u1050' - | '\u1051' ..'\u1055' - | '\u105a' ..'\u105d' - | '\u1061' ..'\u1065' - | '\u1066' ..'\u106e' - | '\u106f' ..'\u1070' - | '\u1075' ..'\u1081' - | '\u108e' ..'\u10d0' - | '\u10d1' ..'\u10fa' - | '\u10fd' ..'\u1248' - | '\u124a' ..'\u124d' - | '\u1250' ..'\u1256' - | '\u1258' ..'\u125a' - | '\u125b' ..'\u125d' - | '\u1260' ..'\u1288' - | '\u128a' ..'\u128d' - | '\u1290' ..'\u12b0' - | '\u12b2' ..'\u12b5' - | '\u12b8' ..'\u12be' - | '\u12c0' ..'\u12c2' - | '\u12c3' ..'\u12c5' - | '\u12c8' ..'\u12d6' - | '\u12d8' ..'\u1310' - | '\u1312' ..'\u1315' - | '\u1318' ..'\u135a' - | '\u1380' ..'\u138f' - | '\u13a0' ..'\u13f4' - | '\u1401' ..'\u166c' - | '\u166f' ..'\u167f' - | '\u1681' ..'\u169a' - | '\u16a0' ..'\u16ea' - | '\u16f1' ..'\u16f8' - | '\u1700' ..'\u170c' - | '\u170e' ..'\u1711' - | '\u1720' ..'\u1731' - | '\u1740' ..'\u1751' - | '\u1760' ..'\u176c' - | '\u176e' ..'\u1770' - | '\u1780' ..'\u17b3' - | '\u17dc' ..'\u1820' - | '\u1821' ..'\u1842' - | '\u1844' ..'\u1877' - | '\u1880' ..'\u18a8' - | '\u18aa' ..'\u18b0' - | '\u18b1' ..'\u18f5' - | '\u1900' ..'\u191e' - | '\u1950' ..'\u196d' - | '\u1970' ..'\u1974' - | '\u1980' ..'\u19ab' - | '\u19c1' ..'\u19c7' - | '\u1a00' ..'\u1a16' - | '\u1a20' ..'\u1a54' - | '\u1b05' ..'\u1b33' - | '\u1b45' ..'\u1b4b' - | '\u1b83' ..'\u1ba0' - | '\u1bae' ..'\u1baf' - | '\u1bba' ..'\u1be5' - | '\u1c00' ..'\u1c23' - | '\u1c4d' ..'\u1c4f' - | '\u1c5a' ..'\u1c77' - | '\u1ce9' ..'\u1cec' - | '\u1cee' ..'\u1cf1' - | '\u1cf5' ..'\u1cf6' - | '\u2135' ..'\u2138' - | '\u2d30' ..'\u2d67' - | '\u2d80' ..'\u2d96' - | '\u2da0' ..'\u2da6' - | '\u2da8' ..'\u2dae' - | '\u2db0' ..'\u2db6' - | '\u2db8' ..'\u2dbe' - | '\u2dc0' ..'\u2dc6' - | '\u2dc8' ..'\u2dce' - | '\u2dd0' ..'\u2dd6' - | '\u2dd8' ..'\u2dde' - | '\u3006' ..'\u303c' - | '\u3041' ..'\u3096' - | '\u309f' ..'\u30a1' - | '\u30a2' ..'\u30fa' - | '\u30ff' ..'\u3105' - | '\u3106' ..'\u312d' - | '\u3131' ..'\u318e' - | '\u31a0' ..'\u31ba' - | '\u31f0' ..'\u31ff' - | '\u3400' ..'\u4db5' - | '\u4e00' ..'\u9fcc' - | '\ua000' ..'\ua014' - | '\ua016' ..'\ua48c' - | '\ua4d0' ..'\ua4f7' - | '\ua500' ..'\ua60b' - | '\ua610' ..'\ua61f' - | '\ua62a' ..'\ua62b' - | '\ua66e' ..'\ua6a0' - | '\ua6a1' ..'\ua6e5' - | '\ua7f7' ..'\ua7fb' - | '\ua7fc' ..'\ua801' - | '\ua803' ..'\ua805' - | '\ua807' ..'\ua80a' - | '\ua80c' ..'\ua822' - | '\ua840' ..'\ua873' - | '\ua882' ..'\ua8b3' - | '\ua8f2' ..'\ua8f7' - | '\ua8fb' ..'\ua90a' - | '\ua90b' ..'\ua925' - | '\ua930' ..'\ua946' - | '\ua960' ..'\ua97c' - | '\ua984' ..'\ua9b2' - | '\ua9e0' ..'\ua9e4' - | '\ua9e7' ..'\ua9ef' - | '\ua9fa' ..'\ua9fe' - | '\uaa00' ..'\uaa28' - | '\uaa40' ..'\uaa42' - | '\uaa44' ..'\uaa4b' - | '\uaa60' ..'\uaa6f' - | '\uaa71' ..'\uaa76' - | '\uaa7a' ..'\uaa7e' - | '\uaa7f' ..'\uaaaf' - | '\uaab1' ..'\uaab5' - | '\uaab6' ..'\uaab9' - | '\uaaba' ..'\uaabd' - | '\uaac0' ..'\uaac2' - | '\uaadb' ..'\uaadc' - | '\uaae0' ..'\uaaea' - | '\uaaf2' ..'\uab01' - | '\uab02' ..'\uab06' - | '\uab09' ..'\uab0e' - | '\uab11' ..'\uab16' - | '\uab20' ..'\uab26' - | '\uab28' ..'\uab2e' - | '\uabc0' ..'\uabe2' - | '\uac00' ..'\ud7a3' - | '\ud7b0' ..'\ud7c6' - | '\ud7cb' ..'\ud7fb' - | '\uf900' ..'\ufa6d' - | '\ufa70' ..'\ufad9' - | '\ufb1d' ..'\ufb1f' - | '\ufb20' ..'\ufb28' - | '\ufb2a' ..'\ufb36' - | '\ufb38' ..'\ufb3c' - | '\ufb3e' ..'\ufb40' - | '\ufb41' ..'\ufb43' - | '\ufb44' ..'\ufb46' - | '\ufb47' ..'\ufbb1' - | '\ufbd3' ..'\ufd3d' - | '\ufd50' ..'\ufd8f' - | '\ufd92' ..'\ufdc7' - | '\ufdf0' ..'\ufdfb' - | '\ufe70' ..'\ufe74' - | '\ufe76' ..'\ufefc' - | '\uff66' ..'\uff6f' - | '\uff71' ..'\uff9d' - | '\uffa0' ..'\uffbe' - | '\uffc2' ..'\uffc7' - | '\uffca' ..'\uffcf' - | '\uffd2' ..'\uffd7' - | '\uffda' ..'\uffdc' -; - -fragment UnicodeClassNL: - '\u16EE' // RUNIC ARLAUG SYMBOL - | '\u16EF' // RUNIC TVIMADUR SYMBOL - | '\u16F0' // RUNIC BELGTHOR SYMBOL - | '\u2160' // ROMAN NUMERAL ONE - | '\u2161' // ROMAN NUMERAL TWO - | '\u2162' // ROMAN NUMERAL THREE - | '\u2163' // ROMAN NUMERAL FOUR - | '\u2164' // ROMAN NUMERAL FIVE - | '\u2165' // ROMAN NUMERAL SIX - | '\u2166' // ROMAN NUMERAL SEVEN - | '\u2167' // ROMAN NUMERAL EIGHT - | '\u2168' // ROMAN NUMERAL NINE - | '\u2169' // ROMAN NUMERAL TEN - | '\u216A' // ROMAN NUMERAL ELEVEN - | '\u216B' // ROMAN NUMERAL TWELVE - | '\u216C' // ROMAN NUMERAL FIFTY - | '\u216D' // ROMAN NUMERAL ONE HUNDRED - | '\u216E' // ROMAN NUMERAL FIVE HUNDRED - | '\u216F' // ROMAN NUMERAL ONE THOUSAND -; - -fragment UnicodeClassMN: - '\u0300' // COMBINING GRAVE ACCENT - | '\u0301' // COMBINING ACUTE ACCENT - | '\u0302' // COMBINING CIRCUMFLEX ACCENT - | '\u0303' // COMBINING TILDE - | '\u0304' // COMBINING MACRON - | '\u0305' // COMBINING OVERLINE - | '\u0306' // COMBINING BREVE - | '\u0307' // COMBINING DOT ABOVE - | '\u0308' // COMBINING DIAERESIS - | '\u0309' // COMBINING HOOK ABOVE - | '\u030A' // COMBINING RING ABOVE - | '\u030B' // COMBINING DOUBLE ACUTE ACCENT - | '\u030C' // COMBINING CARON - | '\u030D' // COMBINING VERTICAL LINE ABOVE - | '\u030E' // COMBINING DOUBLE VERTICAL LINE ABOVE - | '\u030F' // COMBINING DOUBLE GRAVE ACCENT - | '\u0310' // COMBINING CANDRABINDU -; - -fragment UnicodeClassMC: - '\u0903' // DEVANAGARI SIGN VISARGA - | '\u093E' // DEVANAGARI VOWEL SIGN AA - | '\u093F' // DEVANAGARI VOWEL SIGN I - | '\u0940' // DEVANAGARI VOWEL SIGN II - | '\u0949' // DEVANAGARI VOWEL SIGN CANDRA O - | '\u094A' // DEVANAGARI VOWEL SIGN SHORT O - | '\u094B' // DEVANAGARI VOWEL SIGN O - | '\u094C' // DEVANAGARI VOWEL SIGN AU -; - -fragment UnicodeClassCF: - '\u00AD' // SOFT HYPHEN - | '\u0600' // ARABIC NUMBER SIGN - | '\u0601' // ARABIC SIGN SANAH - | '\u0602' // ARABIC FOOTNOTE MARKER - | '\u0603' // ARABIC SIGN SAFHA - | '\u06DD' // ARABIC END OF AYAH -; - -fragment UnicodeClassPC: - '\u005F' // LOW LINE - | '\u203F' // UNDERTIE - | '\u2040' // CHARACTER TIE - | '\u2054' // INVERTED UNDERTIE - | '\uFE33' // PRESENTATION FORM FOR VERTICAL LOW LINE - | '\uFE34' // PRESENTATION FORM FOR VERTICAL WAVY LOW LINE - | '\uFE4D' // DASHED LOW LINE - | '\uFE4E' // CENTRELINE LOW LINE - | '\uFE4F' // WAVY LOW LINE - | '\uFF3F' // FULLWIDTH LOW LINE -; - -fragment UnicodeClassND: - '\u0030' ..'\u0039' - | '\u0660' ..'\u0669' - | '\u06f0' ..'\u06f9' - | '\u07c0' ..'\u07c9' - | '\u0966' ..'\u096f' - | '\u09e6' ..'\u09ef' - | '\u0a66' ..'\u0a6f' - | '\u0ae6' ..'\u0aef' - | '\u0b66' ..'\u0b6f' - | '\u0be6' ..'\u0bef' - | '\u0c66' ..'\u0c6f' - | '\u0ce6' ..'\u0cef' - | '\u0d66' ..'\u0d6f' - | '\u0de6' ..'\u0def' - | '\u0e50' ..'\u0e59' - | '\u0ed0' ..'\u0ed9' - | '\u0f20' ..'\u0f29' - | '\u1040' ..'\u1049' - | '\u1090' ..'\u1099' - | '\u17e0' ..'\u17e9' - | '\u1810' ..'\u1819' - | '\u1946' ..'\u194f' - | '\u19d0' ..'\u19d9' - | '\u1a80' ..'\u1a89' - | '\u1a90' ..'\u1a99' - | '\u1b50' ..'\u1b59' - | '\u1bb0' ..'\u1bb9' - | '\u1c40' ..'\u1c49' - | '\u1c50' ..'\u1c59' - | '\ua620' ..'\ua629' - | '\ua8d0' ..'\ua8d9' - | '\ua900' ..'\ua909' - | '\ua9d0' ..'\ua9d9' - | '\ua9f0' ..'\ua9f9' - | '\uaa50' ..'\uaa59' - | '\uabf0' ..'\uabf9' - | '\uff10' ..'\uff19' -; \ No newline at end of file diff --git a/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpParser.g4 b/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpParser.g4 deleted file mode 100755 index f57ce620d..000000000 --- a/engine/src/main/antlr4/com/ibm/engine/language/csharp/antlr/CSharpParser.g4 +++ /dev/null @@ -1,1315 +0,0 @@ -// EBNF following ECMA 334 Version 7 language specification. -// MIT License. - -// Eclipse Public License - v 1.0, http://www.eclipse.org/legal/epl-v10.html -// Copyright (c) 2013, Christian Wulf (chwchw@gmx.de) -// Copyright (c) 2016-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. - -// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false -// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging - -parser grammar CSharpParser; - -options { - tokenVocab = CSharpLexer; - superClass = CSharpParserBase; -} - -// Insert here @header for parser. - - -// entry point -compilation_unit - : BYTE_ORDER_MARK? extern_alias_directives? using_directives? global_attribute_section* namespace_member_declarations? EOF - ; - -//B.2 Syntactic grammar - -//B.2.1 Basic concepts - -namespace_or_type_name - : (identifier type_argument_list? | qualified_alias_member) ( - '.' identifier type_argument_list? - )* - ; - -//B.2.2 Types -type_ - : base_type ('?' | rank_specifier | '*')* - ; - -base_type - : simple_type - | class_type // represents types: enum, class, interface, delegate, type_parameter - | VOID '*' - | tuple_type - ; - -tuple_type - : '(' tuple_element (',' tuple_element)+ ')' - ; - -tuple_element - : type_ identifier? - ; - -simple_type - : numeric_type - | BOOL - ; - -numeric_type - : integral_type - | floating_point_type - | DECIMAL - ; - -integral_type - : SBYTE - | BYTE - | SHORT - | USHORT - | INT - | UINT - | LONG - | ULONG - | CHAR - ; - -floating_point_type - : FLOAT - | DOUBLE - ; - -/** namespace_or_type_name, OBJECT, STRING */ -class_type - : namespace_or_type_name - | OBJECT - | DYNAMIC - | STRING - ; - -type_argument_list - : '<' type_ (',' type_)* '>' - ; - -//B.2.4 Expressions -argument_list - : argument (',' argument)* - ; - -argument - : (identifier ':')? refout = (REF | OUT | IN)? (expression | (VAR | type_) expression) - ; - -expression - : assignment - | non_assignment_expression - | REF non_assignment_expression - ; - -non_assignment_expression - : lambda_expression - | query_expression - | conditional_expression - ; - -assignment - : unary_expression assignment_operator expression - | unary_expression '??=' throwable_expression - ; - -assignment_operator - : '=' - | '+=' - | '-=' - | '*=' - | '/=' - | '%=' - | '&=' - | '|=' - | '^=' - | '<<=' - | right_shift_assignment - ; - -conditional_expression - : null_coalescing_expression ('?' throwable_expression ':' throwable_expression)? - ; - -null_coalescing_expression - : conditional_or_expression ('??' (null_coalescing_expression | throw_expression))? - ; - -conditional_or_expression - : conditional_and_expression (OP_OR conditional_and_expression)* - ; - -conditional_and_expression - : inclusive_or_expression (OP_AND inclusive_or_expression)* - ; - -inclusive_or_expression - : exclusive_or_expression ('|' exclusive_or_expression)* - ; - -exclusive_or_expression - : and_expression ('^' and_expression)* - ; - -and_expression - : equality_expression ('&' equality_expression)* - ; - -equality_expression - : relational_expression ((OP_EQ | OP_NE) relational_expression)* - ; - -relational_expression - : shift_expression (('<' | '>' | '<=' | '>=') shift_expression | IS pattern | AS type_)* - ; - -shift_expression - : additive_expression (('<<' | right_shift) additive_expression)* - ; - -additive_expression - : multiplicative_expression (('+' | '-') multiplicative_expression)* - ; - -multiplicative_expression - : unary_expression (('*' | '/' | '%') unary_expression)* - ; - -// https://msdn.microsoft.com/library/6a71f45d(v=vs.110).aspx -unary_expression - : cast_expression - | primary_expression - | '+' unary_expression - | '-' unary_expression - | BANG unary_expression - | '~' unary_expression - | '++' unary_expression - | '--' unary_expression - | AWAIT unary_expression // C# 5 - | '&' unary_expression - | '*' unary_expression - | '^' unary_expression // C# 8 ranges - ; - -cast_expression - : OPEN_PARENS type_ CLOSE_PARENS unary_expression - ; - -primary_expression // Null-conditional operators C# 6: https://msdn.microsoft.com/en-us/library/dn986595.aspx - : pe = primary_expression_start '!'? bracket_expression* '!'? ( - (member_access | method_invocation | '++' | '--' | '->' identifier) '!'? bracket_expression* '!'? - )* - ; - -primary_expression_start - : literal # literalExpression - | identifier type_argument_list? # simpleNameExpression - | OPEN_PARENS expression CLOSE_PARENS # parenthesisExpressions - | predefined_type # memberAccessExpression - | qualified_alias_member # memberAccessExpression - | LITERAL_ACCESS # literalAccessExpression - | THIS # thisReferenceExpression - | BASE ('.' identifier type_argument_list? | '[' expression_list ']') # baseAccessExpression - | NEW ( - type_ ( - object_creation_expression - | object_or_collection_initializer - | '[' expression_list ']' rank_specifier* array_initializer? - | rank_specifier+ array_initializer - ) - | anonymous_object_initializer - | rank_specifier array_initializer - ) # objectCreationExpression - | OPEN_PARENS argument ( ',' argument)+ CLOSE_PARENS # tupleExpression - | TYPEOF OPEN_PARENS (unbound_type_name | type_ | VOID) CLOSE_PARENS # typeofExpression - | CHECKED OPEN_PARENS expression CLOSE_PARENS # checkedExpression - | UNCHECKED OPEN_PARENS expression CLOSE_PARENS # uncheckedExpression - | DEFAULT (OPEN_PARENS type_ CLOSE_PARENS)? # defaultValueExpression - | ASYNC? DELEGATE (OPEN_PARENS explicit_anonymous_function_parameter_list? CLOSE_PARENS)? block # anonymousMethodExpression - | SIZEOF OPEN_PARENS type_ CLOSE_PARENS # sizeofExpression - // C# 6: https://msdn.microsoft.com/en-us/library/dn986596.aspx - | NAMEOF OPEN_PARENS (identifier '.')* identifier CLOSE_PARENS # nameofExpression - // C# 7.2: stackalloc in general expression context - | stackalloc_initializer # stackallocExpression - ; - -throwable_expression - : expression - | throw_expression - ; - -throw_expression - : THROW expression - ; - -member_access - : '?'? '.' identifier type_argument_list? - ; - -bracket_expression - : '?'? '[' indexer_argument (',' indexer_argument)* ']' - ; - -indexer_argument - : (identifier ':')? expression - ; - -predefined_type - : BOOL - | BYTE - | CHAR - | DECIMAL - | DOUBLE - | FLOAT - | INT - | LONG - | OBJECT - | SBYTE - | SHORT - | STRING - | UINT - | ULONG - | USHORT - ; - -expression_list - : expression (',' expression)* - ; - -object_or_collection_initializer - : object_initializer - | collection_initializer - ; - -object_initializer - : OPEN_BRACE (member_initializer_list ','?)? CLOSE_BRACE - ; - -member_initializer_list - : member_initializer (',' member_initializer)* - ; - -member_initializer - : (identifier | '[' expression ']') '=' initializer_value // C# 6 - ; - -initializer_value - : expression - | object_or_collection_initializer - ; - -collection_initializer - : OPEN_BRACE element_initializer (',' element_initializer)* ','? CLOSE_BRACE - ; - -element_initializer - : non_assignment_expression - | OPEN_BRACE expression_list CLOSE_BRACE - ; - -anonymous_object_initializer - : OPEN_BRACE (member_declarator_list ','?)? CLOSE_BRACE - ; - -member_declarator_list - : member_declarator (',' member_declarator)* - ; - -member_declarator - : primary_expression - | identifier '=' expression - ; - -unbound_type_name - : identifier (generic_dimension_specifier? | '::' identifier generic_dimension_specifier?) ( - '.' identifier generic_dimension_specifier? - )* - ; - -generic_dimension_specifier - : '<' ','* '>' - ; - -lambda_expression - : ASYNC? anonymous_function_signature right_arrow anonymous_function_body - ; - -anonymous_function_signature - : OPEN_PARENS CLOSE_PARENS - | OPEN_PARENS explicit_anonymous_function_parameter_list CLOSE_PARENS - | OPEN_PARENS implicit_anonymous_function_parameter_list CLOSE_PARENS - | identifier - ; - -explicit_anonymous_function_parameter_list - : explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)* - ; - -explicit_anonymous_function_parameter - : refout = (REF | OUT | IN)? type_ identifier - ; - -implicit_anonymous_function_parameter_list - : identifier (',' identifier)* - ; - -anonymous_function_body - : throwable_expression - | REF non_assignment_expression - | block - ; - -query_expression - : from_clause query_body - ; - -from_clause - : FROM type_? identifier IN expression - ; - -query_body - : query_body_clause* select_or_group_clause query_continuation? - ; - -query_body_clause - : from_clause - | let_clause - | where_clause - | combined_join_clause - | orderby_clause - ; - -let_clause - : LET identifier '=' expression - ; - -where_clause - : WHERE expression - ; - -combined_join_clause - : JOIN type_? identifier IN expression ON expression EQUALS expression (INTO identifier)? - ; - -orderby_clause - : ORDERBY ordering (',' ordering)* - ; - -ordering - : expression dir = (ASCENDING | DESCENDING)? - ; - -select_or_group_clause - : SELECT expression - | GROUP expression BY expression - ; - -query_continuation - : INTO identifier query_body - ; - -//B.2.5 Statements -statement - : labeled_Statement - | declarationStatement - | embedded_statement - ; - -declarationStatement - : local_variable_declaration ';' - | local_constant_declaration ';' - | local_function_declaration - ; - -local_function_declaration - : local_function_header local_function_body - ; - -local_function_header - : local_function_modifiers? return_type identifier type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS - type_parameter_constraints_clauses? - ; - -local_function_modifiers - : (ASYNC | UNSAFE) STATIC? - | STATIC (ASYNC | UNSAFE) - ; - -local_function_body - : block - | right_arrow throwable_expression ';' - ; - -labeled_Statement - : identifier ':' statement - ; - -embedded_statement - : block - | simple_embedded_statement - ; - -simple_embedded_statement - : ';' # theEmptyStatement - | expression ';' # expressionStatement - - // selection statements - | IF OPEN_PARENS expression CLOSE_PARENS if_body (ELSE if_body)? # ifStatement - | SWITCH OPEN_PARENS expression CLOSE_PARENS OPEN_BRACE switch_section* CLOSE_BRACE # switchStatement - - // iteration statements - | WHILE OPEN_PARENS expression CLOSE_PARENS embedded_statement # whileStatement - | DO embedded_statement WHILE OPEN_PARENS expression CLOSE_PARENS ';' # doStatement - | FOR OPEN_PARENS for_initializer? ';' expression? ';' for_iterator? CLOSE_PARENS embedded_statement # forStatement - | FOREACH OPEN_PARENS (REF READONLY? | READONLY REF)? local_variable_type identifier IN expression CLOSE_PARENS embedded_statement # foreachStatement - | FOREACH OPEN_PARENS VAR parenthesized_variable_designation IN expression CLOSE_PARENS embedded_statement # foreachDeconstructStatement - - // jump statements - | BREAK ';' # breakStatement - | CONTINUE ';' # continueStatement - | GOTO (identifier | CASE expression | DEFAULT) ';' # gotoStatement - | RETURN expression? ';' # returnStatement - | THROW expression? ';' # throwStatement - | TRY block (catch_clauses finally_clause? | finally_clause) # tryStatement - | CHECKED block # checkedStatement - | UNCHECKED block # uncheckedStatement - | LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement # lockStatement - | USING OPEN_PARENS resource_acquisition CLOSE_PARENS embedded_statement # usingStatement - | YIELD (RETURN expression | BREAK) ';' # yieldStatement - - // unsafe statements - | UNSAFE block # unsafeStatement - | FIXED OPEN_PARENS pointer_type fixed_pointer_declarators CLOSE_PARENS embedded_statement # fixedStatement - ; - -block - : OPEN_BRACE statement_list? CLOSE_BRACE - ; - -local_variable_declaration - : (USING | REF | REF READONLY)? local_variable_type local_variable_declarator ( - ',' local_variable_declarator {this.IsLocalVariableDeclaration()}? - )* - | FIXED pointer_type fixed_pointer_declarators - ; - -local_variable_type - : VAR - | type_ - ; - -local_variable_declarator - : identifier ('=' REF? local_variable_initializer)? - ; - -local_variable_initializer - : expression - | array_initializer - | stackalloc_initializer - ; - -local_constant_declaration - : CONST type_ constant_declarators - ; - -if_body - : block - | simple_embedded_statement - ; - -switch_section - : switch_label+ statement_list - ; - -switch_label - : CASE pattern case_guard? ':' - | DEFAULT ':' - ; - -case_guard - : WHEN expression - ; - -// C# 7.0: pattern matching (ECMA-334 §11.20.4) -pattern - : VAR variable_designation // var_pattern - | type_ simple_designation // declaration_pattern - | type_ // type_pattern (old-style 'is Type' without name, e.g. 'is byte[]') - | expression // constant_pattern - ; - -variable_designation - : simple_designation - | parenthesized_variable_designation - ; - -parenthesized_variable_designation - : OPEN_PARENS variable_designation (',' variable_designation)+ CLOSE_PARENS - ; - -simple_designation - : identifier - ; - -statement_list - : statement+ - ; - -for_initializer - : local_variable_declaration - | expression (',' expression)* - ; - -for_iterator - : expression (',' expression)* - ; - -catch_clauses - : specific_catch_clause specific_catch_clause* general_catch_clause? - | general_catch_clause - ; - -specific_catch_clause - : CATCH OPEN_PARENS class_type identifier? CLOSE_PARENS exception_filter? block - ; - -general_catch_clause - : CATCH exception_filter? block - ; - -exception_filter // C# 6 - : WHEN OPEN_PARENS expression CLOSE_PARENS - ; - -finally_clause - : FINALLY block - ; - -resource_acquisition - : local_variable_declaration - | expression - ; - -//B.2.6 Namespaces; -namespace_declaration - : NAMESPACE qi = qualified_identifier namespace_body ';'? - ; - -qualified_identifier - : identifier ('.' identifier)* - ; - -namespace_body - : OPEN_BRACE extern_alias_directives? using_directives? namespace_member_declarations? CLOSE_BRACE - ; - -extern_alias_directives - : extern_alias_directive+ - ; - -extern_alias_directive - : EXTERN ALIAS identifier ';' - ; - -using_directives - : using_directive+ - ; - -using_directive - : USING identifier '=' namespace_or_type_name ';' # usingAliasDirective - | USING namespace_or_type_name ';' # usingNamespaceDirective - // C# 6: https://msdn.microsoft.com/en-us/library/ms228593.aspx - | USING STATIC namespace_or_type_name ';' # usingStaticDirective - ; - -namespace_member_declarations - : namespace_member_declaration+ - ; - -namespace_member_declaration - : namespace_declaration - | type_declaration - ; - -type_declaration - : attributes? all_member_modifiers? ( - class_definition - | struct_definition - | interface_definition - | enum_definition - | delegate_definition - ) - ; - -qualified_alias_member - : identifier '::' identifier type_argument_list? - ; - -//B.2.7 Classes; -type_parameter_list - : '<' type_parameter (',' type_parameter)* '>' - ; - -type_parameter - : attributes? identifier - ; - -class_base - : ':' class_type (',' namespace_or_type_name)* - ; - -interface_type_list - : namespace_or_type_name (',' namespace_or_type_name)* - ; - -type_parameter_constraints_clauses - : type_parameter_constraints_clause+ - ; - -type_parameter_constraints_clause - : WHERE identifier ':' type_parameter_constraints - ; - -type_parameter_constraints - : constructor_constraint - | primary_constraint (',' secondary_constraints)? (',' constructor_constraint)? - ; - -primary_constraint - : class_type - | CLASS '?'? - | STRUCT - | UNMANAGED - ; - -// namespace_or_type_name includes identifier -secondary_constraints - : namespace_or_type_name (',' namespace_or_type_name)* - ; - -constructor_constraint - : NEW OPEN_PARENS CLOSE_PARENS - ; - -class_body - : OPEN_BRACE class_member_declarations? CLOSE_BRACE - ; - -class_member_declarations - : class_member_declaration+ - ; - -class_member_declaration - : attributes? all_member_modifiers? (common_member_declaration | destructor_definition) - ; - -all_member_modifiers - : all_member_modifier+ - ; - -all_member_modifier - : NEW - | PUBLIC - | PROTECTED - | INTERNAL - | PRIVATE - | READONLY - | VOLATILE - | VIRTUAL - | SEALED - | OVERRIDE - | ABSTRACT - | STATIC - | UNSAFE - | EXTERN - | PARTIAL - | ASYNC // C# 5 - ; - -// represents the intersection of struct_member_declaration and class_member_declaration -common_member_declaration - : constant_declaration - | typed_member_declaration - | event_declaration - | conversion_operator_declarator (body | right_arrow throwable_expression ';') // C# 6 - | constructor_declaration - | VOID method_declaration - | class_definition - | struct_definition - | interface_definition - | enum_definition - | delegate_definition - ; - -typed_member_declaration - : (REF | READONLY REF | REF READONLY)? type_ ( - namespace_or_type_name '.' indexer_declaration - | method_declaration - | property_declaration - | indexer_declaration - | operator_declaration - | field_declaration - ) - ; - -constant_declarators - : constant_declarator (',' constant_declarator)* - ; - -constant_declarator - : identifier '=' expression - ; - -variable_declarators - : variable_declarator (',' variable_declarator)* - ; - -variable_declarator - : identifier ('=' variable_initializer)? - ; - -variable_initializer - : expression - | array_initializer - ; - -return_type - : type_ - | VOID - ; - -member_name - : namespace_or_type_name - ; - -method_body - : block - | ';' - ; - -formal_parameter_list - : parameter_array - | fixed_parameters (',' parameter_array)? - ; - -fixed_parameters - : fixed_parameter (',' fixed_parameter)* - ; - -fixed_parameter - : attributes? parameter_modifier? arg_declaration - | ARGLIST - ; - -parameter_modifier - : REF - | OUT - | IN - | REF THIS - | IN THIS - | THIS - ; - -parameter_array - : attributes? PARAMS array_type identifier - ; - -accessor_declarations - : attrs = attributes? mods = accessor_modifier? ( - GET accessor_body set_accessor_declaration? - | SET accessor_body get_accessor_declaration? - ) - ; - -get_accessor_declaration - : attributes? accessor_modifier? GET accessor_body - ; - -set_accessor_declaration - : attributes? accessor_modifier? SET accessor_body - ; - -accessor_modifier - : PROTECTED - | INTERNAL - | PRIVATE - | PROTECTED INTERNAL - | INTERNAL PROTECTED - | PRIVATE PROTECTED - | PROTECTED PRIVATE - ; - -accessor_body - : block - | right_arrow throwable_expression ';' - | ';' - ; - -event_accessor_declarations - : attributes? (ADD block remove_accessor_declaration | REMOVE block add_accessor_declaration) - ; - -add_accessor_declaration - : attributes? ADD block - ; - -remove_accessor_declaration - : attributes? REMOVE block - ; - -overloadable_operator - : '+' - | '-' - | BANG - | '~' - | '++' - | '--' - | TRUE - | FALSE - | '*' - | '/' - | '%' - | '&' - | '|' - | '^' - | '<<' - | right_shift - | OP_EQ - | OP_NE - | '>' - | '<' - | '>=' - | '<=' - ; - -conversion_operator_declarator - : (IMPLICIT | EXPLICIT) OPERATOR type_ OPEN_PARENS arg_declaration CLOSE_PARENS - ; - -constructor_initializer - : ':' (BASE | THIS) OPEN_PARENS argument_list? CLOSE_PARENS - ; - -body - : block - | right_arrow throwable_expression ';' - | ';' - ; - -//B.2.8 Structs -struct_interfaces - : ':' interface_type_list - ; - -struct_body - : OPEN_BRACE struct_member_declaration* CLOSE_BRACE - ; - -struct_member_declaration - : attributes? all_member_modifiers? ( - common_member_declaration - | FIXED type_ fixed_size_buffer_declarator+ ';' - ) - ; - -//B.2.9 Arrays -array_type - : base_type (('*' | '?')* rank_specifier)+ - ; - -rank_specifier - : '[' ','* ']' - ; - -array_initializer - : OPEN_BRACE (variable_initializer (',' variable_initializer)* ','?)? CLOSE_BRACE - ; - -//B.2.10 Interfaces -variant_type_parameter_list - : '<' variant_type_parameter (',' variant_type_parameter)* '>' - ; - -variant_type_parameter - : attributes? variance_annotation? identifier - ; - -variance_annotation - : IN - | OUT - ; - -interface_base - : ':' interface_type_list - ; - -interface_body // ignored in csharp 8 - : OPEN_BRACE interface_member_declaration* CLOSE_BRACE - ; - -interface_member_declaration - : attributes? NEW? ( - UNSAFE? (REF | REF READONLY | READONLY REF)? type_ ( - identifier type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ';' - | identifier OPEN_BRACE interface_accessors CLOSE_BRACE - | THIS '[' formal_parameter_list ']' OPEN_BRACE interface_accessors CLOSE_BRACE - ) - | UNSAFE? VOID identifier type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ';' - | EVENT type_ identifier ';' - ) - ; - -interface_accessors - : attributes? (GET ';' (attributes? SET ';')? | SET ';' (attributes? GET ';')?) - ; - -//B.2.11 Enums -enum_base - : ':' type_ - ; - -enum_body - : OPEN_BRACE (enum_member_declaration (',' enum_member_declaration)* ','?)? CLOSE_BRACE - ; - -enum_member_declaration - : attributes? identifier ('=' expression)? - ; - -//B.2.12 Delegates - -//B.2.13 Attributes -global_attribute_section - : '[' global_attribute_target ':' attribute_list ','? ']' - ; - -global_attribute_target - : keyword - | identifier - ; - -attributes - : attribute_section+ - ; - -attribute_section - : '[' (attribute_target ':')? attribute_list ','? ']' - ; - -attribute_target - : keyword - | identifier - ; - -attribute_list - : attribute (',' attribute)* - ; - -attribute - : namespace_or_type_name ( - OPEN_PARENS (attribute_argument (',' attribute_argument)*)? CLOSE_PARENS - )? - ; - -attribute_argument - : (identifier ':')? expression - ; - -//B.3 Grammar extensions for unsafe code -pointer_type - : (simple_type | class_type) (rank_specifier | '?')* '*' - | VOID '*' - ; - -fixed_pointer_declarators - : fixed_pointer_declarator (',' fixed_pointer_declarator)* - ; - -fixed_pointer_declarator - : identifier '=' fixed_pointer_initializer - ; - -fixed_pointer_initializer - : '&'? expression - | stackalloc_initializer - ; - -fixed_size_buffer_declarator - : identifier '[' expression ']' - ; - -stackalloc_initializer - : STACKALLOC type_ '[' expression ']' - | STACKALLOC type_? '[' expression? ']' OPEN_BRACE (expression (',' expression)* ','?)? CLOSE_BRACE - ; - -right_arrow - : '=' '>' {this.IsRightArrow()}? // Nothing between the tokens? - ; - -right_shift - : '>' '>' {this.IsRightShift()}? // Nothing between the tokens? - ; - -right_shift_assignment - : '>' '>=' {this.IsRightShiftAssignment()}? // Nothing between the tokens? - ; - -literal - : boolean_literal - | string_literal - | INTEGER_LITERAL - | HEX_INTEGER_LITERAL - | BIN_INTEGER_LITERAL - | REAL_LITERAL - | CHARACTER_LITERAL - | NULL_ - ; - -boolean_literal - : TRUE - | FALSE - ; - -string_literal - : interpolated_regular_string - | interpolated_verbatium_string - | REGULAR_STRING - | VERBATIUM_STRING - ; - -interpolated_regular_string - : INTERPOLATED_REGULAR_STRING_START interpolated_regular_string_part* DOUBLE_QUOTE_INSIDE - ; - -interpolated_verbatium_string - : INTERPOLATED_VERBATIUM_STRING_START interpolated_verbatium_string_part* DOUBLE_QUOTE_INSIDE - ; - -interpolated_regular_string_part - : interpolated_string_expression - | DOUBLE_CURLY_INSIDE - | REGULAR_CHAR_INSIDE - | REGULAR_STRING_INSIDE - ; - -interpolated_verbatium_string_part - : interpolated_string_expression - | DOUBLE_CURLY_INSIDE - | VERBATIUM_DOUBLE_QUOTE_INSIDE - | VERBATIUM_INSIDE_STRING - ; - -interpolated_string_expression - : expression (',' expression)* (':' FORMAT_STRING+)? - ; - -//B.1.7 Keywords -keyword - : ABSTRACT - | AS - | BASE - | BOOL - | BREAK - | BYTE - | CASE - | CATCH - | CHAR - | CHECKED - | CLASS - | CONST - | CONTINUE - | DECIMAL - | DEFAULT - | DELEGATE - | DO - | DOUBLE - | ELSE - | ENUM - | EVENT - | EXPLICIT - | EXTERN - | FALSE - | FINALLY - | FIXED - | FLOAT - | FOR - | FOREACH - | GOTO - | IF - | IMPLICIT - | IN - | INT - | INTERFACE - | INTERNAL - | IS - | LOCK - | LONG - | NAMESPACE - | NEW - | NULL_ - | OBJECT - | OPERATOR - | OUT - | OVERRIDE - | PARAMS - | PRIVATE - | PROTECTED - | PUBLIC - | READONLY - | REF - | RETURN - | SBYTE - | SEALED - | SHORT - | SIZEOF - | STACKALLOC - | STATIC - | STRING - | STRUCT - | SWITCH - | THIS - | THROW - | TRUE - | TRY - | TYPEOF - | UINT - | ULONG - | UNCHECKED - | UNMANAGED - | UNSAFE - | USHORT - | USING - | VIRTUAL - | VOID - | VOLATILE - | WHILE - ; - -// -------------------- extra rules for modularization -------------------------------- - -class_definition - : CLASS identifier type_parameter_list? class_base? type_parameter_constraints_clauses? class_body ';'? - ; - -struct_definition - : (READONLY | REF)? STRUCT identifier type_parameter_list? struct_interfaces? type_parameter_constraints_clauses? struct_body ';'? - ; - -interface_definition - : INTERFACE identifier variant_type_parameter_list? interface_base? type_parameter_constraints_clauses? class_body ';'? - ; - -enum_definition - : ENUM identifier enum_base? enum_body ';'? - ; - -delegate_definition - : DELEGATE return_type identifier variant_type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? - ';' - ; - -event_declaration - : EVENT type_ ( - variable_declarators ';' - | member_name OPEN_BRACE event_accessor_declarations CLOSE_BRACE - ) - ; - -field_declaration - : variable_declarators ';' - ; - -property_declaration // Property initializer & lambda in properties C# 6 - : member_name ( - OPEN_BRACE accessor_declarations CLOSE_BRACE ('=' variable_initializer ';')? - | right_arrow throwable_expression ';' - ) - ; - -constant_declaration - : CONST type_ constant_declarators ';' - ; - -indexer_declaration // lamdas from C# 6 - : THIS '[' formal_parameter_list ']' ( - OPEN_BRACE accessor_declarations CLOSE_BRACE - | right_arrow throwable_expression ';' - ) - ; - -destructor_definition - : '~' identifier OPEN_PARENS CLOSE_PARENS body - ; - -constructor_declaration - : identifier OPEN_PARENS formal_parameter_list? CLOSE_PARENS constructor_initializer? body - ; - -method_declaration // lamdas from C# 6 - : method_member_name type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ( - method_body - | right_arrow throwable_expression ';' - ) - ; - -method_member_name - : (identifier | identifier '::' identifier) (type_argument_list? '.' identifier)* - ; - -operator_declaration // lamdas form C# 6 - : OPERATOR overloadable_operator OPEN_PARENS IN? arg_declaration (',' IN? arg_declaration)? CLOSE_PARENS ( - body - | right_arrow throwable_expression ';' - ) - ; - -arg_declaration - : type_ identifier ('=' expression)? - ; - -method_invocation - : OPEN_PARENS argument_list? CLOSE_PARENS - ; - -object_creation_expression - : OPEN_PARENS argument_list? CLOSE_PARENS object_or_collection_initializer? - ; - -identifier - : IDENTIFIER - | ADD - | ALIAS - | ARGLIST - | ASCENDING - | ASYNC - | AWAIT - | BY - | DESCENDING - | DYNAMIC - | EQUALS - | FROM - | GET - | GROUP - | INTO - | JOIN - | LET - | NAMEOF - | ON - | ORDERBY - | PARTIAL - | REMOVE - | SELECT - | SET - | UNMANAGED - | VAR - | WHEN - | WHERE - | YIELD - ; \ No newline at end of file diff --git a/engine/src/main/java/com/ibm/engine/language/LanguageSupporter.java b/engine/src/main/java/com/ibm/engine/language/LanguageSupporter.java index c5a82a55a..db35a5ed7 100644 --- a/engine/src/main/java/com/ibm/engine/language/LanguageSupporter.java +++ b/engine/src/main/java/com/ibm/engine/language/LanguageSupporter.java @@ -19,11 +19,6 @@ */ package com.ibm.engine.language; -import com.ibm.engine.language.csharp.CSharpCheck; -import com.ibm.engine.language.csharp.CSharpLanguageSupport; -import com.ibm.engine.language.csharp.CSharpScanContext; -import com.ibm.engine.language.csharp.CSharpSymbol; -import com.ibm.engine.language.csharp.tree.CSharpTree; import com.ibm.engine.language.go.GoLanguageSupport; import com.ibm.engine.language.go.GoScanContext; import com.ibm.engine.language.java.JavaLanguageSupport; @@ -67,10 +62,4 @@ private LanguageSupporter() { public static ILanguageSupport goLanguageSupporter() { return new GoLanguageSupport(); } - - @Nonnull - public static ILanguageSupport - csharpLanguageSupporter() { - return new CSharpLanguageSupport(); - } } diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpBaseMethodVisitor.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpBaseMethodVisitor.java deleted file mode 100755 index 791fe89f4..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpBaseMethodVisitor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.detection.IBaseMethodVisitor; -import com.ibm.engine.detection.IDetectionEngine; -import com.ibm.engine.detection.TraceSymbol; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import javax.annotation.Nonnull; - -/** - * Base method visitor for C# that invokes the detection engine on each method body. - * - *

Mirrors {@code GoBaseMethodVisitor}: when the sensor dispatches a method body (a {@link - * CSharpBlockTree}) via {@link #visitMethodDefinition}, the detection engine is run on it. - */ -public final class CSharpBaseMethodVisitor implements IBaseMethodVisitor { - - @Nonnull private final TraceSymbol traceSymbol; - @Nonnull private final IDetectionEngine detectionEngine; - - public CSharpBaseMethodVisitor( - @Nonnull TraceSymbol traceSymbol, - @Nonnull IDetectionEngine detectionEngine) { - this.traceSymbol = traceSymbol; - this.detectionEngine = detectionEngine; - } - - @Override - public void visitMethodDefinition(@Nonnull CSharpTree method) { - if (method instanceof CSharpBlockTree blockTree) { - detectionEngine.run(traceSymbol, blockTree); - } - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpCheck.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpCheck.java deleted file mode 100755 index 15809ee48..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpCheck.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import javax.annotation.Nonnull; - -/** - * Marker interface for C# cryptography detection checks. - * - *

Since sonar-csharp exposes no custom rule registration API (unlike Java's CheckRegistrar or - * Python's PythonCustomRuleRepository), {@link CryptoCSharpSensor} calls {@link #scan} directly for - * every method body it encounters during ANTLR4-based parsing. - */ -public interface CSharpCheck { - - /** - * Invoked once per method body found in a C# source file. - * - * @param scanContext the current scan context (input file, sensor context, repository key) - * @param blockTree the method body to analyse - */ - void scan(@Nonnull CSharpScanContext scanContext, @Nonnull CSharpBlockTree blockTree); -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpDetectionEngine.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpDetectionEngine.java deleted file mode 100755 index c2743b432..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpDetectionEngine.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.detection.Handler; -import com.ibm.engine.detection.IDetectionEngine; -import com.ibm.engine.detection.MethodDetection; -import com.ibm.engine.detection.ResolvedValue; -import com.ibm.engine.detection.TraceSymbol; -import com.ibm.engine.detection.ValueDetection; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import com.ibm.engine.language.csharp.tree.CSharpIdentifierTree; -import com.ibm.engine.language.csharp.tree.CSharpLiteralTree; -import com.ibm.engine.language.csharp.tree.CSharpMemberAccessTree; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.model.factory.IValueFactory; -import com.ibm.engine.rule.DetectableParameter; -import com.ibm.engine.rule.DetectionRule; -import com.ibm.engine.rule.MethodDetectionRule; -import com.ibm.engine.rule.Parameter; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * Detection engine implementation for C#. - * - *

Walks a {@link CSharpBlockTree} looking for {@link CSharpMethodInvocationTree} and {@link - * CSharpObjectCreationTree} nodes that match the active detection rule, then emits detections and - * resolves argument values. - * - *

Symbol resolution is intentionally minimal: ANTLR4 provides no semantic type inference, so - * only literal values ({@link CSharpLiteralTree}), enum-style member accesses ({@link - * CSharpMemberAccessTree}), and direct identifiers ({@link CSharpIdentifierTree}) are resolved. - * - *

Variable tracking — property setters: Property assignments on a detected variable (e.g. - * {@code aes.Mode = CipherMode.CBC}) are supported via synthetic method invocations emitted by - * {@link CSharpTreeConverter}. Each assignment {@code obj.Prop = val} is converted to a synthetic - * {@code CSharpMethodInvocationTree} with method name {@code set_Prop} and {@code val} as the - * argument. The detection engine's {@code isInvocationOnVariable} then matches these synthetic - * nodes against the tracked variable, and {@code withDependingDetectionRules} chains fire the - * appropriate detection rule. - * - *

Only single-level property assignments on simple local variables are tracked (e.g. {@code - * aes.Mode = ...}). Chained access ({@code aes.Inner.Mode = ...}) and method calls ({@code - * aes.GenerateKey()}) on the variable are not linked to the creation finding. - */ -@SuppressWarnings("java:S3776") -public final class CSharpDetectionEngine implements IDetectionEngine { - - @Nonnull - private final DetectionStore - detectionStore; - - @Nonnull - private final Handler handler; - - public CSharpDetectionEngine( - @Nonnull - DetectionStore - detectionStore, - @Nonnull Handler handler) { - this.detectionStore = detectionStore; - this.handler = handler; - } - - @Override - public void run(@Nonnull CSharpTree tree) { - run(TraceSymbol.createStart(), tree); - } - - @Override - public void run(@Nonnull TraceSymbol traceSymbol, @Nonnull CSharpTree tree) { - if (tree instanceof CSharpBlockTree blockTree) { - for (CSharpTree statement : blockTree.getStatements()) { - processStatement(traceSymbol, statement); - } - } else if (tree instanceof CSharpMethodInvocationTree invocation) { - if (traceSymbol.is(TraceSymbol.State.SYMBOL) - && !isInvocationOnVariable(invocation, traceSymbol)) { - return; - } - handler.addCallToCallStack(invocation, detectionStore.getScanContext()); - if (detectionStore - .getDetectionRule() - .match(invocation, handler.getLanguageSupport().translation())) { - analyseMethodInvocation(invocation); - } - } else if (tree instanceof CSharpObjectCreationTree creation) { - if (traceSymbol.is(TraceSymbol.State.SYMBOL) - && !isInitForVariable(creation, traceSymbol)) { - return; - } - handler.addCallToCallStack(creation, detectionStore.getScanContext()); - if (detectionStore - .getDetectionRule() - .match(creation, handler.getLanguageSupport().translation())) { - analyseObjectCreation(creation); - } - } - } - - /** - * Dispatches a single statement within a block for detection. - * - *

When {@code traceSymbol} has state {@link TraceSymbol.State#SYMBOL} (i.e. we are scanning - * for depending rules on a tracked variable), only statements that are invocations on that - * variable are processed. - */ - private void processStatement( - @Nonnull TraceSymbol traceSymbol, @Nonnull CSharpTree statement) { - if (statement instanceof CSharpMethodInvocationTree invocation) { - if (traceSymbol.is(TraceSymbol.State.SYMBOL) - && !isInvocationOnVariable(invocation, traceSymbol)) { - return; - } - handler.addCallToCallStack(invocation, detectionStore.getScanContext()); - if (detectionStore - .getDetectionRule() - .match(invocation, handler.getLanguageSupport().translation())) { - analyseMethodInvocation(invocation); - } - } else if (statement instanceof CSharpObjectCreationTree creation) { - if (traceSymbol.is(TraceSymbol.State.SYMBOL) - && !isInitForVariable(creation, traceSymbol)) { - return; - } - handler.addCallToCallStack(creation, detectionStore.getScanContext()); - if (detectionStore - .getDetectionRule() - .match(creation, handler.getLanguageSupport().translation())) { - analyseObjectCreation(creation); - } - } - } - - // ------------------------------------------------------------------------- - // Invocation / creation analysis - // ------------------------------------------------------------------------- - - private void analyseMethodInvocation(@Nonnull CSharpMethodInvocationTree invocation) { - DetectionRule rule = emitDetectionAndGetRule(invocation); - if (rule == null) { - return; - } - List arguments = invocation.getArguments(); - processParameters(rule.parameters(), arguments, invocation); - } - - private void analyseObjectCreation(@Nonnull CSharpObjectCreationTree creation) { - DetectionRule rule = emitDetectionAndGetRule(creation); - if (rule == null) { - return; - } - List arguments = creation.getArguments(); - processParameters(rule.parameters(), arguments, creation); - } - - /** - * Emits the initial method detection and returns the detection rule for parameter processing. - * Returns {@code null} for {@link MethodDetectionRule} (already fully handled). - */ - @SuppressWarnings("unchecked") - @Nullable private DetectionRule emitDetectionAndGetRule(@Nonnull CSharpTree tree) { - if (detectionStore.getDetectionRule().is(MethodDetectionRule.class)) { - detectionStore.onReceivingNewDetection(new MethodDetection<>(tree, null)); - return null; - } - DetectionRule detectionRule = - (DetectionRule) detectionStore.getDetectionRule(); - if (detectionRule.actionFactory() != null) { - detectionStore.onReceivingNewDetection(new MethodDetection<>(tree, null)); - } - return detectionRule; - } - - /** Processes positional parameters against the provided argument list. */ - private void processParameters( - @Nonnull List> parameters, - @Nonnull List arguments, - @Nonnull CSharpTree parentTree) { - int index = 0; - for (Parameter parameter : parameters) { - if (index >= arguments.size()) { - break; - } - processParameter(parameter, arguments.get(index), parentTree); - index++; - } - } - - @SuppressWarnings("unchecked") - private void processParameter( - @Nonnull Parameter parameter, - @Nonnull CSharpTree expression, - @Nonnull CSharpTree parentTree) { - if (parameter.is(DetectableParameter.class)) { - DetectableParameter detectable = - (DetectableParameter) parameter; - List> resolved = - resolveValuesInInnerScope( - Object.class, expression, detectable.getiValueFactory()); - if (resolved.isEmpty()) { - resolveValuesInOuterScope(expression, detectable); - } else { - resolved.stream() - .map(rv -> new ValueDetection<>(rv, detectable, parentTree, parentTree)) - .forEach(detectionStore::onReceivingNewDetection); - } - } else if (!parameter.getDetectionRules().isEmpty()) { - dispatchDependingParameter(parameter, expression); - } - } - - private void dispatchDependingParameter( - @Nonnull Parameter parameter, @Nonnull CSharpTree expression) { - if (expression instanceof CSharpMethodInvocationTree invocation) { - detectionStore.onDetectedDependingParameter( - parameter, invocation, DetectionStore.Scope.EXPRESSION); - } else if (expression instanceof CSharpObjectCreationTree creation) { - detectionStore.onDetectedDependingParameter( - parameter, creation, DetectionStore.Scope.EXPRESSION); - } else { - detectionStore.onDetectedDependingParameter( - parameter, expression, DetectionStore.Scope.EXPRESSION); - } - } - - // ------------------------------------------------------------------------- - // Value resolution - // ------------------------------------------------------------------------- - - @Nonnull - @Override - public List> resolveValuesInInnerScope( - @Nonnull Class clazz, - @Nonnull CSharpTree expression, - @Nullable IValueFactory valueFactory) { - return resolveValues(clazz, expression, new LinkedList<>()); - } - - @Nonnull - @SuppressWarnings({"unchecked"}) - private List> resolveValues( - @Nonnull Class clazz, - @Nonnull CSharpTree tree, - @Nonnull LinkedList selections) { - if (selections.size() > 15) { - return Collections.emptyList(); - } - - // Literal: string or numeric constant - if (tree instanceof CSharpLiteralTree literal) { - String value = literal.getValue(); - Optional resolved = resolveConstant(clazz, value); - return resolved.map(v -> List.of(new ResolvedValue<>(v, tree))) - .orElse(Collections.emptyList()); - } - - // Member access: e.g. HashAlgorithmName.SHA256 → "SHA256" - if (tree instanceof CSharpMemberAccessTree memberAccess) { - selections.addFirst(memberAccess); - String memberName = memberAccess.getMemberName(); - Optional resolved = resolveConstant(clazz, memberName); - if (resolved.isPresent()) { - return List.of(new ResolvedValue<>(resolved.get(), tree)); - } - return Collections.emptyList(); - } - - // Identifier: resolve to its name as a string - if (tree instanceof CSharpIdentifierTree identifier) { - Optional resolved = resolveConstant(clazz, identifier.getName()); - return resolved.map(v -> List.of(new ResolvedValue<>(v, tree))) - .orElse(Collections.emptyList()); - } - - return Collections.emptyList(); - } - - @Nonnull - @SuppressWarnings("unchecked") - private Optional resolveConstant(@Nonnull Class clazz, @Nullable String value) { - if (value == null) { - return Optional.empty(); - } - try { - if (clazz == String.class) { - return Optional.of(clazz.cast(value)); - } - if (clazz == Integer.class || clazz == Object.class) { - try { - Integer intValue = Integer.parseInt(value); - if (clazz == Integer.class) { - return Optional.of(clazz.cast(intValue)); - } - return Optional.of((O) intValue); - } catch (NumberFormatException e) { - // not a number - } - } - if (clazz == Object.class) { - return Optional.of((O) value); - } - return Optional.empty(); - } catch (ClassCastException e) { - return Optional.empty(); - } - } - - @Override - public void resolveValuesInOuterScope( - @Nonnull CSharpTree expression, @Nonnull Parameter parameter) { - // Cross-scope resolution not supported without semantic analysis - } - - @Override - public void resolveMethodReturnValues( - @Nonnull Class clazz, - @Nonnull CSharpTree methodDefinition, - @Nonnull Parameter parameter) { - // Return value resolution not supported without type inference - } - - @Nullable @Override - public ResolvedValue resolveEnumValue( - @Nonnull Class clazz, - @Nonnull CSharpTree enumClassDefinition, - @Nonnull LinkedList selections) { - // Enum class definition lookup not supported - return null; - } - - // ------------------------------------------------------------------------- - // Symbol tracking (minimal — ANTLR4 has no symbol table) - // ------------------------------------------------------------------------- - - @Nonnull - @Override - public Optional> getAssignedSymbol(@Nonnull CSharpTree expression) { - if (expression instanceof CSharpMethodInvocationTree invocation) { - String assigned = invocation.getAssignedIdentifier(); - if (assigned != null) { - return Optional.of(TraceSymbol.createFrom(new CSharpSymbol(assigned))); - } - } else if (expression instanceof CSharpObjectCreationTree creation) { - String assigned = creation.getAssignedIdentifier(); - if (assigned != null) { - return Optional.of(TraceSymbol.createFrom(new CSharpSymbol(assigned))); - } - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional> getMethodInvocationParameterSymbol( - @Nonnull CSharpTree methodInvocation, @Nonnull Parameter parameter) { - if (methodInvocation instanceof CSharpMethodInvocationTree invocation) { - List args = invocation.getArguments(); - int idx = parameter.getIndex(); - if (idx >= 0 && idx < args.size()) { - return Optional.of(TraceSymbol.createWithStateNoSymbol()); - } - return Optional.of(TraceSymbol.createWithStateDifferent()); - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional> getNewClassParameterSymbol( - @Nonnull CSharpTree newClass, @Nonnull Parameter parameter) { - if (newClass instanceof CSharpObjectCreationTree creation) { - List args = creation.getArguments(); - int idx = parameter.getIndex(); - if (idx >= 0 && idx < args.size()) { - return Optional.of(TraceSymbol.createWithStateNoSymbol()); - } - return Optional.of(TraceSymbol.createWithStateDifferent()); - } - return Optional.empty(); - } - - @Override - public boolean isInvocationOnVariable( - CSharpTree methodInvocation, @Nonnull TraceSymbol variableSymbol) { - if (!(methodInvocation instanceof CSharpMethodInvocationTree invocation)) { - return false; - } - CSharpSymbol sym = variableSymbol.getSymbol(); - if (sym == null) { - return false; - } - // The objectTypeName holds the receiver — matches when it equals the variable name - // (e.g. "aes" in aes.Encrypt(...) matches TraceSymbol("aes")) - return invocation.getObjectTypeName().equals(sym.getName()); - } - - @Override - public boolean isInitForVariable( - CSharpTree newClass, @Nonnull TraceSymbol variableSymbol) { - String assignedId = null; - if (newClass instanceof CSharpMethodInvocationTree invocation) { - assignedId = invocation.getAssignedIdentifier(); - } else if (newClass instanceof CSharpObjectCreationTree creation) { - assignedId = creation.getAssignedIdentifier(); - } - if (assignedId == null) { - return false; - } - CSharpSymbol sym = variableSymbol.getSymbol(); - if (sym == null) { - return false; - } - return assignedId.equals(sym.getName()); - } - - @Nullable @Override - public CSharpTree extractArgumentFromMethodCaller( - @Nonnull CSharpTree methodDefinition, - @Nonnull CSharpTree methodInvocation, - @Nonnull CSharpTree methodParameterIdentifier) { - // Inter-procedural argument mapping not supported - return null; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageSupport.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageSupport.java deleted file mode 100755 index 8d17b743b..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageSupport.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.detection.DetectionStore; -import com.ibm.engine.detection.EnumMatcher; -import com.ibm.engine.detection.Handler; -import com.ibm.engine.detection.IBaseMethodVisitorFactory; -import com.ibm.engine.detection.IDetectionEngine; -import com.ibm.engine.detection.MatchContext; -import com.ibm.engine.detection.MethodMatcher; -import com.ibm.engine.executive.DetectionExecutive; -import com.ibm.engine.language.ILanguageSupport; -import com.ibm.engine.language.ILanguageTranslation; -import com.ibm.engine.language.IScanContext; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import com.ibm.engine.rule.IDetectionRule; -import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * Language support implementation for C#. - * - *

Mirrors {@code GoLanguageSupport}: wires together the {@link CSharpLanguageTranslation}, - * {@link CSharpDetectionEngine}, and {@link CSharpBaseMethodVisitor} using the shared {@link - * Handler} and {@link DetectionExecutive} infrastructure. - */ -public final class CSharpLanguageSupport - implements ILanguageSupport { - - @Nonnull - private final Handler handler; - - @Nonnull private final CSharpLanguageTranslation translation; - - public CSharpLanguageSupport() { - this.handler = new Handler<>(this); - this.translation = new CSharpLanguageTranslation(); - } - - @Nonnull - @Override - public ILanguageTranslation translation() { - return translation; - } - - @Nonnull - @Override - public DetectionExecutive - createDetectionExecutive( - @Nonnull CSharpTree tree, - @Nonnull IDetectionRule detectionRule, - @Nonnull IScanContext scanContext) { - return new DetectionExecutive<>(tree, detectionRule, scanContext, this.handler); - } - - @Nonnull - @Override - public IDetectionEngine createDetectionEngineInstance( - @Nonnull - DetectionStore - detectionStore) { - return new CSharpDetectionEngine(detectionStore, this.handler); - } - - @Nonnull - @Override - public IBaseMethodVisitorFactory getBaseMethodVisitorFactory() { - return CSharpBaseMethodVisitor::new; - } - - @Nonnull - @Override - public Optional getEnclosingMethod(@Nonnull CSharpTree expression) { - if (expression instanceof CSharpMethodInvocationTree invocation - && invocation.getEnclosingBlock() != null) { - return Optional.of(invocation.getEnclosingBlock()); - } - if (expression instanceof CSharpObjectCreationTree creation - && creation.getEnclosingBlock() != null) { - return Optional.of(creation.getEnclosingBlock()); - } - return Optional.empty(); - } - - @Nullable @Override - public MethodMatcher createMethodMatcherBasedOn( - @Nonnull CSharpTree methodDefinition) { - // Inter-procedural method matching not supported without semantic analysis - return null; - } - - @Nullable @Override - public EnumMatcher createSimpleEnumMatcherFor( - @Nonnull CSharpTree enumIdentifier, @Nonnull MatchContext matchContext) { - Optional name = translation().getEnumIdentifierName(matchContext, enumIdentifier); - return name.>map(EnumMatcher::new).orElse(null); - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageTranslation.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageTranslation.java deleted file mode 100755 index bc15a34bc..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpLanguageTranslation.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.detection.IType; -import com.ibm.engine.detection.MatchContext; -import com.ibm.engine.language.ILanguageTranslation; -import com.ibm.engine.language.csharp.tree.CSharpIdentifierTree; -import com.ibm.engine.language.csharp.tree.CSharpLiteralTree; -import com.ibm.engine.language.csharp.tree.CSharpMemberAccessTree; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; - -/** - * Language translation implementation for C#. - * - *

Extracts method names, object type strings, and parameter information from the CSharpTree - * hierarchy produced by the ANTLR4-based tree converter. Since ANTLR4 provides only syntactic - * information (no type inference), all parameter types match any expected type. - */ -public final class CSharpLanguageTranslation implements ILanguageTranslation { - - @Nonnull - @Override - public Optional getMethodName( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree methodInvocation) { - if (methodInvocation instanceof CSharpMethodInvocationTree invocation) { - return Optional.of(invocation.getMethodName()); - } else if (methodInvocation instanceof CSharpObjectCreationTree) { - // Constructor calls map to the "" sentinel used throughout the engine - return Optional.of(""); - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional getInvokedObjectTypeString( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree methodInvocation) { - if (methodInvocation instanceof CSharpMethodInvocationTree invocation) { - String typeName = invocation.getObjectTypeName(); - return Optional.of(expectedType -> expectedType.equals(typeName)); - } else if (methodInvocation instanceof CSharpObjectCreationTree creation) { - String typeName = creation.getTypeName(); - return Optional.of(expectedType -> expectedType.equals(typeName)); - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional getMethodReturnTypeString( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree methodInvocation) { - // ANTLR4 provides no type inference; return type unavailable - return Optional.empty(); - } - - @Nonnull - @Override - public List getMethodParameterTypes( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree methodInvocation) { - List args = null; - if (methodInvocation instanceof CSharpMethodInvocationTree invocation) { - args = invocation.getArguments(); - } else if (methodInvocation instanceof CSharpObjectCreationTree creation) { - args = creation.getArguments(); - } - if (args == null || args.isEmpty()) { - return Collections.emptyList(); - } - // No semantic type info; every argument matches any expected type - List types = new ArrayList<>(args.size()); - for (int i = 0; i < args.size(); i++) { - types.add(expectedType -> true); - } - return types; - } - - @Nonnull - @Override - public Optional resolveIdentifierAsString( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree identifierTree) { - if (identifierTree instanceof CSharpLiteralTree literal) { - return Optional.of(literal.getValue()); - } else if (identifierTree instanceof CSharpIdentifierTree identifier) { - return Optional.of(identifier.getName()); - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional getEnumIdentifierName( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree enumIdentifier) { - if (enumIdentifier instanceof CSharpMemberAccessTree memberAccess) { - // e.g. CipherMode.CBC → "CBC" - return Optional.of(memberAccess.getMemberName()); - } else if (enumIdentifier instanceof CSharpIdentifierTree identifier) { - return Optional.of(identifier.getName()); - } - return Optional.empty(); - } - - @Nonnull - @Override - public Optional getEnumClassName( - @Nonnull MatchContext matchContext, @Nonnull CSharpTree enumClass) { - if (enumClass instanceof CSharpMemberAccessTree memberAccess) { - // e.g. CipherMode.CBC → "CipherMode" - return Optional.of(memberAccess.getTypeName()); - } - return Optional.empty(); - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpScanContext.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpScanContext.java deleted file mode 100755 index a375e8f3c..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpScanContext.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.language.IScanContext; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.issue.NewIssue; -import org.sonar.api.batch.sensor.issue.NewIssueLocation; -import org.sonar.api.rule.RuleKey; -import org.sonar.check.Rule; - -/** - * C# scan context wrapping the SonarQube SensorContext. - * - *

Unlike Go (which delegates to sonar-go's {@code CheckContext}), C# has no sonar-csharp - * framework, so this record holds the raw {@link SensorContext} and {@link InputFile} and reports - * issues directly via the sensor API. - * - * @param sensorContext the SonarQube sensor context for the current analysis - * @param inputFile the file currently being analysed - * @param repositoryKey the rule repository key (e.g. {@code "sonar-cs-crypto"}) - */ -public record CSharpScanContext( - @Nonnull SensorContext sensorContext, - @Nonnull InputFile inputFile, - @Nonnull String repositoryKey) - implements IScanContext { - - @Override - public void reportIssue( - @Nonnull CSharpCheck currentRule, @Nonnull CSharpTree tree, @Nonnull String message) { - String ruleKey = getRuleKey(currentRule); - if (ruleKey == null) { - return; - } - int line = Math.max(1, tree.getLine()); - NewIssue issue = sensorContext.newIssue(); - NewIssueLocation location = - issue.newLocation().on(inputFile).at(inputFile.selectLine(line)).message(message); - issue.forRule(RuleKey.of(repositoryKey, ruleKey)).at(location).save(); - } - - @Nullable private static String getRuleKey(@Nonnull CSharpCheck rule) { - Rule annotation = rule.getClass().getAnnotation(Rule.class); - return annotation != null ? annotation.key() : null; - } - - @Nonnull - @Override - public InputFile getInputFile() { - return inputFile; - } - - @Nonnull - @Override - public String getFilePath() { - return inputFile.uri().getPath(); - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpSymbol.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpSymbol.java deleted file mode 100755 index e261fc7f8..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpSymbol.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import javax.annotation.Nonnull; - -/** - * Minimal symbol representation for C# detection. - * - *

Since the ANTLR4 grammar does not provide semantic symbol resolution (no type inference), this - * class holds only the identifier name. Full symbol tracking across scopes is not supported in the - * current implementation. - */ -public final class CSharpSymbol { - - @Nonnull private final String name; - - public CSharpSymbol(@Nonnull String name) { - this.name = name; - } - - @Nonnull - public String getName() { - return name; - } - - @Override - public String toString() { - return "CSharpSymbol{" + name + "}"; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpTreeConverter.java b/engine/src/main/java/com/ibm/engine/language/csharp/CSharpTreeConverter.java deleted file mode 100644 index 059e125d0..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/CSharpTreeConverter.java +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp; - -import com.ibm.engine.language.csharp.antlr.CSharpParser; -import com.ibm.engine.language.csharp.antlr.CSharpParserBaseVisitor; -import com.ibm.engine.language.csharp.tree.CSharpBlockTree; -import com.ibm.engine.language.csharp.tree.CSharpIdentifierTree; -import com.ibm.engine.language.csharp.tree.CSharpLiteralTree; -import com.ibm.engine.language.csharp.tree.CSharpMemberAccessTree; -import com.ibm.engine.language.csharp.tree.CSharpMethodInvocationTree; -import com.ibm.engine.language.csharp.tree.CSharpObjectCreationTree; -import com.ibm.engine.language.csharp.tree.CSharpTree; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; - -/** - * Converts an ANTLR4 C# parse tree to the language-agnostic {@link CSharpTree} hierarchy. - * - *

This visitor walks the ANTLR parse tree to find method bodies ({@link - * CSharpParser.BlockContext}) and extracts the following patterns from each body: - * - *

    - *
  • Static factory calls: {@code Aes.Create()}, {@code RSA.Create(2048)} - *
  • Constructor calls: {@code new AesManaged()}, {@code new AesGcm(key)} - *
- * - *

Each method body is returned as a {@link CSharpBlockTree} containing the detected invocations, - * ready to be handed to the detection engine. - * - *

The converter uses two ANTLR visitor layers: - * - *

    - *
  1. Outer {@link CSharpTreeConverter} — walks the whole compilation unit and calls {@link - * #visitBlock} for every {@code { }} scope found. - *
  2. Inner {@link StatementCollector} — collects method invocations and object creations within - * a single block, stopping at nested blocks so they are picked up by the outer visitor. - *
- */ -public final class CSharpTreeConverter extends CSharpParserBaseVisitor { - - private final List bodies = new ArrayList<>(); - - /** - * Extracts all method bodies from the compilation unit. - * - * @param root the root parse tree node - * @return list of block trees, one per method/constructor/lambda body found - */ - @Nonnull - public List extractMethodBodies( - @Nonnull CSharpParser.Compilation_unitContext root) { - visit(root); - return Collections.unmodifiableList(bodies); - } - - /** - * Called for every {@code { ... }} block in the parse tree. - * - *

Collects the invocations at this block's immediate statement level (via {@link - * StatementCollector}), adds the resulting {@link CSharpBlockTree} to the list, then recurses - * into children so nested blocks are discovered by subsequent {@link #visitBlock} calls. - */ - @Override - public Void visitBlock(CSharpParser.BlockContext ctx) { - StatementCollector collector = new StatementCollector(); - // Visit each child of the block through the collector (not the block itself, to avoid - // triggering StatementCollector.visitBlock which stops at nested blocks) - for (int i = 0; i < ctx.getChildCount(); i++) { - collector.visit(ctx.getChild(i)); - } - bodies.add( - new CSharpBlockTree( - ctx.getStart().getLine(), - ctx.getStart().getCharPositionInLine(), - collector.getStatements())); - // Recurse to discover nested blocks (lambdas, local functions, etc.) - visitChildren(ctx); - return null; - } - - // ----------------------------------------------------------------------- - // Inner visitor: collects invocations within a single block level - // ----------------------------------------------------------------------- - - /** - * Collects method invocations and object creations from a single block, stopping at nested - * {@link CSharpParser.BlockContext} nodes so they are handled by the outer visitor. - */ - private static final class StatementCollector extends CSharpParserBaseVisitor { - - private final List statements = new ArrayList<>(); - - /** - * Set to the LHS identifier before descending into a {@code local_variable_declarator}'s - * initializer. Consumed (set back to null) by {@link #visitPrimary_expression} so it is - * applied to exactly the first (outermost) primary_expression in the initializer. - */ - @Nullable private String pendingAssignedIdentifier = null; - - @Nonnull - List getStatements() { - return Collections.unmodifiableList(statements); - } - - /** Stop at nested blocks — they become separate {@link CSharpBlockTree} entries. */ - @Override - public Void visitBlock(CSharpParser.BlockContext ctx) { - return null; - } - - /** - * Captures the variable name from {@code var x = Expr()} so that the emitted tree node gets - * its {@code assignedIdentifier} populated for later symbol tracking. - */ - @Override - public Void visitLocal_variable_declarator( - CSharpParser.Local_variable_declaratorContext ctx) { - if (ctx.identifier() != null && ctx.local_variable_initializer() != null) { - pendingAssignedIdentifier = ctx.identifier().getText(); - } - try { - return visitChildren(ctx); - } finally { - pendingAssignedIdentifier = null; - } - } - - /** - * Handles property-setter assignments of the form {@code obj.Property = value}. - * - *

Emits a synthetic {@link CSharpMethodInvocationTree} with method name {@code - * set_} (e.g. {@code set_Mode}) and the RHS as the sole argument. This mirrors - * the underlying CLR semantics — C# properties compile to {@code get_X}/{@code set_X} - * accessor methods. The synthetic node is then picked up by {@code isInvocationOnVariable} - * + {@code withDependingDetectionRules} in the detection engine. - * - *

Stops recursion so that neither the LHS nor the RHS {@code primary_expression} nodes - * are visited separately. - */ - @Override - public Void visitAssignment(CSharpParser.AssignmentContext ctx) { - // Only handle simple assignment (=), not compound (+=, -=, etc.) - if (ctx.assignment_operator() == null - || ctx.assignment_operator().ASSIGNMENT() == null) { - return null; - } - - // Find primary_expression inside the LHS unary_expression - CSharpParser.Primary_expressionContext lhsPrimary = - findPrimaryExpression(ctx.unary_expression()); - if (lhsPrimary == null) { - return null; - } - - List children = lhsPrimary.children; - if (children == null || children.size() < 2) { - return null; - } - - CSharpParser.Primary_expression_startContext start = - lhsPrimary.primary_expression_start(); - if (!(start instanceof CSharpParser.SimpleNameExpressionContext simpleCtx)) { - return null; - } - - // LHS must be exactly: identifier.PropertyName — one member_access, no method - // invocation - String propertyName = null; - for (int i = 1; i < children.size(); i++) { - if (children.get(i) instanceof CSharpParser.Member_accessContext memberCtx) { - if (propertyName != null) { - return null; // chained access like a.b.c — skip - } - propertyName = memberCtx.identifier().getText(); - } else if (children.get(i) instanceof CSharpParser.Method_invocationContext) { - return null; // method call, not a property assignment - } - } - if (propertyName == null) { - return null; - } - - String variableName = simpleCtx.identifier().getText(); - String setterName = "set_" + propertyName; - - // Convert RHS expression to the setter argument - CSharpParser.ExpressionContext rhs = ctx.expression(); - if (rhs == null) { - return null; - } - CSharpTree rhsTree = convertExpression(rhs); - List args = - rhsTree != null ? Collections.singletonList(rhsTree) : Collections.emptyList(); - - statements.add( - new CSharpMethodInvocationTree( - ctx.getStart().getLine(), - ctx.getStart().getCharPositionInLine(), - variableName, - setterName, - args, - null, // property setters are not themselves assigned to a variable - null)); // enclosingBlock set by CSharpBlockTree constructor - - return null; // do NOT visit children — prevents double-counting LHS / RHS nodes - } - - /** - * Converts the primary_expression and adds it to the statement list. Does NOT recurse - * further to avoid double-counting nested primary_expressions. Consumes {@link - * #pendingAssignedIdentifier} so it is applied to the outermost call only. - */ - @Override - public Void visitPrimary_expression(CSharpParser.Primary_expressionContext ctx) { - String assignedId = pendingAssignedIdentifier; - pendingAssignedIdentifier = null; // consume — prevents leaking to sibling expressions - CSharpTree node = convertPrimaryExpression(ctx, assignedId); - if (node != null) { - statements.add(node); - } - return null; - } - - // ----------------------------------------------------------------------- - // Primary expression conversion - // ----------------------------------------------------------------------- - - /** - * Converts a primary_expression to a CSharpTree node. - * - *

Handled patterns: - * - *

    - *
  • {@code new AesManaged()} — objectCreationExpression start, no further parts - *
  • {@code Aes.Create()} — simpleNameExpression + member_access + method_invocation - *
- */ - @Nullable private CSharpTree convertPrimaryExpression( - @Nonnull CSharpParser.Primary_expressionContext ctx, - @Nullable String assignedIdentifier) { - CSharpParser.Primary_expression_startContext start = ctx.primary_expression_start(); - - // Pattern: new AesManaged(), new AesGcm(key), etc. - if (start instanceof CSharpParser.ObjectCreationExpressionContext objCreationCtx) { - return convertObjectCreationFromStart(objCreationCtx, assignedIdentifier); - } - - // Pattern: Aes.Create(), RSA.Create(2048), SHA256.Create() - // Children of primary_expression in order: [start, ...parts...] - List children = ctx.children; - if (children == null || children.size() < 3) { - return null; - } - - // Find the last method_invocation in the child list - int methodInvIdx = -1; - for (int i = children.size() - 1; i >= 1; i--) { - if (children.get(i) instanceof CSharpParser.Method_invocationContext) { - methodInvIdx = i; - break; - } - } - if (methodInvIdx < 0) { - return null; - } - - // Find the member_access immediately preceding the method_invocation - int memberAccessIdx = -1; - for (int i = methodInvIdx - 1; i >= 1; i--) { - if (children.get(i) instanceof CSharpParser.Member_accessContext) { - memberAccessIdx = i; - break; - } - // bracket_expressions can appear between member_access and method_invocation - if (!(children.get(i) instanceof CSharpParser.Bracket_expressionContext)) { - break; - } - } - if (memberAccessIdx < 0) { - return null; - } - - CSharpParser.Member_accessContext memberAccess = - (CSharpParser.Member_accessContext) children.get(memberAccessIdx); - CSharpParser.Method_invocationContext methodInv = - (CSharpParser.Method_invocationContext) children.get(methodInvIdx); - - String methodName = memberAccess.identifier().getText(); - String objectTypeName = resolveObjectTypeName(start, children, memberAccessIdx); - List args = convertArgumentList(methodInv.argument_list()); - - return new CSharpMethodInvocationTree( - ctx.getStart().getLine(), - ctx.getStart().getCharPositionInLine(), - objectTypeName, - methodName, - args, - assignedIdentifier, - null); - } - - /** - * Resolves the object type name for a method invocation chain. - * - *

For {@code Aes.Create()}: start = "Aes", memberAccessIdx = 1 → "Aes". For {@code - * foo.Aes.Create()}: the member_access before the last gives "Aes". - */ - @Nonnull - private String resolveObjectTypeName( - @Nonnull CSharpParser.Primary_expression_startContext start, - @Nonnull List children, - int memberAccessIdx) { - // Check if there's a preceding member_access (chained call) - for (int i = memberAccessIdx - 1; i >= 1; i--) { - if (children.get(i) instanceof CSharpParser.Member_accessContext prevMember) { - return prevMember.identifier().getText(); - } - } - // Simple case: start holds the receiver type name - if (start instanceof CSharpParser.SimpleNameExpressionContext simpleCtx) { - return simpleCtx.identifier().getText(); - } - return start.getText(); - } - - /** Handles the {@code new Type(...)} pattern from an objectCreationExpression start. */ - @Nullable private CSharpTree convertObjectCreationFromStart( - @Nonnull CSharpParser.ObjectCreationExpressionContext objCreationCtx, - @Nullable String assignedIdentifier) { - // In v7 grammar, type_ is directly on ObjectCreationExpressionContext - // (not nested inside object_creation_expression as in the old simplified grammar) - CSharpParser.Type_Context typeCtx = objCreationCtx.type_(); - if (typeCtx == null) { - return null; - } - String typeName = typeCtx.getText(); - // Strip generic type arguments for matching (e.g. "List" → "List") - int ltIdx = typeName.indexOf('<'); - if (ltIdx > 0) { - typeName = typeName.substring(0, ltIdx); - } - - // In v7, object_creation_expression holds (OPEN_PARENS argument_list? CLOSE_PARENS) - // directly — there is no object_creation_args wrapper - List args = Collections.emptyList(); - CSharpParser.Object_creation_expressionContext objExpr = - objCreationCtx.object_creation_expression(); - if (objExpr != null) { - args = convertArgumentList(objExpr.argument_list()); - } - - return new CSharpObjectCreationTree( - objCreationCtx.getStart().getLine(), - objCreationCtx.getStart().getCharPositionInLine(), - typeName, - args, - assignedIdentifier, - null); - } - - // ----------------------------------------------------------------------- - // Argument conversion - // ----------------------------------------------------------------------- - - @Nonnull - private List convertArgumentList( - @Nullable CSharpParser.Argument_listContext argListCtx) { - if (argListCtx == null) { - return Collections.emptyList(); - } - List args = new ArrayList<>(); - for (CSharpParser.ArgumentContext arg : argListCtx.argument()) { - CSharpTree argTree = convertArgument(arg); - if (argTree != null) { - args.add(argTree); - } - } - return Collections.unmodifiableList(args); - } - - @Nullable private CSharpTree convertArgument(@Nonnull CSharpParser.ArgumentContext arg) { - CSharpParser.ExpressionContext expr = arg.expression(); - if (expr == null) { - return null; - } - return convertExpression(expr); - } - - @Nullable private CSharpTree convertExpression(@Nonnull CSharpParser.ExpressionContext expr) { - String text = expr.getText(); - if (text == null || text.isEmpty()) { - return null; - } - CSharpParser.Primary_expressionContext primaryExpr = findPrimaryExpression(expr); - if (primaryExpr != null) { - CSharpTree start = convertPrimaryExpressionStart(primaryExpr); - if (start != null) { - return start; - } - } - return createLeafFromText(text, expr.getStart()); - } - - /** - * Walks an expression to find the first primary_expression child (handles intermediate - * grammar rules before reaching primary). - */ - @Nullable private CSharpParser.Primary_expressionContext findPrimaryExpression( - @Nonnull ParseTree tree) { - if (tree instanceof CSharpParser.Primary_expressionContext primary) { - return primary; - } - for (int i = 0; i < tree.getChildCount(); i++) { - CSharpParser.Primary_expressionContext found = - findPrimaryExpression(tree.getChild(i)); - if (found != null) { - return found; - } - } - return null; - } - - /** Converts a primary_expression to its simplest leaf form (for argument extraction). */ - @Nullable private CSharpTree convertPrimaryExpressionStart( - @Nonnull CSharpParser.Primary_expressionContext ctx) { - CSharpParser.Primary_expression_startContext start = ctx.primary_expression_start(); - - if (start instanceof CSharpParser.LiteralExpressionContext literalCtx) { - return convertLiteral(literalCtx.literal()); - } - - if (start instanceof CSharpParser.SimpleNameExpressionContext simpleCtx) { - String name = simpleCtx.identifier().getText(); - List children = ctx.children; - if (children != null && children.size() >= 2) { - for (int i = 1; i < children.size(); i++) { - if (children.get(i) - instanceof CSharpParser.Member_accessContext memberCtx) { - return new CSharpMemberAccessTree( - ctx.getStart().getLine(), - ctx.getStart().getCharPositionInLine(), - name, - memberCtx.identifier().getText()); - } - } - } - return new CSharpIdentifierTree( - ctx.getStart().getLine(), ctx.getStart().getCharPositionInLine(), name); - } - - return null; - } - - @Nullable private CSharpTree convertLiteral(@Nullable CSharpParser.LiteralContext literalCtx) { - if (literalCtx == null) { - return null; - } - String text = literalCtx.getText(); - int line = literalCtx.getStart().getLine(); - int col = literalCtx.getStart().getCharPositionInLine(); - - if (literalCtx.INTEGER_LITERAL() != null) { - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.INTEGER, text); - } - if (literalCtx.REAL_LITERAL() != null) { - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.REAL, text); - } - if (literalCtx.string_literal() != null) { - String value = text; - if (value.length() >= 2 && value.charAt(0) == '"') { - value = value.substring(1, value.length() - 1); - } else if (value.startsWith("@\"") && value.endsWith("\"")) { - value = value.substring(2, value.length() - 1); - } - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.STRING, value); - } - if (literalCtx.CHARACTER_LITERAL() != null) { - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.CHARACTER, text); - } - if (literalCtx.boolean_literal() != null) { - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.BOOLEAN, text); - } - if (literalCtx.NULL_() != null) { - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.NULL, "null"); - } - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.STRING, text); - } - - /** Last-resort fallback: creates a leaf node by inspecting the raw text. */ - @Nullable private CSharpTree createLeafFromText(@Nonnull String text, @Nullable Token startToken) { - int line = startToken != null ? startToken.getLine() : 0; - int col = startToken != null ? startToken.getCharPositionInLine() : 0; - - if (text.isEmpty() || "null".equals(text)) { - return null; - } - try { - Integer.parseInt(text); - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.INTEGER, text); - } catch (NumberFormatException ignored) { - // not integer - } - if ((text.startsWith("\"") && text.endsWith("\"")) - || (text.startsWith("@\"") && text.endsWith("\""))) { - String value = text.replaceAll("^@?\"|\"$", ""); - return new CSharpLiteralTree(line, col, CSharpLiteralTree.Kind.STRING, value); - } - int dotIdx = text.lastIndexOf('.'); - if (dotIdx > 0) { - String typePart = text.substring(0, dotIdx); - String memberPart = text.substring(dotIdx + 1); - return new CSharpMemberAccessTree(line, col, typePart, memberPart); - } - return new CSharpIdentifierTree(line, col, text); - } - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpLexerBase.java b/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpLexerBase.java deleted file mode 100644 index ce65b7176..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpLexerBase.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.antlr; - -import java.util.ArrayDeque; -import java.util.Deque; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CommonToken; -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.Token; - -public abstract class CSharpLexerBase extends Lexer { - - protected CSharpLexerBase(CharStream input) { - super(input); - } - - protected int interpolatedStringLevel; - protected final Deque interpolatedVerbatiums = new ArrayDeque<>(); - protected final Deque curlyLevels = new ArrayDeque<>(); - protected boolean verbatium; - - protected void OnInterpolatedRegularStringStart() { - interpolatedStringLevel++; - interpolatedVerbatiums.push(false); - verbatium = false; - } - - protected void OnInterpolatedVerbatiumStringStart() { - interpolatedStringLevel++; - interpolatedVerbatiums.push(true); - verbatium = true; - } - - protected void OnOpenBrace() { - if (interpolatedStringLevel > 0) { - curlyLevels.push(curlyLevels.pop() + 1); - } - } - - protected void OnCloseBrace() { - if (interpolatedStringLevel > 0) { - curlyLevels.push(curlyLevels.pop() - 1); - if (curlyLevels.peek() == 0) { - curlyLevels.pop(); - skip(); - popMode(); - } - } - } - - protected void OnColon() { - if (interpolatedStringLevel > 0) { - int ind = 1; - boolean switchToFormatString = true; - while ((char) getInputStream().LA(ind) != '}') { - if (getInputStream().LA(ind) == ':' || getInputStream().LA(ind) == ')') { - switchToFormatString = false; - break; - } - ind++; - } - if (switchToFormatString) { - mode(CSharpLexer.INTERPOLATION_FORMAT); - } - } - } - - protected void OpenBraceInside() { - curlyLevels.push(1); - } - - protected void OnDoubleQuoteInside() { - interpolatedStringLevel--; - interpolatedVerbatiums.pop(); - verbatium = (interpolatedVerbatiums.size() > 0 ? interpolatedVerbatiums.peek() : false); - } - - protected void OnCloseBraceInside() { - curlyLevels.pop(); - } - - protected boolean IsRegularCharInside() { - return !verbatium; - } - - protected boolean IsVerbatiumDoubleQuoteInside() { - return verbatium; - } - - // ------------------------------------------------------------------------- - // nextToken override — routes DIRECTIVE-channel tokens to HIDDEN - // All preprocessor branches are kept visible so every crypto asset in the - // source is reachable for detection, regardless of compile-time symbols. - // ------------------------------------------------------------------------- - @Override - public Token nextToken() { - Token tok = super.nextToken(); - if (tok.getChannel() == CSharpLexer.DIRECTIVE) { - // Route directive tokens to HIDDEN so the parser ignores the - // directives themselves, but does NOT skip any code — both sides - // of #if/#else remain in the token stream and are analysed. - ((CommonToken) tok).setChannel(HIDDEN); - } - return tok; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpParserBase.java b/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpParserBase.java deleted file mode 100644 index 3aabfe94d..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/antlr/CSharpParserBase.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.antlr; - -import java.util.HashSet; -import java.util.Set; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; - -public abstract class CSharpParserBase extends Parser { - private static final String[] ALL_SEMANTIC_FUNCTIONS = {"IsLocalVariableDeclaration"}; - - private final Set noSemantics; - - protected CSharpParserBase(TokenStream input) { - super(input); - noSemantics = parseNoSemantics(System.getProperty("sun.java.command", "").split("\\s+")); - } - - private static Set parseNoSemantics(String[] args) { - Set result = new HashSet<>(); - for (String a : args) { - if (a.toLowerCase().startsWith("--no-semantics")) { - int eq = a.indexOf('='); - if (eq == -1) { - for (String f : ALL_SEMANTIC_FUNCTIONS) result.add(f); - } else { - for (String f : a.substring(eq + 1).split(",")) result.add(f.trim()); - } - } - } - return result; - } - - protected boolean IsRightArrow() { - return areAdjacent(); - } - - protected boolean IsRightShift() { - return areAdjacent(); - } - - protected boolean IsRightShiftAssignment() { - return areAdjacent(); - } - - private boolean areAdjacent() { - Token first = _input.LT(-2); - Token second = _input.LT(-1); - return first != null - && second != null - && first.getTokenIndex() + 1 == second.getTokenIndex(); - } - - protected boolean IsLocalVariableDeclaration() { - if (noSemantics.contains("IsLocalVariableDeclaration")) return true; - if (!(this._ctx instanceof CSharpParser.Local_variable_declarationContext)) { - return false; - } - CSharpParser.Local_variable_declarationContext local_var_decl = - (CSharpParser.Local_variable_declarationContext) this._ctx; - CSharpParser.Local_variable_typeContext local_variable_type = - local_var_decl.local_variable_type(); - if (local_variable_type == null) return true; - if (local_variable_type.getText().equals("var")) return false; - return true; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpBlockTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpBlockTree.java deleted file mode 100755 index 5ee7bbbcc..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpBlockTree.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Represents a C# code block (method body, lambda, etc.), containing a list of statements. - * - *

This is the entry point for the detection engine — the sensor dispatches per-method blocks to - * the engine for crypto pattern detection. - */ -public final class CSharpBlockTree implements CSharpTree { - - private final int line; - private final int column; - @Nonnull private final List statements; - - public CSharpBlockTree(int line, int column, @Nonnull List statements) { - this.line = line; - this.column = column; - this.statements = statements; - // Back-patch each statement so getEnclosingMethod() can navigate back to this block - for (CSharpTree statement : statements) { - if (statement instanceof CSharpMethodInvocationTree inv) { - inv.setEnclosingBlock(this); - } else if (statement instanceof CSharpObjectCreationTree creation) { - creation.setEnclosingBlock(this); - } - } - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return ""; - } - - @Nonnull - public List getStatements() { - return statements; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpIdentifierTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpIdentifierTree.java deleted file mode 100755 index f8acae517..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpIdentifierTree.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import javax.annotation.Nonnull; - -/** - * Represents a C# identifier (variable name, type name, etc.) used as an argument or in expressions - * where the resolved value is not immediately known. - */ -public final class CSharpIdentifierTree implements CSharpTree { - - private final int line; - private final int column; - @Nonnull private final String name; - - public CSharpIdentifierTree(int line, int column, @Nonnull String name) { - this.line = line; - this.column = column; - this.name = name; - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return name; - } - - @Nonnull - public String getName() { - return name; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpLiteralTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpLiteralTree.java deleted file mode 100755 index f828bd5bd..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpLiteralTree.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import javax.annotation.Nonnull; - -/** - * Represents a C# literal value (string, integer, boolean, etc.). - * - *

The {@code value} field contains the raw literal text as it appears in source code. For string - * literals, the surrounding quotes are stripped. - */ -public final class CSharpLiteralTree implements CSharpTree { - - /** Literal kind. */ - public enum Kind { - STRING, - INTEGER, - REAL, - BOOLEAN, - CHARACTER, - NULL - } - - private final int line; - private final int column; - @Nonnull private final Kind kind; - - /** The literal value. For strings: content without quotes. For integers: the numeric string. */ - @Nonnull private final String value; - - public CSharpLiteralTree(int line, int column, @Nonnull Kind kind, @Nonnull String value) { - this.line = line; - this.column = column; - this.kind = kind; - this.value = value; - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return value; - } - - @Nonnull - public Kind getKind() { - return kind; - } - - @Nonnull - public String getValue() { - return value; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMemberAccessTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMemberAccessTree.java deleted file mode 100755 index 8cf4dbbd4..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMemberAccessTree.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import javax.annotation.Nonnull; - -/** - * Represents a C# member access expression such as {@code CipherMode.CBC} or {@code - * ECCurve.NamedCurves.nistP256}. - * - *

Used for enum-like values in C# that are passed as arguments: - * - *

- *   aes.Mode = CipherMode.CBC;
- *   var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
- *   new Rfc2898DeriveBytes(pwd, salt, iter, HashAlgorithmName.SHA256);
- * 
- * - *

The {@code typeName} and {@code memberName} allow the detection engine to implement {@link - * com.ibm.engine.language.ILanguageTranslation#getEnumClassName} and {@link - * com.ibm.engine.language.ILanguageTranslation#getEnumIdentifierName}. - */ -public final class CSharpMemberAccessTree implements CSharpTree { - - private final int line; - private final int column; - - /** The qualifier/type name (e.g. "CipherMode", "HashAlgorithmName", "ECCurve"). */ - @Nonnull private final String typeName; - - /** The member name (e.g. "CBC", "SHA256", "nistP256"). */ - @Nonnull private final String memberName; - - public CSharpMemberAccessTree( - int line, int column, @Nonnull String typeName, @Nonnull String memberName) { - this.line = line; - this.column = column; - this.typeName = typeName; - this.memberName = memberName; - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return typeName + "." + memberName; - } - - @Nonnull - public String getTypeName() { - return typeName; - } - - @Nonnull - public String getMemberName() { - return memberName; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMethodInvocationTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMethodInvocationTree.java deleted file mode 100755 index 2774c0a84..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpMethodInvocationTree.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * Represents a C# method invocation expression such as {@code Aes.Create()} or {@code - * RSA.Create(2048)}. - * - *

The {@code objectTypeName} is the simple class/package name before the dot (e.g. {@code - * "Aes"}, {@code "SHA256"}), and {@code methodName} is the method name (e.g. {@code "Create"}). - * - *

For chained calls, only the outermost method invocation is captured. - */ -public final class CSharpMethodInvocationTree implements CSharpTree { - - private final int line; - private final int column; - - /** The type/receiver name before the dot (e.g. "Aes", "RSA", "HashAlgorithm"). */ - @Nonnull private final String objectTypeName; - - /** The method name (e.g. "Create", "init"). */ - @Nonnull private final String methodName; - - /** The argument trees in call order. */ - @Nonnull private final List arguments; - - /** Optional identifier this invocation result is assigned to (for depending rule tracking). */ - @Nullable private final String assignedIdentifier; - - /** The enclosing block tree (for depending rule context). */ - @Nullable private CSharpBlockTree enclosingBlock; - - public CSharpMethodInvocationTree( - int line, - int column, - @Nonnull String objectTypeName, - @Nonnull String methodName, - @Nonnull List arguments, - @Nullable String assignedIdentifier, - @Nullable CSharpBlockTree enclosingBlock) { - this.line = line; - this.column = column; - this.objectTypeName = objectTypeName; - this.methodName = methodName; - this.arguments = arguments; - this.assignedIdentifier = assignedIdentifier; - this.enclosingBlock = enclosingBlock; - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return objectTypeName + "." + methodName + "(...)"; - } - - @Nonnull - public String getObjectTypeName() { - return objectTypeName; - } - - @Nonnull - public String getMethodName() { - return methodName; - } - - @Nonnull - public List getArguments() { - return arguments; - } - - @Nullable public String getAssignedIdentifier() { - return assignedIdentifier; - } - - @Nullable public CSharpBlockTree getEnclosingBlock() { - return enclosingBlock; - } - - /** Back-patched by {@link CSharpBlockTree} once the block is fully constructed. */ - public void setEnclosingBlock(@Nonnull CSharpBlockTree enclosingBlock) { - this.enclosingBlock = enclosingBlock; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpObjectCreationTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpObjectCreationTree.java deleted file mode 100755 index 996ff9e2f..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpObjectCreationTree.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * Represents a C# object creation expression such as {@code new AesManaged()} or {@code new - * AesGcm(key)}. - * - *

Detection rules match constructors using {@code - * forObjectTypes("AesManaged").forMethods("")}. - */ -public final class CSharpObjectCreationTree implements CSharpTree { - - private final int line; - private final int column; - - /** The simple type name (e.g. "AesManaged", "AesGcm", "HMACSHA256"). */ - @Nonnull private final String typeName; - - /** The constructor arguments. */ - @Nonnull private final List arguments; - - /** Optional identifier this new object is assigned to. */ - @Nullable private final String assignedIdentifier; - - /** The enclosing block tree (for depending rule context). */ - @Nullable private CSharpBlockTree enclosingBlock; - - public CSharpObjectCreationTree( - int line, - int column, - @Nonnull String typeName, - @Nonnull List arguments, - @Nullable String assignedIdentifier, - @Nullable CSharpBlockTree enclosingBlock) { - this.line = line; - this.column = column; - this.typeName = typeName; - this.arguments = arguments; - this.assignedIdentifier = assignedIdentifier; - this.enclosingBlock = enclosingBlock; - } - - @Override - public int getLine() { - return line; - } - - @Override - public int getColumn() { - return column; - } - - @Nonnull - @Override - public String getText() { - return "new " + typeName + "(...)"; - } - - @Nonnull - public String getTypeName() { - return typeName; - } - - @Nonnull - public List getArguments() { - return arguments; - } - - @Nullable public String getAssignedIdentifier() { - return assignedIdentifier; - } - - @Nullable public CSharpBlockTree getEnclosingBlock() { - return enclosingBlock; - } - - /** Back-patched by {@link CSharpBlockTree} once the block is fully constructed. */ - public void setEnclosingBlock(@Nonnull CSharpBlockTree enclosingBlock) { - this.enclosingBlock = enclosingBlock; - } -} diff --git a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpTree.java b/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpTree.java deleted file mode 100755 index 5c185365d..000000000 --- a/engine/src/main/java/com/ibm/engine/language/csharp/tree/CSharpTree.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Sonar Cryptography Plugin - * Copyright (C) 2024 PQCA - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.ibm.engine.language.csharp.tree; - -import javax.annotation.Nonnull; - -/** - * Base interface for C# AST nodes used in the detection engine. - * - *

Implementations of this interface wrap ANTLR4-generated parse tree nodes (from the - * CSharpParser grammar) and expose only the information needed by the detection engine. This keeps - * the engine free of ANTLR4 dependencies. - */ -public interface CSharpTree { - - /** Returns the 1-based line number of this node in the source file. */ - int getLine(); - - /** Returns the 0-based character offset within the line. */ - int getColumn(); - - /** Returns a brief human-readable description of this tree node for debugging purposes. */ - @Nonnull - String getText(); -} diff --git a/pom.xml b/pom.xml index 56b238582..86ff0fd7e 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,6 @@ java python go - csharp engine output common diff --git a/sonar-cryptography-plugin/pom.xml b/sonar-cryptography-plugin/pom.xml index 9ac6bfe6a..189ab59a2 100644 --- a/sonar-cryptography-plugin/pom.xml +++ b/sonar-cryptography-plugin/pom.xml @@ -41,12 +41,6 @@ 2.0.0-SNAPSHOT compile - - com.ibm - csharp - 2.0.0-SNAPSHOT - compile - @@ -71,7 +65,7 @@ Sonar Crypto Plugin com.ibm.plugin.CryptographyPlugin - java,jsp,py,ipynb,go,cs + java,jsp,py,ipynb,go ${sonar.minVersion} true true diff --git a/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/CryptographyPlugin.java b/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/CryptographyPlugin.java index 415b5a011..59bb441e6 100644 --- a/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/CryptographyPlugin.java +++ b/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/CryptographyPlugin.java @@ -48,9 +48,6 @@ public void define(Context context) { // golang GoScannerRuleDefinition.class, // Define Go rules CryptoGoSensor.class, // Custom sensor (sonar-go has no CheckRegistrar API) - // csharp - CSharpScannerRuleDefinition.class, // Define C# rules - CryptoCSharpSensor.class, // Custom sensor (sonar-csharp has no CheckRegistrar API) // general OutputFileJob.class); } diff --git a/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/ScannerManager.java b/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/ScannerManager.java index 7f8491b6f..5570021ef 100644 --- a/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/ScannerManager.java +++ b/sonar-cryptography-plugin/src/main/java/com/ibm/plugin/ScannerManager.java @@ -66,7 +66,6 @@ private List getAggregatedNodes() { nodes.addAll(JavaAggregator.getDetectedNodes()); nodes.addAll(PythonAggregator.getDetectedNodes()); nodes.addAll(GoAggregator.getDetectedNodes()); - nodes.addAll(CSharpAggregator.getDetectedNodes()); return nodes; } @@ -74,6 +73,5 @@ public void reset() { JavaAggregator.reset(); PythonAggregator.reset(); GoAggregator.reset(); - CSharpAggregator.reset(); } } diff --git a/sonar-cryptography-plugin/src/test/java/com/ibm/plugin/PluginTest.java b/sonar-cryptography-plugin/src/test/java/com/ibm/plugin/PluginTest.java index d7a409553..1721c93d2 100644 --- a/sonar-cryptography-plugin/src/test/java/com/ibm/plugin/PluginTest.java +++ b/sonar-cryptography-plugin/src/test/java/com/ibm/plugin/PluginTest.java @@ -39,6 +39,6 @@ void testExtensions() { Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); CryptographyPlugin plugin = new CryptographyPlugin(); plugin.define(context); - Assertions.assertEquals(10, context.getExtensions().size()); + Assertions.assertEquals(8, context.getExtensions().size()); } }