From 3d2c5575be0725884bacc4cff144f0dc0d15ee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9lio=20Rocha?= Date: Thu, 15 Oct 2026 17:59:43 +0100 Subject: [PATCH 1/4] Bump Opengrep to v1.31.0 Co-Authored-By: Claude Opus 5.5 --- .tool_version | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.tool_version b/.tool_version index ff6d09b..8b96872 100644 --- a/.tool_version +++ b/.tool_version @@ -1 +1 @@ -1.30.0 \ No newline at end of file +1.31.0 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0bd684d..a83af26 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG OPENGREP_VERSION=v1.30.0 +ARG OPENGREP_VERSION=v1.31.0 # Build codacy-opengrep wrapper FROM golang:1.23-alpine3.21 AS builder From 68ace1b58db471afcf12273420687074b9eb9391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9lio=20Rocha?= Date: Thu, 15 Oct 2026 17:59:43 +0100 Subject: [PATCH 2/4] Support Complexity, UnusedCode and Comprehensibility categories in docgen Co-Authored-By: Claude Opus 5.5 --- internal/docgen/parsing.go | 7 +++++++ internal/docgen/pattern.go | 15 +++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/docgen/parsing.go b/internal/docgen/parsing.go index db006b5..4eb6638 100644 --- a/internal/docgen/parsing.go +++ b/internal/docgen/parsing.go @@ -116,6 +116,7 @@ func getCodacyRules(docsDir string) (*ParsedSemgrepRules, error) { "codacy-rules-i18n.yaml", "codacy-rules-ai.yaml", "codacy-rules-exotic.yaml", + "codacy-rules-csharp.yaml", } for _, file := range customRulesFiles { filePath, _ := filepath.Abs(path.Join(docsDir, file)) @@ -433,6 +434,12 @@ func toCodacyCategory(r SemgrepRule) Category { return BestPractice case "codestyle": return CodeStyle + case "complexity": + return Complexity + case "unused-code": + return UnusedCode + case "comprehensibility": + return Comprehensibility case "": if len(r.Metadata.CWEs) > 0 { return Security diff --git a/internal/docgen/pattern.go b/internal/docgen/pattern.go index 6ded9c1..f7539d0 100644 --- a/internal/docgen/pattern.go +++ b/internal/docgen/pattern.go @@ -3,12 +3,15 @@ package docgen type Category string const ( - Security Category = "Security" - Performance Category = "Performance" - Compatibility Category = "Compatibility" - ErrorProne Category = "ErrorProne" - BestPractice Category = "BestPractice" - CodeStyle Category = "CodeStyle" + Security Category = "Security" + Performance Category = "Performance" + Compatibility Category = "Compatibility" + ErrorProne Category = "ErrorProne" + BestPractice Category = "BestPractice" + CodeStyle Category = "CodeStyle" + Complexity Category = "Complexity" + UnusedCode Category = "UnusedCode" + Comprehensibility Category = "Comprehensibility" ) type Level string From e373ca6f8d621d70b8e633e1f4808e3745ed00eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9lio=20Rocha?= Date: Thu, 15 Oct 2026 17:59:44 +0100 Subject: [PATCH 3/4] Add C# code quality and security rules Adds 405 custom rules for C# in docs/codacy-rules-csharp.yaml covering code style, correctness, best practices, performance, complexity, unused code and security, with one test file per rule. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- docs/codacy-rules-csharp.yaml | 8389 +++++++++++++++++ .../codacy-rules-csharp-header/patterns.xml | 4 + .../codacy-rules-csharp-header/results.xml | 6 + .../src/missing-copyright-header.cs | 8 + .../src/with-block-header.cs | 10 + .../src/with-header.cs | 9 + .../codacy-rules-csharp/patterns.xml | 407 + .../codacy-rules-csharp/results.xml | 2744 ++++++ .../src/absolute-action-route-template.cs | 24 + .../abstract-class-without-implementation.cs | 20 + .../action-route-without-controller-route.cs | 19 + .../action-without-produces-response-type.cs | 25 + .../src/always-same-math-comparison.cs | 15 + .../src/anonymous-delegate-unsubscribe.cs | 20 + .../any-with-equality-instead-of-contains.cs | 20 + .../src/api-action-without-http-verb.cs | 27 + .../api-controller-derives-from-controller.cs | 25 + .../src/argument-exception-parameter-name.cs | 29 + .../src/array-created-for-params.cs | 15 + .../assembly-com-visibility-not-explicit.cs | 10 + .../src/assembly-load-from-path.cs | 15 + .../src/assembly-not-marked-cls-compliant.cs | 9 + .../src/assertion-arguments-order.cs | 23 + .../src/assignment-in-sub-expression.cs | 34 + .../src/async-argument-validation.cs | 24 + .../src/async-await-as-identifier.cs | 21 + .../src/async-method-naming.cs | 37 + .../src/async-void-method.cs | 29 + .../src/attribute-not-sealed.cs | 21 + .../src/attribute-without-attribute-usage.cs | 19 + .../src/azure-function-failure-not-logged.cs | 34 + .../azure-function-without-error-handling.cs | 35 + .../src/backslash-in-route-template.cs | 14 + .../src/base-equals-reference-check.cs | 31 + .../src/base-object-equality-call.cs | 35 + .../src/begininvoke-without-endinvoke.cs | 20 + .../bitwise-operation-on-non-flags-enum.cs | 29 + .../src/blocking-async-call.cs | 31 + .../src/blocking-call-in-async-method.cs | 25 + .../src/blocking-call-in-azure-function.cs | 18 + .../src/boolean-literal-in-assertion.cs | 19 + .../src/break-outside-switch.cs | 29 + .../caller-information-parameter-not-last.cs | 16 + .../src/catch-general-exception.cs | 57 + .../src/catch-null-reference-exception.cs | 35 + .../src/catch-only-rethrows.cs | 35 + .../src/caught-exception-not-logged.cs | 41 + .../src/check-before-assign.cs | 21 + .../src/class-owns-disposable-fields.cs | 35 + .../class-with-only-private-constructors.cs | 25 + .../src/clear-text-protocol.cs | 19 + ...t-created-per-azure-function-invocation.cs | 22 + .../src/close-brace-at-line-start.cs | 22 + .../src/collection-element-overwritten.cs | 19 + .../src/collection-passed-to-own-method.cs | 17 + .../collection-property-with-public-setter.cs | 12 + .../src/com-security-call-in-managed-code.cs | 16 + .../src/commented-out-code.cs | 19 + ...oncurrentdictionary-lambda-captures-key.cs | 13 + .../src/condition-always-false.cs | 32 + .../src/condition-always-true.cs | 25 + .../src/conditional-on-same-line-as-brace.cs | 27 + .../conflicting-transparency-annotations.cs | 13 + .../src/console-output-logging.cs | 23 + .../src/control-character-in-string.cs | 12 + .../src/cookie-without-httponly-flag.cs | 16 + .../src/cookie-without-secure-flag.cs | 19 + .../src/count-used-to-check-emptiness.cs | 23 + .../src/csrf-protection-disabled.cs | 21 + .../culture-insensitive-string-operation.cs | 18 + .../src/custom-cryptographic-algorithm.cs | 18 + .../src/dangerous-safehandle-access.cs | 14 + .../database-connection-without-password.cs | 16 + .../src/datatable-without-locale.cs | 21 + .../src/date-parse-without-format-provider.cs | 18 + .../src/datetime-instead-of-datetimeoffset.cs | 14 + .../src/datetime-now-for-timing.cs | 21 + .../src/datetime-without-kind.cs | 14 + .../codacy-rules-csharp/src/dead-store.cs | 18 + .../src/debug-feature-enabled.cs | 18 + .../src/default-clause-position.cs | 35 + ...efault-parameter-value-without-optional.cs | 18 + .../src/default-value-on-parameter.cs | 22 + .../src/default-value-passed-explicitly.cs | 16 + .../src/deprecated-code.cs | 17 + .../src/derived-type-name-suffix.cs | 29 + .../src/deserialization-without-validation.cs | 43 + .../src/disposable-not-disposed.cs | 52 + .../src/disposable-without-finalizer.cs | 20 + .../src/dispose-does-not-dispose-fields.cs | 21 + .../src/dispose-method-without-idisposable.cs | 19 + .../src/disposed-object-returned.cs | 29 + .../src/doubled-prefix-operator.cs | 12 + .../src/duplicate-branch.cs | 36 + .../codacy-rules-csharp/src/duplicate-cast.cs | 22 + .../src/duplicate-condition-in-if-chain.cs | 34 + .../src/duplicate-log-template-placeholder.cs | 16 + .../src/else-if-without-else.cs | 51 + .../src/empty-case-before-default.cs | 26 + .../codacy-rules-csharp/src/empty-class.cs | 20 + .../src/empty-collection-accessed.cs | 22 + .../codacy-rules-csharp/src/empty-comment.cs | 17 + .../src/empty-default-clause.cs | 31 + .../src/empty-finalizer.cs | 17 + .../src/empty-generic-catch.cs | 30 + .../src/empty-interface.cs | 20 + .../codacy-rules-csharp/src/empty-method.cs | 26 + .../src/empty-namespace.cs | 9 + .../src/empty-nested-block.cs | 30 + .../src/empty-statement.cs | 28 + .../src/enum-name-suffix.cs | 18 + .../codacy-rules-csharp/src/enum-naming.cs | 29 + .../src/enum-storage-not-int32.cs | 13 + .../enumerable-first-last-on-linkedlist.cs | 17 + .../enumerable-method-instead-of-indexing.cs | 13 + .../src/enumerable-min-max-on-sorted-set.cs | 17 + .../equality-operator-on-reference-type.cs | 24 + .../src/equals-without-gethashcode.cs | 26 + .../src/equals-without-iequatable.cs | 20 + .../src/event-handler-signature.cs | 14 + .../src/event-never-raised.cs | 20 + .../src/exception-created-not-thrown.cs | 23 + ...exception-missing-standard-constructors.cs | 28 + .../src/exception-rethrown-explicitly.cs | 34 + ...exception-thrown-from-unexpected-method.cs | 45 + .../src/excessive-request-content-length.cs | 19 + ...ude-from-coverage-without-justification.cs | 16 + .../src/exit-method-call.cs | 20 + .../src/expected-exception-attribute.cs | 29 + .../src/export-without-implementation.cs | 16 + .../src/extension-method-in-same-namespace.cs | 17 + .../src/extension-method-on-object.cs | 13 + .../src/field-could-be-readonly.cs | 27 + .../src/field-shadows-parent-field.cs | 14 + .../src/file-too-many-lines.cs | 2006 ++++ .../codacy-rules-csharp/src/fixme-tag.cs | 13 + .../src/flags-enum-invalid-value.cs | 20 + .../src/flags-enum-members-not-initialized.cs | 38 + .../src/flags-zero-member-not-none.cs | 26 + .../src/floating-point-equality.cs | 15 + .../src/for-loop-never-runs.cs | 24 + .../src/for-loop-only-condition.cs | 23 + .../src/for-loop-wrong-direction.cs | 21 + .../src/for-update-not-loop-counter.cs | 18 + .../src/format-string-unused-arguments.cs | 14 + ...mattablestring-instead-of-string-create.cs | 17 + .../codacy-rules-csharp/src/gc-collect.cs | 14 + .../src/general-exception-thrown.cs | 29 + .../src/generic-logger-type-mismatch.cs | 20 + .../src/get-executing-assembly.cs | 15 + .../src/gethashcode-uses-mutable-field.cs | 20 + .../src/getter-method-could-be-property.cs | 23 + .../src/gettype-on-type-instance.cs | 18 + .../codacy-rules-csharp/src/goto-statement.cs | 25 + .../src/hardcoded-credentials.cs | 23 + .../src/hardcoded-date-format.cs | 16 + .../src/hardcoded-ip-address.cs | 18 + .../src/hardcoded-jwt-secret.cs | 22 + .../codacy-rules-csharp/src/hardcoded-uri.cs | 17 + .../src/httpclient-created-per-call.cs | 20 + .../icomparable-without-equality-operators.cs | 29 + .../src/identical-branches.cs | 30 + .../src/identical-method-implementations.cs | 25 + .../src/identical-operands.cs | 17 + .../src/iequatable-class-not-sealed.cs | 19 + .../src/ignored-return-value.cs | 21 + .../src/ignored-test-without-reason.cs | 30 + .../src/ill-formed-format-string.cs | 21 + .../src/incomplete-assertion.cs | 17 + .../src/inconsistent-operator-overloading.cs | 26 + .../incorrect-idisposable-implementation.cs | 31 + .../src/increment-in-expression.cs | 16 + .../src/indexof-positive-check.cs | 15 + .../src/infinite-loop-or-recursion.cs | 49 + .../src/insecure-cipher-mode-or-padding.cs | 17 + .../src/insecure-temporary-file.cs | 13 + .../src/integer-division-to-floating-point.cs | 14 + .../src/invalid-dynamic-shift-operand.cs | 12 + .../src/invalid-event-arguments.cs | 22 + .../src/invalid-log-message-template.cs | 17 + .../src/invalid-regular-expression.cs | 16 + .../src/invalid-shift-count.cs | 15 + .../src/invalid-test-method-signature.cs | 35 + .../src/inverted-boolean-check.cs | 15 + .../src/irregular-number-grouping.cs | 12 + .../iserializable-incorrect-implementation.cs | 18 + .../src/issue-suppression.cs | 18 + .../src/iterator-argument-validation.cs | 24 + .../src/jsinvokable-method-not-public.cs | 16 + .../src/jwt-signature-not-verified.cs | 21 + .../src/large-number-without-underscores.cs | 14 + .../codacy-rules-csharp/src/line-too-long.cs | 8 + .../src/list-in-public-api.cs | 20 + .../src/local-could-be-const.cs | 23 + .../src/local-shadows-field.cs | 22 + .../src/local-time-recorded.cs | 15 + .../src/lock-not-released-on-all-paths.cs | 48 + .../src/lock-on-local-variable.cs | 22 + .../src/lock-on-non-readonly-field.cs | 31 + .../src/lock-on-shared-resource.cs | 29 + .../src/lock-on-weak-identity-object.cs | 30 + .../src/log-and-rethrow.cs | 45 + .../src/log-template-argument-order.cs | 17 + ...og-template-placeholder-not-pascal-case.cs | 14 + .../src/logger-category-mismatch.cs | 18 + .../src/logger-configuration.cs | 21 + ...ogger-field-not-private-static-readonly.cs | 10 + .../codacy-rules-csharp/src/logger-naming.cs | 12 + .../logging-arguments-in-message-arguments.cs | 25 + .../src/loop-could-use-linq.cs | 28 + .../src/loop-counter-modified-in-body.cs | 23 + .../src/loop-with-single-iteration.cs | 42 + .../src/loose-file-permissions.cs | 15 + .../src/lowercase-literal-suffix.cs | 13 + .../src/lowercase-string-normalization.cs | 12 + .../codacy-rules-csharp/src/magic-number.cs | 30 + .../src/manual-timezone-conversion.cs | 15 + .../src/member-more-visible-than-type.cs | 22 + .../src/mergeable-if-statements.cs | 43 + .../src/mergeable-try-statements.cs | 35 + .../src/method-overloads-not-grouped.cs | 20 + .../src/method-property-pascal-case.cs | 25 + .../src/method-returns-constant.cs | 19 + .../src/misleading-conditional-indentation.cs | 24 + .../src/missing-assembly-version.cs | 11 + .../src/missing-configure-await.cs | 16 + .../src/missing-curly-braces.cs | 50 + .../src/missing-final-newline.cs | 6 + .../src/missing-format-provider.cs | 17 + ...missing-stathread-on-windows-forms-main.cs | 22 + .../src/missing-string-comparison.cs | 15 + .../src/model-state-not-validated.cs | 28 + .../src/modulus-equality-check.cs | 27 + .../src/multidimensional-array-parameter.cs | 21 + .../src/multidimensional-array.cs | 16 + .../src/multiline-block-without-braces.cs | 27 + .../src/multiple-declarations-per-line.cs | 14 + .../src/multiple-orderby-calls.cs | 23 + .../src/multiple-statements-per-line.cs | 30 + .../codacy-rules-csharp/src/nan-comparison.cs | 17 + .../src/native-method-not-wrapped.cs | 21 + .../src/nested-code-block.cs | 30 + .../src/nested-generic-type-in-signature.cs | 15 + .../src/nested-member-shadows-outer-member.cs | 13 + .../codacy-rules-csharp/src/nested-switch.cs | 24 + .../codacy-rules-csharp/src/nested-ternary.cs | 21 + .../src/non-constant-log-template.cs | 16 + .../src/non-constant-visible-static-field.cs | 19 + .../src/non-existent-operator.cs | 18 + .../src/non-generic-collection.cs | 22 + .../src/non-generic-event-handler.cs | 14 + .../src/non-integral-indexer.cs | 17 + .../src/non-private-field.cs | 16 + .../src/non-public-exception-type.cs | 16 + .../src/non-short-circuit-logic.cs | 17 + .../src/nonsensical-size-comparison.cs | 15 + .../src/not-implemented-exception.cs | 19 + .../src/null-pointer-dereference.cs | 47 + .../src/null-returned-for-collection.cs | 33 + .../src/null-returned-from-task-method.cs | 28 + .../src/nullable-gettype-comparison.cs | 14 + .../src/nullable-value-without-check.cs | 28 + .../src/object-created-and-dropped.cs | 22 + .../src/object-disposed-twice.cs | 29 + .../src/obsolete-without-explanation.cs | 16 + .../src/one-way-operation-returns-value.cs | 14 + .../src/operator-without-named-alternative.cs | 10 + ...l-field-without-deserialization-handler.cs | 25 + .../src/optional-on-ref-or-out-parameter.cs | 18 + .../src/optional-parameter.cs | 17 + .../src/orderby-before-where.cs | 14 + .../src/os-command-from-path.cs | 16 + .../src/out-or-ref-parameter.cs | 24 + .../src/outdated-base-type.cs | 17 + .../src/overlapping-overload-defaults.cs | 10 + .../src/overridable-call-in-constructor.cs | 34 + .../src/override-only-calls-base.cs | 27 + .../src/parameter-name-as-string.cs | 19 + ...parameter-name-differs-from-declaration.cs | 26 + .../src/parameter-named-like-method.cs | 18 + .../src/parameter-overwritten-before-read.cs | 38 + .../src/parameterless-guid-creation.cs | 15 + .../src/params-added-on-override.cs | 20 + .../part-creation-policy-without-export.cs | 17 + .../src/permissive-cors-policy.cs | 30 + .../src/predictable-initialization-vector.cs | 19 + .../src/predictable-password-salt.cs | 20 + .../src/predictable-secure-random-seed.cs | 16 + .../src/private-class-not-sealed.cs | 21 + .../src/property-getter-throws.cs | 36 + .../src/property-name-matches-get-method.cs | 19 + .../src/property-returns-collection-copy.cs | 22 + .../src/protected-member-in-sealed-class.cs | 18 + .../src/public-constant.cs | 18 + .../public-constructor-in-abstract-class.cs | 20 + .../codacy-rules-csharp/src/public-field.cs | 22 + .../src/public-static-mutable-field.cs | 13 + .../src/publicly-writable-directory.cs | 16 + .../src/pure-method-returns-void.cs | 16 + .../src/raw-request-data-in-controller.cs | 19 + .../src/readonly-mutable-field.cs | 12 + .../src/recursive-type-inheritance.cs | 14 + .../src/redundant-anonymous-property-name.cs | 18 + .../src/redundant-boolean-literal.cs | 28 + .../codacy-rules-csharp/src/redundant-cast.cs | 23 + .../redundant-constructor-or-destructor.cs | 24 + .../src/redundant-default-initialization.cs | 22 + .../src/redundant-double-parentheses.cs | 28 + .../src/redundant-inheritance.cs | 16 + .../codacy-rules-csharp/src/redundant-jump.cs | 46 + .../src/redundant-member-initializer.cs | 24 + .../src/redundant-modifier.cs | 27 + .../src/redundant-null-check-with-is.cs | 14 + .../src/redundant-parentheses-creation.cs | 24 + .../src/redundant-tochararray.cs | 19 + .../src/redundant-tostring.cs | 14 + .../src/ref-object-parameter.cs | 13 + .../src/reference-equals-value-type.cs | 19 + .../src/reflection-accessibility-bypass.cs | 16 + .../src/regex-without-timeout.cs | 16 + .../src/request-validation-disabled.cs | 19 + .../src/reserved-enum-member.cs | 11 + .../src/same-condition-tested-twice.cs | 28 + .../src/self-assignment.cs | 17 + .../src/serialization-handler-signature.cs | 21 + .../server-certificate-validation-disabled.cs | 16 + .../service-contract-without-operations.cs | 17 + .../src/setter-ignores-value.cs | 27 + .../src/shared-part-instantiated.cs | 20 + .../src/side-effect-in-debug-assert.cs | 17 + .../src/simplify-conditional.cs | 49 + .../src/simplify-linq-expression.cs | 19 + .../src/simplify-type-check.cs | 14 + .../src/sql-keyword-without-whitespace.cs | 16 + .../src/stateful-azure-function.cs | 24 + ...tic-constructor-only-initializes-fields.cs | 27 + .../static-field-assigned-in-constructor.cs | 23 + .../src/static-field-in-generic-type.cs | 12 + .../src/static-field-initialization-order.cs | 14 + .../src/static-field-written-from-instance.cs | 19 + .../src/static-readonly-could-be-const.cs | 10 + .../src/stream-read-result-ignored.cs | 24 + .../src/string-concatenation-in-loop.cs | 24 + ...tring-literal-for-localizable-parameter.cs | 22 + .../src/string-overload-for-single-char.cs | 17 + .../src/string-uri-overload-not-delegating.cs | 27 + .../src/stringbuilder-never-read.cs | 37 + .../src/struct-without-iequatable.cs | 20 + .../src/substring-before-indexof.cs | 15 + .../src/suppress-finalize-outside-dispose.cs | 25 + .../suppress-finalize-without-finalizer.cs | 22 + .../src/switch-too-few-cases.cs | 48 + .../src/switch-without-default.cs | 29 + .../codacy-rules-csharp/src/tab-characters.cs | 8 + .../src/temporal-type-as-primary-key.cs | 30 + .../src/test-class-without-tests.cs | 31 + .../src/test-without-assertion.cs | 38 + .../src/this-exposed-from-constructor.cs | 27 + .../src/thread-sleep-in-test.cs | 21 + .../src/thread-suspend-resume.cs | 14 + .../src/threadstatic-field-initialized.cs | 15 + .../src/threadstatic-on-instance-field.cs | 13 + .../src/throw-in-finalizer.cs | 18 + .../src/throw-in-finally.cs | 38 + .../codacy-rules-csharp/src/todo-tag.cs | 15 + .../src/too-many-generic-parameters.cs | 16 + .../src/too-many-parameters.cs | 27 + .../src/tostring-returns-null.cs | 28 + .../codacy-rules-csharp/src/trace-write.cs | 23 + .../src/trace-writelineif-with-traceswitch.cs | 17 + .../src/trivial-property.cs | 22 + .../src/type-check-on-this.cs | 17 + .../src/type-name-matches-namespace.cs | 14 + .../src/type-outside-namespace.cs | 18 + .../src/type-parameter-not-inferable.cs | 18 + .../src/type-pascal-case.cs | 17 + .../src/unassigned-field.cs | 16 + .../src/unauthenticated-ldap-connection.cs | 15 + .../src/unchecked-enumerable-sum.cs | 27 + .../unconstrained-generic-null-comparison.cs | 19 + .../src/unix-epoch-created-manually.cs | 15 + .../src/unrestricted-archive-extraction.cs | 18 + .../src/unrestricted-deserialization.cs | 23 + .../src/unsafe-code-block.cs | 21 + .../src/untestable-system-clock.cs | 18 + .../src/unused-local-variable.cs | 26 + .../src/unused-private-method-parameter.cs | 38 + .../src/unused-type-parameter.cs | 20 + .../src/uri-string-parameter.cs | 10 + .../src/uri-string-property.cs | 15 + .../src/uri-string-return-value.cs | 15 + .../src/use-exists-instead-of-any.cs | 17 + .../src/use-find-instead-of-firstordefault.cs | 17 + .../src/use-string-isnullorempty.cs | 13 + .../src/use-trueforall-instead-of-all.cs | 14 + .../src/useless-bitwise-operation.cs | 13 + .../src/useless-increment.cs | 20 + .../src/valuetask-consumed-incorrectly.cs | 25 + .../src/vararg-parameter.cs | 16 + .../src/verbose-declaration.cs | 17 + .../src/virtual-field-like-event.cs | 17 + .../src/visible-pinvoke-method.cs | 13 + .../src/visible-unmanaged-pointer.cs | 12 + .../src/weak-cipher-algorithm.cs | 14 + .../src/weak-cryptographic-key.cs | 17 + .../src/weak-hashing-algorithm.cs | 15 + .../src/weak-password-hashing.cs | 14 + .../src/weak-pseudorandom-number-generator.cs | 17 + .../src/weak-ssl-tls-protocol.cs | 19 + .../src/write-only-property.cs | 21 + .../src/xml-external-entity-processing.cs | 20 + .../src/xml-signature-checked-without-key.cs | 17 + 413 files changed, 22270 insertions(+), 1 deletion(-) create mode 100644 docs/codacy-rules-csharp.yaml create mode 100644 docs/multiple-tests/codacy-rules-csharp-header/patterns.xml create mode 100644 docs/multiple-tests/codacy-rules-csharp-header/results.xml create mode 100644 docs/multiple-tests/codacy-rules-csharp-header/src/missing-copyright-header.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp-header/src/with-block-header.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp-header/src/with-header.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/patterns.xml create mode 100644 docs/multiple-tests/codacy-rules-csharp/results.xml create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/absolute-action-route-template.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/abstract-class-without-implementation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/action-route-without-controller-route.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/action-without-produces-response-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/always-same-math-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/anonymous-delegate-unsubscribe.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/any-with-equality-instead-of-contains.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/api-action-without-http-verb.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/api-controller-derives-from-controller.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/argument-exception-parameter-name.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/array-created-for-params.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/assembly-com-visibility-not-explicit.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/assembly-load-from-path.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/assembly-not-marked-cls-compliant.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/assertion-arguments-order.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/assignment-in-sub-expression.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/async-argument-validation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/async-await-as-identifier.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/async-method-naming.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/async-void-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/attribute-not-sealed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/attribute-without-attribute-usage.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/azure-function-failure-not-logged.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/azure-function-without-error-handling.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/backslash-in-route-template.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/base-equals-reference-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/base-object-equality-call.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/begininvoke-without-endinvoke.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/bitwise-operation-on-non-flags-enum.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/blocking-async-call.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-async-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-azure-function.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/boolean-literal-in-assertion.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/break-outside-switch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/caller-information-parameter-not-last.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/catch-general-exception.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/catch-null-reference-exception.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/catch-only-rethrows.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/caught-exception-not-logged.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/check-before-assign.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/class-owns-disposable-fields.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/class-with-only-private-constructors.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/clear-text-protocol.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/client-created-per-azure-function-invocation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/close-brace-at-line-start.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/collection-element-overwritten.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/collection-passed-to-own-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/collection-property-with-public-setter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/com-security-call-in-managed-code.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/commented-out-code.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/concurrentdictionary-lambda-captures-key.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/condition-always-false.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/condition-always-true.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/conditional-on-same-line-as-brace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/conflicting-transparency-annotations.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/console-output-logging.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/control-character-in-string.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/cookie-without-httponly-flag.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/cookie-without-secure-flag.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/count-used-to-check-emptiness.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/csrf-protection-disabled.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/culture-insensitive-string-operation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/custom-cryptographic-algorithm.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/dangerous-safehandle-access.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/database-connection-without-password.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/datatable-without-locale.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/date-parse-without-format-provider.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/datetime-instead-of-datetimeoffset.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/datetime-now-for-timing.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/datetime-without-kind.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/dead-store.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/debug-feature-enabled.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/default-clause-position.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/default-parameter-value-without-optional.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/default-value-on-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/default-value-passed-explicitly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/deprecated-code.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/derived-type-name-suffix.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/deserialization-without-validation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/disposable-not-disposed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/disposable-without-finalizer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/dispose-does-not-dispose-fields.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/dispose-method-without-idisposable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/disposed-object-returned.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/doubled-prefix-operator.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/duplicate-branch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/duplicate-cast.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/duplicate-condition-in-if-chain.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/duplicate-log-template-placeholder.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/else-if-without-else.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-case-before-default.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-class.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-collection-accessed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-comment.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-default-clause.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-finalizer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-generic-catch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-interface.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-namespace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-nested-block.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/empty-statement.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enum-name-suffix.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enum-naming.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enum-storage-not-int32.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enumerable-first-last-on-linkedlist.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enumerable-method-instead-of-indexing.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/enumerable-min-max-on-sorted-set.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/equality-operator-on-reference-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/equals-without-gethashcode.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/equals-without-iequatable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/event-handler-signature.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/event-never-raised.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exception-created-not-thrown.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exception-missing-standard-constructors.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exception-rethrown-explicitly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exception-thrown-from-unexpected-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/excessive-request-content-length.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exclude-from-coverage-without-justification.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/exit-method-call.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/expected-exception-attribute.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/export-without-implementation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/extension-method-in-same-namespace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/extension-method-on-object.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/field-could-be-readonly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/field-shadows-parent-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/file-too-many-lines.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/fixme-tag.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/flags-enum-invalid-value.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/flags-enum-members-not-initialized.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/flags-zero-member-not-none.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/floating-point-equality.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/for-loop-never-runs.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/for-loop-only-condition.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/for-loop-wrong-direction.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/for-update-not-loop-counter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/format-string-unused-arguments.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/formattablestring-instead-of-string-create.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/gc-collect.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/general-exception-thrown.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/generic-logger-type-mismatch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/get-executing-assembly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/gethashcode-uses-mutable-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/getter-method-could-be-property.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/gettype-on-type-instance.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/goto-statement.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/hardcoded-credentials.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/hardcoded-date-format.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/hardcoded-ip-address.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/hardcoded-jwt-secret.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/hardcoded-uri.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/httpclient-created-per-call.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/icomparable-without-equality-operators.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/identical-branches.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/identical-method-implementations.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/identical-operands.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/iequatable-class-not-sealed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/ignored-return-value.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/ignored-test-without-reason.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/ill-formed-format-string.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/incomplete-assertion.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/inconsistent-operator-overloading.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/incorrect-idisposable-implementation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/increment-in-expression.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/indexof-positive-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/infinite-loop-or-recursion.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/insecure-cipher-mode-or-padding.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/insecure-temporary-file.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/integer-division-to-floating-point.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-dynamic-shift-operand.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-event-arguments.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-log-message-template.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-regular-expression.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-shift-count.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/invalid-test-method-signature.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/inverted-boolean-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/irregular-number-grouping.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/iserializable-incorrect-implementation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/issue-suppression.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/iterator-argument-validation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/jsinvokable-method-not-public.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/jwt-signature-not-verified.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/large-number-without-underscores.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/line-too-long.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/list-in-public-api.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/local-could-be-const.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/local-shadows-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/local-time-recorded.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lock-not-released-on-all-paths.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lock-on-local-variable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lock-on-non-readonly-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lock-on-shared-resource.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lock-on-weak-identity-object.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/log-and-rethrow.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/log-template-argument-order.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/log-template-placeholder-not-pascal-case.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/logger-category-mismatch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/logger-configuration.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/logger-field-not-private-static-readonly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/logger-naming.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/logging-arguments-in-message-arguments.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/loop-could-use-linq.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/loop-counter-modified-in-body.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/loop-with-single-iteration.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/loose-file-permissions.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lowercase-literal-suffix.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/lowercase-string-normalization.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/magic-number.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/manual-timezone-conversion.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/member-more-visible-than-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/mergeable-if-statements.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/mergeable-try-statements.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/method-overloads-not-grouped.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/method-property-pascal-case.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/method-returns-constant.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/misleading-conditional-indentation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-assembly-version.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-configure-await.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-curly-braces.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-final-newline.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-format-provider.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-stathread-on-windows-forms-main.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/missing-string-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/model-state-not-validated.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/modulus-equality-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multiline-block-without-braces.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multiple-declarations-per-line.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multiple-orderby-calls.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/multiple-statements-per-line.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nan-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/native-method-not-wrapped.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nested-code-block.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nested-generic-type-in-signature.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nested-member-shadows-outer-member.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nested-switch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nested-ternary.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-constant-log-template.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-constant-visible-static-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-existent-operator.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-generic-collection.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-generic-event-handler.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-integral-indexer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-private-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-public-exception-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/non-short-circuit-logic.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nonsensical-size-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/not-implemented-exception.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/null-pointer-dereference.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/null-returned-for-collection.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/null-returned-from-task-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nullable-gettype-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/nullable-value-without-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/object-created-and-dropped.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/object-disposed-twice.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/obsolete-without-explanation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/one-way-operation-returns-value.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/operator-without-named-alternative.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/optional-field-without-deserialization-handler.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/optional-on-ref-or-out-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/optional-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/orderby-before-where.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/os-command-from-path.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/out-or-ref-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/outdated-base-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/overlapping-overload-defaults.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/overridable-call-in-constructor.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/override-only-calls-base.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/parameter-name-as-string.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/parameter-name-differs-from-declaration.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/parameter-named-like-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/parameter-overwritten-before-read.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/parameterless-guid-creation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/params-added-on-override.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/part-creation-policy-without-export.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/permissive-cors-policy.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/predictable-initialization-vector.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/predictable-password-salt.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/predictable-secure-random-seed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/private-class-not-sealed.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/property-getter-throws.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/property-name-matches-get-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/property-returns-collection-copy.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/protected-member-in-sealed-class.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/public-constant.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/public-constructor-in-abstract-class.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/public-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/public-static-mutable-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/publicly-writable-directory.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/pure-method-returns-void.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/raw-request-data-in-controller.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/readonly-mutable-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/recursive-type-inheritance.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-anonymous-property-name.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-boolean-literal.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-cast.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-constructor-or-destructor.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-default-initialization.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-double-parentheses.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-inheritance.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-jump.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-member-initializer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-modifier.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-null-check-with-is.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-parentheses-creation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-tochararray.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/redundant-tostring.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/ref-object-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/reference-equals-value-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/reflection-accessibility-bypass.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/regex-without-timeout.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/request-validation-disabled.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/reserved-enum-member.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/same-condition-tested-twice.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/self-assignment.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/serialization-handler-signature.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/server-certificate-validation-disabled.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/service-contract-without-operations.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/setter-ignores-value.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/shared-part-instantiated.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/side-effect-in-debug-assert.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/simplify-conditional.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/simplify-linq-expression.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/simplify-type-check.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/sql-keyword-without-whitespace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/stateful-azure-function.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-constructor-only-initializes-fields.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-field-assigned-in-constructor.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-field-in-generic-type.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-field-initialization-order.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-field-written-from-instance.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/static-readonly-could-be-const.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/stream-read-result-ignored.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/string-concatenation-in-loop.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/string-literal-for-localizable-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/string-overload-for-single-char.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/string-uri-overload-not-delegating.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/stringbuilder-never-read.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/struct-without-iequatable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/substring-before-indexof.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-outside-dispose.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-without-finalizer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/switch-too-few-cases.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/switch-without-default.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/tab-characters.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/temporal-type-as-primary-key.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/test-class-without-tests.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/test-without-assertion.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/this-exposed-from-constructor.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/thread-sleep-in-test.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/thread-suspend-resume.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/threadstatic-field-initialized.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/threadstatic-on-instance-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/throw-in-finalizer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/throw-in-finally.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/todo-tag.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/too-many-generic-parameters.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/too-many-parameters.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/tostring-returns-null.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/trace-write.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/trace-writelineif-with-traceswitch.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/trivial-property.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/type-check-on-this.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/type-name-matches-namespace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/type-outside-namespace.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/type-parameter-not-inferable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/type-pascal-case.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unassigned-field.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unauthenticated-ldap-connection.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unchecked-enumerable-sum.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unconstrained-generic-null-comparison.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unix-epoch-created-manually.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unrestricted-archive-extraction.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unrestricted-deserialization.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unsafe-code-block.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/untestable-system-clock.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unused-local-variable.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unused-private-method-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/unused-type-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/uri-string-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/uri-string-property.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/uri-string-return-value.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/use-exists-instead-of-any.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/use-find-instead-of-firstordefault.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/use-string-isnullorempty.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/use-trueforall-instead-of-all.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/useless-bitwise-operation.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/useless-increment.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/valuetask-consumed-incorrectly.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/vararg-parameter.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/verbose-declaration.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/virtual-field-like-event.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/visible-pinvoke-method.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/visible-unmanaged-pointer.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-cipher-algorithm.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-cryptographic-key.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-hashing-algorithm.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-password-hashing.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-pseudorandom-number-generator.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/weak-ssl-tls-protocol.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/write-only-property.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/xml-external-entity-processing.cs create mode 100644 docs/multiple-tests/codacy-rules-csharp/src/xml-signature-checked-without-key.cs diff --git a/README.md b/README.md index cac04b4..3c31e7f 100755 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This is a **Codacy engine**: a Go wrapper (`cmd/tool`, `internal/tool`, built on The `docs/` directory holds both hand-maintained inputs and generated outputs: -- `docs/codacy-rules.yaml`, `docs/codacy-rules-i18n.yaml`, `docs/codacy-rules-ai.yaml`, `docs/codacy-rules-exotic.yaml` — Codacy's own custom Semgrep-style rules, hand-maintained, merged in alongside the upstream rule sets. +- `docs/codacy-rules.yaml`, `docs/codacy-rules-i18n.yaml`, `docs/codacy-rules-ai.yaml`, `docs/codacy-rules-exotic.yaml`, `docs/codacy-rules-csharp.yaml` — Codacy's own custom Semgrep-style rules, hand-maintained, merged in alongside the upstream rule sets. `codacy-rules-csharp.yaml` holds the C# code quality and security rules (`codacy.csharp..`); each rule has a test file named after it in `docs/multiple-tests/codacy-rules-csharp/src/`, where `// Noncompliant` comments mark the expected findings (the file-level copyright rule is tested separately in `docs/multiple-tests/codacy-rules-csharp-header/`). - `docs/tool-description.md` — short blurb about the tool, hand-maintained. - `docs/patterns.json`, `docs/description/*.json`, `docs/description/*.md`, `docs/rules.yaml`, `docs/semgrep-pro-rules.yaml` — **generated, git-ignored** (see `.gitignore`: "Ignore generated documentation files to avoid licensing issues"). Do not hand-edit and do not expect to see them in `git status`/PR diffs — they're produced fresh on every `go run ./cmd/docgen` and inside the `Dockerfile` build itself. diff --git a/docs/codacy-rules-csharp.yaml b/docs/codacy-rules-csharp.yaml new file mode 100644 index 0000000..ba35db0 --- /dev/null +++ b/docs/codacy-rules-csharp.yaml @@ -0,0 +1,8389 @@ +rules: + - id: codacy.csharp.codestyle.method-property-pascal-case + severity: INFO + languages: + - csharp + message: >- + Rename this method or property to match the PascalCase naming convention. + Shared naming conventions make code easier to read; names containing '_' are + ignored, but leading or trailing underscores are reported. + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $R $NAME(...) { ... } + - pattern: | + $R $NAME(...) => $X; + - pattern-not: | + override $R $NAME(...) { ... } + - pattern-not: | + override $R $NAME(...) => $X; + - focus-metavariable: $NAME + - metavariable-regex: + metavariable: $NAME + regex: '^(?!(?:get|set|init|add|remove)$)(?:_\w*|\w*_|(?!\w*_)(?:[a-z]\w*|\w*[A-Z]{3}\w*|[A-Z]{2}))$' + - pattern-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|static|virtual|abstract|sealed|new|required|readonly|unsafe|extern)\s+)*(?!override\b|return\b|var\b|await\b)[\w.]+(?:<[^\n;=()]*>)?(?:\[[, ]*\])?\??\s+\K(?:_\w*|\w*_|(?!\w*_)(?:[a-z]\w*|\w*[A-Z]{3}\w*|[A-Z]{2}))(?=\s*(?:\{\s*(?:get|set|init|private|protected|internal)\b|=>))' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.type-pascal-case + severity: INFO + languages: + - csharp + message: >- + Rename this type to match the PascalCase naming convention. + Type names should start with an upper case letter, should not contain '_' and + should not contain more than two consecutive upper case letters. + patterns: + - pattern-either: + - pattern: | + class $NAME { ... } + - pattern: | + struct $NAME { ... } + - pattern: | + interface $NAME { ... } + - pattern: | + enum $NAME { ... } + - pattern: | + record $NAME(...); + - pattern: | + record $NAME { ... } + - focus-metavariable: $NAME + - metavariable-regex: + metavariable: $NAME + regex: '^(?:I(?=[A-Z][a-z0-9]))?(?:\w*_\w*|[a-z]\w*|\w*[A-Z]{3}\w*|[A-Z]{2})$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.line-too-long + severity: INFO + languages: + - csharp + message: >- + Split this line, it is longer than 200 characters. + Long lines are hard to read and to review side by side. + pattern-regex: '(?m)^[^\n]{201,}$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.complexity.file-too-many-lines + severity: WARNING + languages: + - csharp + message: >- + Split this file, it has more than 1000 non-blank lines. + Large files tend to aggregate too many responsibilities and become hard to understand and maintain. + pattern-regex: '\A(?:[ \t\r]*\n)*(?:[^\n]*\S[^\n]*\n(?:[ \t\r]*\n)*){1000}[^\n]*\S' + metadata: + category: complexity + confidence: HIGH + - id: codacy.csharp.codestyle.tab-characters + severity: INFO + languages: + - csharp + message: >- + Replace all tab characters in this file by sequences of white-spaces. + Tab width differs between editors and tools, so mixing tabs and spaces breaks the code layout. + pattern-regex: '\A[^\t]*\K\t' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.complexity.too-many-parameters + severity: WARNING + languages: + - csharp + message: >- + Reduce the number of parameters of this method, it has more than 7. + Long parameter lists are hard to use correctly; group related parameters into a type. + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $R $M($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, ...) { ... } + - pattern: | + $R $M($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, ...) => $X; + - pattern: | + $R $M($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, ...); + - focus-metavariable: $M + - patterns: + - pattern: | + class $C { ... $C($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, ...) { ... } ... } + - pattern-not: | + class $C { ... $C($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, ...) : base(...) { ... } ... } + - focus-metavariable: $P1 + metadata: + category: complexity + confidence: HIGH + - id: codacy.csharp.codestyle.mergeable-if-statements + severity: INFO + languages: + - csharp + message: >- + Merge this if statement with the enclosing one. + Nested if statements without else branches can be combined with '&&' to reduce nesting. + patterns: + - pattern-either: + - pattern: | + if ($A) { if ($B) $S; } + - pattern: | + if ($A) if ($B) $S; + - pattern-not: | + if ($A) $X; else $Y; + - pattern-not: | + if ($A) { if ($B) $S; else $T; } + - pattern-not: | + if ($A) if ($B) $S; else $T; + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.close-brace-at-line-start + severity: INFO + languages: + - csharp + message: >- + Move this closing curly brace to the beginning of a new line. + Closing braces placed after code on the same line make the block structure hard to see. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^{}\n"]*[^\s{}][ \t]*\K\}' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.empty-statement + severity: INFO + languages: + - csharp + message: >- + Remove this empty statement. + A stray semicolon does nothing and may hide a mistake, such as a loop or if statement with no body. + pattern-either: + - pattern-regex: '(?m)^(?![^\n]*\bfor\s*\()(?![ \t]*(?://|/?\*))[^\n]*?;[ \t]*\K;' + - pattern-regex: '(?m)^[ \t]*\K;[ \t]*(?://[^\n]*)?$' + - pattern-regex: '(?m)^[ \t]*(?:if|for|foreach)[ \t]*\((?:[^()\n]|\((?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))*\))*\)[ \t]*\K;[ \t]*(?://[^\n]*)?$' + - pattern: while ($C); + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.local-shadows-field + severity: INFO + languages: + - csharp + message: >- + Rename this local variable, it hides a field or property with the same name. + Shadowing a member makes it unclear which one is read or written. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $T $F; ... } + - pattern-inside: | + class $C { ... $T $F = $I; ... } + - pattern-inside: | + class $C { ... $T $F { get; set; } ... } + - pattern-inside: | + class $C { ... $T $F { get; } ... } + - pattern-inside: | + $R $M(...) { ... } + - pattern-not-inside: | + static $R $M(...) { ... } + - pattern-either: + - pattern: $T2 $G = $V; + - pattern: $T2 $G; + - metavariable-comparison: + comparison: str($F) == str($G) + - focus-metavariable: $G + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.best-practice.general-exception-thrown + severity: ERROR + languages: + - csharp + message: >- + Throw a more specific exception type instead of a general or reserved one. + General exceptions such as Exception or ApplicationException cannot be handled selectively, + and reserved exceptions such as NullReferenceException are meant to be thrown by the runtime only. + patterns: + - pattern-either: + - pattern: throw new $E(...); + - pattern: throw new $E(...) { ... }; + - pattern: $X ?? throw new $E(...) + - focus-metavariable: $E + - metavariable-regex: + metavariable: $E + regex: '^(?:System\.)?(?:Exception|SystemException|ApplicationException|IndexOutOfRangeException|NullReferenceException|OutOfMemoryException|ExecutionEngineException)$' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.assignment-in-sub-expression + severity: INFO + languages: + - csharp + message: >- + Extract this assignment from the expression it is nested in. + Assignments hidden inside other expressions are easy to overlook and hurt readability. + patterns: + - pattern-either: + - pattern: $F(..., $X = $Y, ...) + - pattern: $O.$F(..., $X = $Y, ...) + - pattern: return $X = $Y; + - patterns: + - pattern-either: + - pattern: ($X = $Y) == $Z + - pattern: ($X = $Y) != $Z + - pattern: ($X = $Y) > $Z + - pattern: ($X = $Y) < $Z + - pattern: ($X = $Y) >= $Z + - pattern: ($X = $Y) <= $Z + - pattern: $Z && ($X = $Y) + - pattern: ($X = $Y) && $Z + - pattern: $Z || ($X = $Y) + - pattern: ($X = $Y) || $Z + - pattern-not-inside: if ($C) $S; + - pattern-not-inside: while ($C) $S; + - pattern-not-inside: | + do $S; while ($C); + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + $P => { ... } + - pattern-not-inside: | + ($P) => $E + - pattern-not-inside: | + $P => $E + - pattern-not-inside: | + () => $E + - pattern-not-inside: | + () => { ... } + - pattern-not-inside: | + delegate (...) { ... } + - pattern-not-inside: $A ?? ($X = $Y) + - pattern-not-inside: new $T(...) { ... } + - pattern-not-inside: new { ... } + - pattern-not-regex: '(?m)^[ \t]*(?:for|foreach)\s*\([^\n]*$' + - pattern-not-regex: '(?m)^[ \t]*\[[^\n]*\][ \t]*$' + metadata: + category: codestyle + confidence: LOW + - id: codacy.csharp.codestyle.redundant-boolean-literal + severity: INFO + languages: + - csharp + message: >- + Remove this redundant boolean literal. + Comparing a boolean expression to true or false, or combining it with a literal, only adds noise. + pattern-either: + - patterns: + - pattern-either: + - pattern: $X == true + - pattern: $X == false + - pattern: true == $X + - pattern: false == $X + - pattern: $X != true + - pattern: $X != false + - pattern: true != $X + - pattern: false != $X + - pattern-not: (bool? $X) == $L + - pattern-not: (bool? $X) != $L + - pattern-not: $L == (bool? $X) + - pattern-not: $L != (bool? $X) + - pattern: $X || false + - pattern: $X || true + - pattern: false || $X + - pattern: true || $X + - pattern: $X && true + - pattern: $X && false + - pattern: true && $X + - pattern: false && $X + - pattern: "!true" + - pattern: "!false" + - pattern: "$C ? true : $E" + - pattern: "$C ? false : $E" + - pattern: "$C ? $E : true" + - pattern: "$C ? $E : false" + - pattern-regex: '\bfor\s*\([^;\n]*;\s*\Ktrue(?=\s*;)' + options: + constant_propagation: false + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.missing-final-newline + severity: INFO + languages: + - csharp + message: >- + Add a new line at the end of this file. + Some tools and version control systems handle files without a trailing new line poorly. + pattern-regex: '[^\n]\z' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.missing-curly-braces + severity: INFO + languages: + - csharp + message: >- + Add curly braces around the body of this control structure. + Bodies without braces make it easy to add a statement that looks conditional but is not. + pattern-either: + - patterns: + - pattern: while ($C) $S; + - pattern-not: while ($C) { ... } + - patterns: + - pattern: do $S; while ($C); + - pattern-not: do { ... } while ($C); + - pattern-regex: '(?m)^[ \t]*(?:else[ \t]+)?\K(?:if|foreach|for)[ \t]*\((?:[^()\n]|\((?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))*\))*\)(?>[ \t]*(?://[^\n]*)?)(?>(?:\r?\n[ \t]*)?)(?=[^\s{;/])' + - pattern-regex: '(?m)\belse\b(?>[ \t]*(?://[^\n]*)?)(?>(?:\r?\n[ \t]*)?)\K(?!if\b)[^\s{/]' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.multiple-statements-per-line + severity: INFO + languages: + - csharp + message: >- + Move this statement to its own line. + One statement per line makes the code easier to read and to debug. + pattern-either: + - pattern-regex: '(?m)^(?![ \t]*(?://|/?\*|\[))(?![^\n]*\bfor\s*\()(?:[^\n";/]|/(?![/*])|"(?:[^"\\\n]|\\.)*")*;[ \t]+(?!(?:get|set|init|add|remove|private|protected|internal)\b)\K[A-Za-z_@](?:[^\n";]|"(?:[^"\\\n]|\\.)*")*;' + - pattern-regex: '(?m)^[ \t]*(?:else[ \t]+)?(?:if|while|foreach|for|using|lock)\s*\((?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))*\)[ \t]*\K[^\s{/;][^\n]*;' + - pattern-regex: '(?m)\belse[ \t]+\K(?!if\b)[^\s{/][^\n]*;' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.commented-out-code + severity: INFO + languages: + - csharp + message: >- + Remove this commented out code. + Commented out code distracts readers and becomes stale; version control keeps the history. + pattern-regex: '(?m)^[ \t]*//(?!/)[ \t]*\K(?:[\w.\[\]]+(?:\([^\n]*?\))?[ \t]*(?:=|\+=|-=|\+\+|--)[^=\n][^\n]*?;|[\w.<>\[\]]+\([^\n]*?\)[ \t]*;|(?:if|for|foreach|while|switch|catch)[ \t]*\([^\n]*?\)[ \t]*\{?|return\b[^\n]*?;|(?:var|int|string|bool|long|double|object)[ \t]+\w+[^\n]*?;|[{}])[ \t]*(?://[^\n]*)?$' + metadata: + category: codestyle + confidence: LOW + - id: codacy.csharp.best-practice.else-if-without-else + severity: INFO + languages: + - csharp + message: >- + Add a final else clause to this if-else-if chain. + A closing else clause documents that every remaining case has been considered, even if it only throws or logs. + patterns: + - pattern: if ($A) $B; else if ($C) $D; + - pattern-not: if ($A) $B; else if ($C) $D; else $E; + - focus-metavariable: $C + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.for-loop-only-condition + severity: INFO + languages: + - csharp + message: >- + Replace this for loop with a while loop. + A for loop with neither initializer nor increment is a while loop in disguise. + pattern: for (; $C; ) $S; + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.switch-too-few-cases + severity: INFO + languages: + - csharp + message: >- + Replace this switch with an if statement or a conditional expression, it has fewer than 3 clauses. + A switch with only one or two branches is harder to read than the equivalent if statement. + pattern-either: + - pattern-regex: '(?m)^([ \t]*)(?:[^\n]*[^\w\n])?\Kswitch[ \t]*\([^\n]*?\)[ \t]*(?://[^\n]*)?\r?\n\1\{[ \t]*\r?\n(?:(?!\1\})(?![^\n]*\b(?:case\b|default[ \t]*:))[^\n]*\n)*(?:(?!\1\})[^\n]*\b(?:case\b|default[ \t]*:)[^\n]*\n(?:(?!\1\})(?![^\n]*\b(?:case\b|default[ \t]*:))[^\n]*\n)*){1,2}\1\}' + - pattern-regex: '\bswitch[ \t]*(?://[^\n]*)?\r?\n?[ \t]*\{(?:[^{}=,;]|=(?!>))*=>[^,{}]*(?:,(?:[^{}=,;]|=(?!>))*=>[^,{}]*)?,?\s*\}' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.correctness.switch-without-default + severity: ERROR + languages: + - csharp + message: >- + Add a default clause to this switch statement. + A default clause is defensive programming: it handles values that were not anticipated, such as a newly added enum member. + patterns: + - pattern: | + switch ($X) { case $A: ... } + - pattern-not: | + switch ($X) { case $A: ... default: ... } + - pattern-not: | + switch ($X) { case $A: ... case $B: default: ... } + - pattern-not: | + switch ($X) { case $A: default: ... } + metadata: + category: correctness + cwe: "CWE-478: Missing Default Case in Multiple Condition Expression" + confidence: MEDIUM + - id: codacy.csharp.best-practice.issue-suppression + severity: WARNING + languages: + - csharp + message: >- + Make sure this issue suppression is justified. + Suppressed warnings hide potential problems and should be reviewed regularly. + pattern-either: + - pattern-regex: '\[[ \t]*(?:assembly:[ \t]*|module:[ \t]*)?(?:[\w.]+\.)?\KSuppressMessage(?:Attribute)?\b' + - pattern-regex: '(?m)^[ \t]*\K#pragma[ \t]+warning[ \t]+disable\b' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.missing-copyright-header + severity: INFO + languages: + - csharp + message: >- + Add a copyright and license header to this file. + Each source file should state its copyright and license so that its terms of use are clear. + pattern-regex: '\A(?!(?:\s*//[^\n]*\n)*?\s*//[^\n]*(?i:copyright|licen[cs]e|spdx)|\s*/\*(?:(?!\*/)[\s\S])*?(?i:copyright|licen[cs]e|spdx))\s*\K[^\s][^\n]*' + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.codestyle.multiple-declarations-per-line + severity: INFO + languages: + - csharp + message: >- + Declare each variable or field on its own line. + Separate declarations are easier to read, comment and change. + pattern: $T $A, $B; + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.enum-naming + severity: INFO + languages: + - csharp + message: >- + Rename this enumeration to match the naming convention. + Enumeration names should be PascalCase; [Flags] enumerations should use a plural name and other enumerations a singular one. + pattern-either: + - patterns: + - pattern-either: + - pattern: | + [Flags] + enum $E { ... } + - pattern: | + [FlagsAttribute] + enum $E { ... } + - pattern: | + [System.Flags] + enum $E { ... } + - focus-metavariable: $E + - metavariable-regex: + metavariable: $E + regex: '^(?!(?:[A-Z]{1,3}[a-z0-9]+)*(?:[A-Z]{2})?s$)' + - patterns: + - pattern: | + enum $E { ... } + - pattern-not: | + [Flags] + enum $E { ... } + - pattern-not: | + [FlagsAttribute] + enum $E { ... } + - pattern-not: | + [System.Flags] + enum $E { ... } + - focus-metavariable: $E + - metavariable-regex: + metavariable: $E + regex: '^(?!(?:[A-Z]{1,3}[a-z0-9]+)*(?:[A-Z]{2})?$)' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.enum-name-suffix + severity: INFO + languages: + - csharp + message: >- + Rename this enumeration to remove the 'Flags' or 'Enum' suffix. + The suffix repeats information that the type declaration already carries. + patterns: + - pattern: | + enum $E { ... } + - focus-metavariable: $E + - metavariable-regex: + metavariable: $E + regex: '.*(?:Flags|Enum)$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.comprehensibility.parameter-named-like-method + severity: INFO + languages: + - csharp + message: >- + Rename this parameter, it has the same name as its method. + A parameter named like its method is confusing for readers and callers. + pattern-regex: '(?m)\b(\w+)[ \t]*\((?:[^()\n]*,)?[ \t]*(?:(?:ref|out|in|params|this)[ \t]+)?[\w.]+(?:<[^()\n]*?>)?(?:\[[, ]*\])?\??[ \t]+\K(?i:\1)(?=[ \t]*[,)=])' + metadata: + category: comprehensibility + confidence: MEDIUM + - id: codacy.csharp.best-practice.async-await-as-identifier + severity: INFO + languages: + - csharp + message: >- + Rename this identifier, 'async' and 'await' should not be used as identifiers. + They are contextual keywords and using them as names makes the code confusing. + pattern-regex: '(?m)(?)?(?:\[[, ]*\])?\??[ \t]+\K(?:async|await)(?=[ \t]*(?:=(?!=)|;|,|\)))' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.async-method-naming + severity: INFO + languages: + - csharp + message: >- + Rename this method so that its 'Async' suffix matches whether it returns an awaitable type. + Methods returning Task or ValueTask should end with 'Async', and other methods should not. + pattern-either: + - patterns: + - pattern-either: + - pattern: | + Task $M(...) { ... } + - pattern: | + Task<$T> $M(...) { ... } + - pattern: | + ValueTask $M(...) { ... } + - pattern: | + ValueTask<$T> $M(...) { ... } + - pattern: | + Task $M(...) => $X; + - pattern: | + Task<$T> $M(...) => $X; + - pattern: | + Task $M(...); + - pattern: | + Task<$T> $M(...); + - pattern-not: | + override $R $M(...) { ... } + - pattern-not: | + override $R $M(...) => $X; + - focus-metavariable: $M + - metavariable-regex: + metavariable: $M + regex: '^(?!Main$)(?!.*Async$)' + - patterns: + - pattern-either: + - pattern: | + $R $M(...) { ... } + - pattern: | + $R $M(...) => $X; + - pattern: | + void $M(...) { ... } + - pattern-not: | + override $R $M(...) { ... } + - pattern-not: | + override void $M(...) { ... } + - metavariable-regex: + metavariable: $R + regex: '^(?!(?:System\.Threading\.Tasks\.)?(?:Task|ValueTask)\b|IAsync)' + - focus-metavariable: $M + - metavariable-regex: + metavariable: $M + regex: '.*Async$' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.logger-naming + severity: INFO + languages: + - csharp + message: >- + Rename this logger field or property to match the naming convention '^_?[Ll]og(ger)?$'. + Consistent logger names make logging calls easy to find. + patterns: + - pattern-either: + - pattern: | + class $C { ... ILogger $L; ... } + - pattern: | + class $C { ... ILogger<$T> $L; ... } + - pattern: | + class $C { ... ILog $L; ... } + - pattern: | + class $C { ... Logger $L; ... } + - pattern: | + class $C { ... ILogger $L = $V; ... } + - pattern: | + class $C { ... ILog $L = $V; ... } + - pattern: | + class $C { ... Logger $L = $V; ... } + - pattern: | + class $C { ... ILogger $L { get; set; } ... } + - pattern: | + class $C { ... ILogger $L { get; } ... } + - focus-metavariable: $L + - metavariable-regex: + metavariable: $L + regex: '^(?!_?[Ll]og(?:ger)?$)' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.type-name-matches-namespace + severity: WARNING + languages: + - csharp + message: >- + Rename this type, its name collides with a well-known namespace. + A type named like a namespace forces callers to use fully qualified names to disambiguate. + patterns: + - pattern-either: + - pattern: | + public class $C { ... } + - pattern: | + public interface $C { ... } + - pattern: | + public struct $C { ... } + - pattern: | + public enum $C { ... } + - focus-metavariable: $C + - metavariable-regex: + metavariable: $C + regex: '^(?:System|Collections|Generic|Concurrent|ObjectModel|Specialized|IO|Text|RegularExpressions|Linq|Net|Http|Sockets|Threading|Tasks|Reflection|Runtime|InteropServices|Serialization|Security|Cryptography|Principal|Data|Xml|Diagnostics|Globalization|Resources|ComponentModel|Configuration|Drawing|Windows|Forms|Web|Json|Buffers|Numerics|Timers|Transactions)$' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.derived-type-name-suffix + severity: INFO + languages: + - csharp + message: >- + Rename this class so that it ends with the suffix of its base type: 'Attribute', 'EventArgs' or 'Exception'. + Following this .NET convention lets readers recognize these types by their name. + patterns: + - pattern-either: + - pattern: | + class $C : $B { ... } + - pattern: | + class $C : $B, $I { ... } + - pattern: | + class $C : $B, $I, $J { ... } + - metavariable-regex: + metavariable: $B + regex: '.*(?:Exception|Attribute|EventArgs)$' + - metavariable-comparison: + comparison: not re.match(".*(Exception|Attribute|EventArgs)$", str($C)) + - focus-metavariable: $C + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.lowercase-literal-suffix + severity: INFO + languages: + - csharp + message: >- + Use an upper case 'L' suffix for this numeric literal. + A lower case 'l' is easily confused with the digit '1'. + patterns: + - pattern: $N + - metavariable-regex: + metavariable: $N + regex: '^(?:0[xX][\da-fA-F_]+|0[bB][01_]+|\d[\d_]*)(?:l|ul|Ul|lu|lU)$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.large-number-without-underscores + severity: INFO + languages: + - csharp + message: >- + Add underscores to this numeric literal to make it readable. + Digit separators make large numbers, such as 10_000_000, much easier to read. + patterns: + - pattern: $N + - metavariable-regex: + metavariable: $N + regex: '^(?:\d{6,}(?:\.\d+)?|0[xX][\da-fA-F]{9,}|0[bB][01]{9,})(?:[uU]?[lL]?|[lL][uU]|[fFdDmM])$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.irregular-number-grouping + severity: INFO + languages: + - csharp + message: >- + Group the digits of this numeric literal regularly. + Irregular digit groups, such as 100_00, are misleading; use groups of equal size after the first one. + patterns: + - pattern: $N + - metavariable-regex: + metavariable: $N + regex: '^(?!(?:0[xXbB])?(?:[\da-fA-F]{1,2}(?:_[\da-fA-F]{2})+|[\da-fA-F]{1,3}(?:_[\da-fA-F]{3})+|[\da-fA-F]{1,4}(?:_[\da-fA-F]{4})+|[\da-fA-F]{1,8}(?:_[\da-fA-F]{8})+)(?:\.\d+)?(?:[uU]?[lL]?|[lL][uU]|[fFdDmM])$)(?:0[xXbB])?[\da-fA-F]+(?:_[\da-fA-F]+)+(?:\.\d+)?(?:[uU]?[lL]?|[lL][uU]|[fFdDmM])$' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.conditional-on-same-line-as-brace + severity: INFO + languages: + - csharp + message: >- + Move this if statement to a new line or add the missing 'else'. + An if that starts on the same line as the closing brace of a previous block looks like an 'else if'. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^\n"]*\}[ \t]*\Kif[ \t]*\(' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.correctness.misleading-conditional-indentation + severity: INFO + languages: + - csharp + message: >- + Indent the statement controlled by this conditional, or enclose it in curly braces. + A conditionally executed statement aligned with its condition looks like it always runs. + pattern-regex: '(?m)^([ \t]*)\K(?:(?:else[ \t]+)?if|while|for|foreach)\b[^\n{;]*\)[ \t]*(?://[^\n]*)?\r?\n\1(?![ \t]|\{|//|/\*)\S' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.multiline-block-without-braces + severity: ERROR + languages: + - csharp + message: >- + Add curly braces, only the first statement after this conditional is part of its body. + The indentation suggests that the following statement is also conditional, but it always runs. + pattern-either: + - pattern-regex: '(?m)^([ \t]*)(?:(?:else[ \t]+)?if|while|for|foreach)\b[^\n{;]*\)[ \t]*(?://[^\n]*)?\r?\n\1([ \t]+)[^\s{}/][^\n]*;[ \t]*(?://[^\n]*)?\r?\n\1\2\K(?![ \t])[^\s{}/]' + - pattern-regex: '(?m)^[ \t]*(?:(?:else[ \t]+)?if|while|for|foreach)[ \t]*\((?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))*\)[ \t]*[^\s{;/][^\n;]*;[ \t]*\K[A-Za-z_][^\n;]*;' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.codestyle.goto-statement + severity: INFO + languages: + - csharp + message: >- + Remove this 'goto' statement. + 'goto' makes the control flow hard to follow; use structured statements instead. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^\n"]*?\K\bgoto[ \t]+(?:case\b|default\b|\w+)[^\n;]*;' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.comprehensibility.empty-comment + severity: INFO + languages: + - csharp + message: >- + Remove this empty comment. + Empty comments add visual clutter without conveying any information. + pattern-either: + - pattern-regex: '(?m)(?:\A|^(?![ \t]*//)[^\n]*\n)[ \t]*\K//[ \t]*\r?$(?!\n[ \t]*//)' + - pattern-regex: '/\*[\s*]*\*/' + metadata: + category: comprehensibility + confidence: HIGH + - id: codacy.csharp.best-practice.fixme-tag + severity: WARNING + languages: + - csharp + message: >- + Take the required action to fix the issue indicated by this 'FIXME' comment. + FIXME tags mark known problems that should not be forgotten. + pattern-regex: '(?m)(?://|/\*|^[ \t]*\*)[^\n]*?\K\b(?i:fixme)\b' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.todo-tag + severity: WARNING + languages: + - csharp + message: >- + Complete the task associated to this 'TODO' comment. + TODO tags mark unfinished work that should be tracked and completed. + pattern-regex: '(?m)(?://|/\*|^[ \t]*\*)[^\n]*?\K\b(?i:todo)\b' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-parentheses-creation + severity: INFO + languages: + - csharp + message: >- + Remove these redundant empty parentheses. + Empty parentheses are not needed on attributes without arguments or on object creations followed by an initializer. + pattern-either: + - pattern-regex: '(?m)^[ \t]*\[(?:(?:assembly|module|return|field|property|method|param|type):[ \t]*)?(?:[\w.]+(?:\([^()\]\n]*\))?[ \t]*,[ \t]*)*[\w.]+\K\([ \t]*\)(?=[ \t]*[,\]])' + - pattern-regex: '\bnew[ \t]+[A-Za-z_][\w.]*(?:<[^()\n;]*?>)?\K\([ \t]*\)(?=\s*(?://[^\n]*\s*)?\{)' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.verbose-declaration + severity: INFO + languages: + - csharp + message: >- + Remove the redundant parts of this declaration or initialization. + Empty initializers, explicit array sizes next to initializers and explicit nullable creations can be inferred by the compiler. + pattern-either: + - pattern-regex: '\bnew[ \t]+[A-Za-z_][\w.]*(?:<[^()\n;]*?>)?(?:\([^()\n]*\))?[ \t]*\K\{[ \t]*\}' + - pattern-regex: '\bnew[ \t]+[A-Za-z_][\w.]*[ \t]*\K\[[ \t]*\d+[ \t]*\](?=\s*\{)' + - pattern-regex: '\bnew[ \t]+\K(?:[A-Za-z_][\w.]*\?|Nullable<[^>\n]+>)(?=[ \t]*\()' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.redundant-anonymous-property-name + severity: INFO + languages: + - csharp + message: >- + Remove the redundant property name in this anonymous type. + The name is inferred from the variable or member used to initialize the property. + patterns: + - pattern-either: + - pattern: "new { ..., $X = $Y, ... }" + - pattern: "new { ..., $X = $O.$Y, ... }" + - metavariable-comparison: + comparison: str($X) == str($Y) + - focus-metavariable: $X + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-default-initialization + severity: INFO + languages: + - csharp + message: >- + Remove this initialization to the default value, the compiler already does it. + Explicitly initializing fields, auto-properties or events to their default value only adds noise. + pattern-either: + - patterns: + - pattern-inside: | + class $C { ... } + - pattern-not-inside: | + $R $M(...) { ... } + - pattern-not-inside: | + $R $M(...) => $E; + - pattern-either: + - patterns: + - pattern: $T $F = $V; + - metavariable-regex: + metavariable: $T + regex: '^(?:sbyte|byte|short|ushort|int|uint|long|ulong|nint|nuint|float|double|decimal|char|Int16|Int32|Int64|UInt16|UInt32|UInt64|Single|Double|Decimal)$' + - metavariable-regex: + metavariable: $V + regex: '^(?:0+(?:\.0*)?(?:[uUlLfFdDmM]{1,2})?|0[xX]0+|''\\0'')$' + - pattern: bool $F = false; + - pattern: $T $F = null; + - pattern: $T $F = default; + - pattern: $T $F = default($X); + - pattern-not: const $T $F = $V; + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.empty-case-before-default + severity: INFO + languages: + - csharp + message: >- + Remove this empty case clause, it falls through to the default clause. + Empty cases that fall through to 'default' do not change the behavior. + pattern-regex: '(?m)^[ \t]*\Kcase\b[^:\n]*:(?=[ \t]*(?://[^\n]*)?(?:\r?\n[ \t]*case\b[^:\n]*:[ \t]*(?://[^\n]*)?)*\r?\n[ \t]*default[ \t]*:)' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.empty-default-clause + severity: INFO + languages: + - csharp + message: >- + Remove this empty 'default' clause. + A default clause that only breaks does nothing. + pattern-regex: '(?m)^[ \t]*\Kdefault[ \t]*:\s*break[ \t]*;' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-jump + severity: INFO + languages: + - csharp + message: >- + Remove this redundant jump statement. + A 'return' at the end of a void method, a 'continue' at the end of a loop or a 'goto' to the next statement change nothing. + pattern-either: + - patterns: + - pattern: return; + - pattern-inside: | + void $M(...) { ... } + - pattern-not-inside: if ($C) $S; + - pattern-not-inside: while ($C) $S; + - pattern-not-inside: do $S; while ($C); + - pattern-not-inside: for ($T $I = $X; $C; $U) $S; + - pattern-not-inside: foreach ($T $V in $E) $S; + - pattern-not-inside: foreach (var $V in $E) $S; + - pattern-not-inside: | + switch ($X) { case $A: ... } + - pattern-not-inside: | + try { ... } + - pattern-not-inside: | + using (...) { ... } + - pattern-not-inside: | + lock ($L) { ... } + - pattern-not-inside: | + () => { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + $P => { ... } + - pattern-not-inside: | + delegate (...) { ... } + - pattern-not-inside: | + return; + ... + $S; + - pattern-regex: '\breturn[ \t]*;(?=[ \t]*(?://[^\n]*)?\s*\}[ \t]*(?://[^\n]*)?\r?\n)' + - patterns: + - pattern-either: + - pattern: while ($C) $BODY + - pattern: foreach ($T $V in $E) $BODY + - pattern: foreach (var $V in $E) $BODY + - pattern: for ($T $I = $X; $C; $U) $BODY + - metavariable-regex: + metavariable: $BODY + regex: '(?s)^\{.*\n[ \t]*continue[ \t]*;[ \t]*(?://[^\n]*)?\s*\}\z' + - pattern-regex: '\bcontinue[ \t]*;(?=[ \t]*(?://[^\n]*)?\s*\})' + - pattern-regex: '\bgoto[ \t]+(\w+)[ \t]*;(?:[ \t]*//[^\n]*)?\s*\1[ \t]*:' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.default-clause-position + severity: INFO + languages: + - csharp + message: >- + Move this default clause to the beginning or the end of the switch statement. + A default clause in the middle of the cases is easy to miss. + pattern-regex: '(?m)^([ \t]*)case\b[^\n]*\n(?:(?:\1[ \t]+[^\n]*|[ \t]*|\1case\b[^\n]*)\n)*\1\Kdefault[ \t]*:[^\n]*\n(?:(?:\1[ \t]+[^\n]*|[ \t]*)\n)*\1case\b' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.inverted-boolean-check + severity: INFO + languages: + - csharp + message: >- + Use the opposite operator instead of negating this comparison. + Writing '!(a == b)' instead of 'a != b' makes the condition harder to read. + pattern-either: + - pattern: "!($A == $B)" + - pattern: "!($A != $B)" + - pattern: "!($A < $B)" + - pattern: "!($A > $B)" + - pattern: "!($A <= $B)" + - pattern: "!($A >= $B)" + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-modifier + severity: INFO + languages: + - csharp + message: >- + Remove this redundant modifier. + 'sealed' members of sealed classes and 'checked' or 'unchecked' blocks without integral arithmetic have no effect. + pattern-either: + - patterns: + - pattern-either: + - pattern: | + sealed class $C { ... sealed override $R $M(...) { ... } ... } + - pattern: | + sealed class $C { ... sealed override $R $M(...) => $E; ... } + - focus-metavariable: $M + - pattern-regex: '\b(?:un)?checked[ \t]*(?://[^\n]*)?\s*\{(?![^{}]*(?:\+|-|\*|/|%|<<|>>))[^{}]*\}' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.trivial-property + severity: INFO + languages: + - csharp + message: >- + Make this an auto-implemented property and remove its backing field. + A property that only reads and writes a field adds boilerplate without adding behavior. + patterns: + - pattern-either: + - pattern: | + class $C { ... $FT $F; ... $T $P { get { return $F; } set { $F = value; } } ... } + - pattern: | + class $C { ... $FT $F; ... $T $P { get => $F; set => $F = value; } ... } + - pattern: | + class $C { ... $T $P { get { return $F; } set { $F = value; } } ... $FT $F; ... } + - pattern: | + class $C { ... $T $P { get => $F; set => $F = value; } ... $FT $F; ... } + - focus-metavariable: $P + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.simplify-conditional + severity: INFO + languages: + - csharp + message: >- + Simplify this conditional using '??', '??=' or the conditional operator. + The shorter syntax expresses the same logic with less code. + pattern-either: + - pattern: | + if ($A != null) { $X = $A; } else { $X = $B; } + - pattern: | + if ($A == null) { $X = $B; } else { $X = $A; } + - pattern: | + if ($C) { $X = $A; } else { $X = $B; } + - pattern: | + if ($C) $X = $A; else $X = $B; + - pattern: "$A != null ? $A : $B" + - pattern: "$A == null ? $B : $A" + - pattern: "null != $A ? $A : $B" + - pattern: "null == $A ? $B : $A" + - pattern: null ?? $B + - pattern: $A = $A ?? $B + - patterns: + - pattern-either: + - pattern: | + if ($A == null) { $A = $B; } + - pattern: | + if ($A == null) $A = $B; + - pattern: | + if (null == $A) { $A = $B; } + - pattern-not: if ($A == null) $S; else $E; + - pattern-not: if (null == $A) $S; else $E; + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-constructor-or-destructor + severity: INFO + languages: + - csharp + message: >- + Remove this redundant constructor, destructor or base constructor call. + The compiler generates a public parameterless constructor and calls the base parameterless constructor automatically, and empty static constructors and destructors are useless. + pattern-either: + - patterns: + - pattern-inside: | + class $C { ... public $C() { } ... } + - pattern-not-inside: | + class $C { ... $C($P, ...) { ... } ... } + - pattern-not-inside: | + class $C { ... $C($P, ...) : base(...) { ... } ... } + - pattern-not-inside: | + class $C { ... $C($P, ...) : this(...) { ... } ... } + - pattern-regex: 'public[ \t]+\w+[ \t]*\([ \t]*\)[ \t]*\{\s*\}' + - pattern-regex: '(?m)^[ \t]*\Kstatic[ \t]+\w+[ \t]*\([ \t]*\)[ \t]*\{\s*\}' + - pattern-regex: '(?m)^[ \t]*\K~\w+[ \t]*\([ \t]*\)[ \t]*\{\s*\}' + - pattern-regex: '\)[ \t]*(?:\r?\n[ \t]*)?:[ \t]*\Kbase[ \t]*\([ \t]*\)' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.correctness.throw-in-finalizer + severity: ERROR + languages: + - csharp + message: >- + Remove this 'throw' statement from the finalizer. + An exception thrown from a finalizer terminates the process and prevents other finalizers from running. + patterns: + - pattern-either: + - pattern: throw $E; + - pattern: throw; + - pattern-regex: '~\w+[ \t]*\([ \t]*\)\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.throw-in-finally + severity: ERROR + languages: + - csharp + message: >- + Remove this 'throw' statement from the finally block. + An exception thrown from a finally block replaces and hides any exception thrown in the try or catch blocks. + patterns: + - pattern: throw $E; + - pattern-regex: '\bfinally\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + - pattern-not-inside: | + try { ... } catch ($T $V) { ... } + - pattern-not-inside: | + try { ... } catch { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + $P => { ... } + - pattern-not-inside: | + () => { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.equals-without-gethashcode + severity: ERROR + languages: + - csharp + message: >- + Override both Equals(object) and GetHashCode(), or neither of them. + Objects that are equal must have the same hash code, otherwise hash-based collections such as Dictionary and HashSet behave incorrectly. + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + class $C { ... override bool Equals($T $O) { ... } ... } + - pattern: | + class $C { ... override bool Equals($T $O) => $E; ... } + - pattern: | + struct $C { ... override bool Equals($T $O) { ... } ... } + - pattern: | + struct $C { ... override bool Equals($T $O) => $E; ... } + - pattern-not: | + class $C { ... override int GetHashCode() { ... } ... } + - pattern-not: | + class $C { ... override int GetHashCode() => $H; ... } + - pattern-not: | + struct $C { ... override int GetHashCode() { ... } ... } + - pattern-not: | + struct $C { ... override int GetHashCode() => $H; ... } + - patterns: + - pattern-either: + - pattern: | + class $C { ... override int GetHashCode() { ... } ... } + - pattern: | + class $C { ... override int GetHashCode() => $H; ... } + - pattern: | + struct $C { ... override int GetHashCode() { ... } ... } + - pattern: | + struct $C { ... override int GetHashCode() => $H; ... } + - pattern-not: | + class $C { ... override bool Equals($T $O) { ... } ... } + - pattern-not: | + class $C { ... override bool Equals($T $O) => $E; ... } + - pattern-not: | + struct $C { ... override bool Equals($T $O) { ... } ... } + - pattern-not: | + struct $C { ... override bool Equals($T $O) => $E; ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.icomparable-without-equality-operators + severity: ERROR + languages: + - csharp + message: >- + Override Equals(object) and the comparison operators in this IComparable implementation. + Types that define an ordering are expected to behave consistently with Equals and with the ==, !=, <, <=, > and >= operators. + pattern-either: + - patterns: + - pattern-regex: '\b(?:class|struct)\s+\K\w+(?=[^{;]*:[^{;]*\bIComparable\b)' + - pattern-not-inside: | + class $C { ... override bool Equals($T $O) { ... } ... } + - pattern-not-inside: | + class $C { ... override bool Equals($T $O) => $E; ... } + - pattern-not-inside: | + struct $C { ... override bool Equals($T $O) { ... } ... } + - pattern-not-inside: | + struct $C { ... override bool Equals($T $O) => $E; ... } + - patterns: + - pattern-regex: '\b(?:class|struct)\s+\K\w+(?=[^{;]*:[^{;]*\bIComparable\b)' + - pattern-not-inside: | + class $C { ... static bool operator <($A $X, $B $Y) { ... } ... } + - pattern-not-inside: | + class $C { ... static bool operator <($A $X, $B $Y) => $E; ... } + - pattern-not-inside: | + struct $C { ... static bool operator <($A $X, $B $Y) { ... } ... } + - pattern-not-inside: | + struct $C { ... static bool operator <($A $X, $B $Y) => $E; ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.parameter-overwritten-before-read + severity: WARNING + languages: + - csharp + message: >- + Read the initial value of this parameter or caught exception before overwriting it. + Overwriting a parameter before it is read discards the value passed by the caller and is likely a bug. + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $R $M(..., $T $P, ...) { $P = $X; ... } + - pattern-inside: | + $M(..., $T $P, ...) { $P = $X; ... } + - pattern: $P = $X; + - pattern-not-inside: | + $R $M(..., out $T $P, ...) { ... } + - pattern-not-inside: | + $R $M(..., ref $T $P, ...) { ... } + - pattern-not: $P = <... $P ...>; + - patterns: + - pattern-inside: | + try { ... } catch ($T $P) { $P = $X; ... } + - pattern: $P = $X; + - pattern-not: $P = <... $P ...>; + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.floating-point-equality + severity: ERROR + languages: + - csharp + message: >- + Do not check floating point values for equality with '==' or '!='. + Floating point arithmetic is imprecise; compare the absolute difference with a tolerance instead. + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: $A == $B + - pattern: $A != $B + - metavariable-type: + metavariable: $A + types: [float, double] + - patterns: + - pattern-either: + - pattern: $A == $B + - pattern: $A != $B + - metavariable-type: + metavariable: $B + types: [float, double] + - patterns: + - pattern-either: + - pattern: $A == $B + - pattern: $A != $B + - metavariable-regex: + metavariable: $A + regex: '^-?(?:\d+\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[fFdD])$' + - patterns: + - pattern-either: + - pattern: $A == $B + - pattern: $A != $B + - metavariable-regex: + metavariable: $B + regex: '^-?(?:\d+\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[fFdD])$' + - metavariable-comparison: + comparison: str($A) != str($B) + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.loop-counter-modified-in-body + severity: WARNING + languages: + - csharp + message: >- + Do not update the loop counter inside the body of this for loop. + A for loop whose counter is also changed in its body is hard to understand and its stop condition is no longer invariant. + patterns: + - pattern-inside: for ($T $I = $X; $C; $U) $BODY + - pattern-either: + - pattern: $I = $V + - pattern: $I += $V + - pattern: $I -= $V + - pattern: $I++ + - pattern: $I-- + - pattern: ++$I + - pattern: --$I + - pattern-not-regex: '(?m)^[ \t]*for[ \t]*\([^\n]*' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.self-assignment + severity: WARNING + languages: + - csharp + message: >- + Remove or correct this useless self-assignment. + Assigning a variable to itself has no effect and usually hides a mistake, such as a missing 'this.'. + pattern: $X = $X; + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.catch-null-reference-exception + severity: ERROR + languages: + - csharp + message: >- + Do not catch NullReferenceException; test for null instead. + Catching it hides programming errors and is much slower than a null check. + pattern-regex: '\bcatch[ \t]*\([ \t]*(?:System\.)?\KNullReferenceException\b' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.overridable-call-in-constructor + severity: ERROR + languages: + - csharp + message: >- + Do not call overridable methods from a constructor. + An override runs before the derived class constructor has initialized its state, which can lead to unexpected behavior. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... virtual $R $M(...) { ... } ... } + - pattern-inside: | + class $C { ... virtual $R $M(...) => $E; ... } + - pattern-inside: | + class $C { ... abstract $R $M(...); ... } + - pattern-not-inside: | + sealed class $C { ... } + - pattern-either: + - pattern: $M(...) + - pattern: this.$M(...) + - pattern-regex: '(?m)^[ \t]*(?:(?:public|protected|internal|private)[ \t]+)*(?!(?:if|while|for|foreach|switch|catch|using|lock|fixed|return|new|else)\b)[A-Z]\w*[ \t]*\((?:[^()]|\([^()]*\))*\)\s*(?::\s*(?:base|this)\s*\((?:[^()]|\([^()]*\))*\)\s*)?\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.best-practice.loop-with-single-iteration + severity: WARNING + languages: + - csharp + message: >- + Refactor this loop, it executes at most once. + A loop body that always ends with an unconditional break, return or throw is a disguised if statement. + patterns: + - pattern-either: + - pattern: while ($C) $BODY + - pattern: foreach ($T $V in $E) $BODY + - pattern: foreach (var $V in $E) $BODY + - pattern: for ($T $I = $X; $C; $U) $BODY + - metavariable-regex: + metavariable: $BODY + regex: '(?s)^\{(?!.*\bcontinue\b).*\n[ \t]*(?:break|return\b[^;\n]*|throw\b[^;\n]*)[ \t]*;[ \t]*(?://[^\n]*)?\s*\}\z' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.correctness.identical-operands + severity: WARNING + languages: + - csharp + message: >- + Correct one of the identical expressions on both sides of this operator. + Using the same expression on both sides of a comparison or logical operator is either useless or a copy-paste mistake. + pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern: $X < $X + - pattern: $X > $X + - pattern: $X <= $X + - pattern: $X >= $X + - pattern: $X && $X + - pattern: $X || $X + - pattern: $X & $X + - pattern: $X | $X + - pattern: $X ^ $X + - pattern: $X - $X + - pattern: $X / $X + - pattern: $X % $X + - pattern: $X.Equals($X) + - pattern: object.Equals($X, $X) + - pattern: ReferenceEquals($X, $X) + - pattern: object.ReferenceEquals($X, $X) + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.object-created-and-dropped + severity: ERROR + languages: + - csharp + message: >- + Either remove this useless object instantiation or use the created object. + Creating an object without using it is wasteful and often hides a missing assignment or a missing 'throw'. + patterns: + - pattern: new $T(...); + - pattern-not-inside: $V = $E; + - pattern-not-inside: $TY $V = $E; + - pattern-not-inside: var $V = $E; + - pattern-not-inside: return $E; + - pattern-not-inside: throw $E; + - pattern-not-inside: $F(...); + - pattern-not-inside: $O.$F(...); + - pattern-not-regex: '=>\s*new\b[^;]*;' + - pattern-not-inside: ($P) => $E + - pattern-not-inside: $P => $E + - pattern-not-inside: () => $E + options: + implicit_deep_exprstmt: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.performance.dead-store + severity: WARNING + languages: + - csharp + message: >- + Remove this useless assignment, the value is overwritten before it is read. + Dead stores waste computation and often indicate a logic error. + patterns: + - pattern-either: + - pattern: | + $T $X = $A; + $X = $B; + - patterns: + - pattern: | + $X = $A; + $X = $B; + - pattern-either: + - pattern-inside: | + $T $X; + ... + - pattern-inside: | + $T $X = $I; + ... + - pattern-not: | + $T $X = $A; + $X = <... $X ...>; + - pattern-not: | + $X = $A; + $X = <... $X ...>; + - metavariable-regex: + metavariable: $A + regex: '^(?!(?:-1|0|1|null|true|false|""|string\.Empty|String\.Empty|default)$)' + - focus-metavariable: $A + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.correctness.duplicate-condition-in-if-chain + severity: ERROR + languages: + - csharp + message: >- + Change this condition, it duplicates an earlier condition of the same if-else-if chain. + The branch guarded by a duplicated condition can never execute. + patterns: + - pattern-inside: if ($C) $A; else $REST; + - pattern: if ($C) $B; + - pattern-not: if ($C) $A; else $REST; + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.best-practice.duplicate-branch + severity: WARNING + languages: + - csharp + message: >- + Merge this branch with the identical branch earlier in the same conditional structure. + Two branches with the same implementation are either duplicated code or a copy-paste mistake. + patterns: + - pattern-inside: if ($C) $S; else $REST; + - pattern: if ($D) $S; + - pattern-not: if ($C) $S; else $REST; + - metavariable-regex: + metavariable: $S + regex: '(?s)^\{.*;.*;.*\}$' + options: + constant_propagation: false + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.for-update-not-loop-counter + severity: WARNING + languages: + - csharp + message: >- + Update the loop counter in the increment clause of this for loop. + An increment clause that does not change the loop counter is confusing and may cause an infinite loop. + pattern-either: + - patterns: + - pattern: for ($T $I = $X; $C; $U) $B + - metavariable-pattern: + metavariable: $U + patterns: + - pattern-not: <... $I ...> + - metavariable-pattern: + metavariable: $C + pattern: <... $I ...> + - patterns: + - pattern: for ($I = $X; $C; $U) $B + - metavariable-pattern: + metavariable: $U + patterns: + - pattern-not: <... $I ...> + - metavariable-pattern: + metavariable: $C + pattern: <... $I ...> + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.correctness.collection-passed-to-own-method + severity: WARNING + languages: + - csharp + message: >- + Do not pass a collection to one of its own methods. + Calls such as list.AddRange(list) or set.UnionWith(set) are either useless or produce unexpected results. + patterns: + - pattern: $L.$M($L) + - metavariable-regex: + metavariable: $M + regex: '^(?:AddRange|Concat|Except|ExceptWith|Intersect|IntersectWith|IsProperSubsetOf|IsProperSupersetOf|IsSubsetOf|IsSupersetOf|Overlaps|SequenceEqual|SetEquals|SymmetricExceptWith|Union|UnionWith)$' + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.useless-increment + severity: ERROR + languages: + - csharp + message: >- + Remove this increment or decrement, or correct the code, its result is discarded. + Assigning or returning the postfix increment of a local variable leaves its value unchanged. + pattern-either: + - pattern: $X = $X++; + - pattern: $X = $X--; + - patterns: + - pattern-either: + - pattern: return $X++; + - pattern: return $X--; + - pattern-either: + - pattern-inside: | + $R $M(...) { ... $T $X = $V; ... } + - pattern-inside: | + $R $M(...) { ... $T $X; ... } + - pattern-inside: | + $R $M(..., $T $X, ...) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.non-short-circuit-logic + severity: ERROR + languages: + - csharp + message: >- + Use the short-circuit operator '&&' or '||' instead of '&' or '|' in this boolean expression. + Non-short-circuit operators always evaluate both operands, which wastes work and can cause errors such as null dereferences. + pattern-either: + - pattern: if ($A | $B) $S; + - pattern: if ($A & $B) $S; + - pattern: while ($A | $B) $S; + - pattern: while ($A & $B) $S; + - patterns: + - pattern-either: + - pattern: $A | $B + - pattern: $A & $B + - metavariable-type: + metavariable: $A + type: bool + - patterns: + - pattern-either: + - pattern: $A | $B + - pattern: $A & $B + - metavariable-type: + metavariable: $B + type: bool + - patterns: + - pattern-either: + - pattern: $A | $B + - pattern: $A & $B + - metavariable-pattern: + metavariable: $A + pattern-either: + - pattern: $X == $Y + - pattern: $X != $Y + - pattern: $X < $Y + - pattern: $X > $Y + - pattern: $X <= $Y + - pattern: $X >= $Y + - pattern: "!$X" + - pattern: $X is $Y + - patterns: + - pattern-either: + - pattern: $A | $B + - pattern: $A & $B + - metavariable-pattern: + metavariable: $B + pattern-either: + - pattern: $X == $Y + - pattern: $X != $Y + - pattern: $X < $Y + - pattern: $X > $Y + - pattern: $X <= $Y + - pattern: $X >= $Y + - pattern: "!$X" + - pattern: $X is $Y + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.invalid-shift-count + severity: WARNING + languages: + - csharp + message: >- + Correct the shift count of this shift operation. + Shifting by zero has no effect, and C# masks shift counts larger than the bit width, so the result is not what the code suggests. + pattern-either: + - patterns: + - pattern-either: + - pattern: $X << 0 + - pattern: $X >> 0 + - pattern: $X <<= 0 + - pattern: $X >>= 0 + - metavariable-regex: + metavariable: $X + regex: '^(?!\d)' + - patterns: + - pattern-either: + - pattern: $X << $N + - pattern: $X >> $N + - pattern-either: + - pattern-inside: | + $R $M(..., int $X, ...) { ... } + - pattern-inside: | + int $X = $INIT; + ... + - pattern-inside: | + $R $M(..., uint $X, ...) { ... } + - pattern-inside: | + uint $X = $INIT; + ... + - metavariable-regex: + metavariable: $N + regex: '^\d+$' + - metavariable-comparison: + comparison: int($N) > 31 + - patterns: + - pattern-either: + - pattern: $X << $N + - pattern: $X >> $N + - metavariable-regex: + metavariable: $N + regex: '^\d+$' + - metavariable-comparison: + comparison: int($N) > 63 + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.integer-division-to-floating-point + severity: WARNING + languages: + - csharp + message: >- + Cast one of the operands of this integer division to a floating point type. + The division is computed with integers, so the fractional part is lost before the result is converted. + patterns: + - pattern-either: + - pattern: double $X = $A / $B; + - pattern: float $X = $A / $B; + - pattern: decimal $X = $A / $B; + - metavariable-pattern: + metavariable: $A + pattern-either: + - pattern: (int $Z) + - pattern: (long $Z) + - pattern: (short $Z) + - pattern: (byte $Z) + - patterns: + - pattern: $Z + - metavariable-regex: + metavariable: $Z + regex: '^\d+[lLuU]*$' + - metavariable-pattern: + metavariable: $B + pattern-either: + - pattern: (int $Z) + - pattern: (long $Z) + - pattern: (short $Z) + - pattern: (byte $Z) + - patterns: + - pattern: $Z + - metavariable-regex: + metavariable: $Z + regex: '^\d+[lLuU]*$' + - focus-metavariable: $A + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.infinite-loop-or-recursion + severity: ERROR + languages: + - csharp + message: >- + Add a way to exit this loop or recursion. + Code that loops or recurses forever never completes and eventually hangs or crashes the application. + pattern-either: + - patterns: + - pattern-either: + - pattern: while (true) $BODY + - pattern: for (;;) $BODY + - metavariable-regex: + metavariable: $BODY + regex: '^(?![\s\S]*\b(?:break|return|throw|goto|yield\s+break|Exit)\b)' + - patterns: + - pattern-either: + - pattern: | + $R $M() { return $M(); } + - pattern: | + $R $M() => $M(); + - pattern: | + $R $M($T1 $A) { return $M($A); } + - pattern: | + $R $M($T1 $A) => $M($A); + - pattern: | + $R $M($T1 $A, $T2 $B) { return $M($A, $B); } + - pattern: | + void $M() { $M(); } + - pattern: | + void $M($T1 $A) { $M($A); } + - focus-metavariable: $M + - patterns: + - pattern-either: + - pattern: | + class $C { ... $T $P { get { return $P; } } ... } + - pattern: | + class $C { ... $T $P { get { return $P; } set { ... } } ... } + - pattern: | + class $C { ... $T $P => $P; ... } + - pattern: | + class $C { ... $T $P { get => $P; } ... } + - pattern: | + class $C { ... $T $P { get => $P; set => $S; } ... } + - focus-metavariable: $P + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.modulus-equality-check + severity: ERROR + languages: + - csharp + message: >- + Do not compare the result of this modulus operation with a non-zero value. + The remainder of a negative number is negative, so a check such as 'x % 2 == 1' fails for negative odd numbers. + patterns: + - pattern-either: + - pattern: $X % $N == $K + - pattern: $X % $N != $K + - pattern: $K == $X % $N + - pattern: $K != $X % $N + - metavariable-regex: + metavariable: $K + regex: '^-?[1-9]\d*$' + - metavariable-regex: + metavariable: $X + regex: '^(?!.*\.(?:Count|Length|LongLength)$)(?!.*\.Count\(\)$)' + - pattern-not: (uint $X) % $N == $K + - pattern-not: (ulong $X) % $N == $K + - pattern-not: (byte $X) % $N == $K + - pattern-not: (ushort $X) % $N == $K + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.always-same-math-comparison + severity: WARNING + languages: + - csharp + message: >- + Remove this comparison, its result is always the same. + The value is compared with a constant outside of the range of its type. + pattern-either: + - patterns: + - pattern-either: + - pattern: $A < $B + - pattern: $A <= $B + - pattern: $A > $B + - pattern: $A >= $B + - pattern-either: + - pattern-inside: | + $R $M(..., float $A, ...) { ... } + - pattern-inside: | + float $A = $INIT; + ... + - metavariable-regex: + metavariable: $B + regex: '^(?:double|Double|System\.Double)\.(?:MaxValue|MinValue)$' + - patterns: + - pattern-either: + - pattern: $A < $B + - pattern: $A <= $B + - pattern: $A > $B + - pattern: $A >= $B + - pattern-either: + - pattern-inside: | + $R $M(..., int $A, ...) { ... } + - pattern-inside: | + int $A = $INIT; + ... + - metavariable-regex: + metavariable: $B + regex: '^(?:long|Int64|System\.Int64|ulong|UInt64)\.(?:MaxValue|MinValue)$' + - patterns: + - pattern-either: + - pattern: $A < $B + - pattern: $A <= $B + - pattern: $A > $B + - pattern: $A >= $B + - pattern-either: + - pattern-inside: | + $R $M(..., byte $A, ...) { ... } + - pattern-inside: | + byte $A = $INIT; + ... + - pattern-inside: | + $R $M(..., ushort $A, ...) { ... } + - pattern-inside: | + ushort $A = $INIT; + ... + - pattern-inside: | + $R $M(..., uint $A, ...) { ... } + - pattern-inside: | + uint $A = $INIT; + ... + - pattern-inside: | + $R $M(..., ulong $A, ...) { ... } + - pattern-inside: | + ulong $A = $INIT; + ... + - pattern-inside: | + $R $M(..., char $A, ...) { ... } + - pattern-inside: | + char $A = $INIT; + ... + - metavariable-regex: + metavariable: $B + regex: '^-\d+$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.ignored-return-value + severity: WARNING + languages: + - csharp + message: >- + Use the return value of this method call, the method has no side effects. + Methods such as LINQ queries, string methods or DateTime arithmetic return a new value instead of changing the receiver. + patterns: + - pattern-either: + - patterns: + - pattern: $X.$M(...); + - metavariable-regex: + metavariable: $M + regex: '^(?:Where|Select|SelectMany|Any|All|Count|LongCount|First|FirstOrDefault|Last|LastOrDefault|Single|SingleOrDefault|OrderBy|OrderByDescending|ThenBy|ThenByDescending|GroupBy|Distinct|DistinctBy|Concat|Union|Intersect|Except|Skip|SkipWhile|Take|TakeWhile|Zip|ToList|ToArray|ToDictionary|ToHashSet|ToLookup|Sum|Min|Max|Average|Aggregate|Cast|OfType|ElementAt|ElementAtOrDefault|DefaultIfEmpty|SequenceEqual|AsEnumerable)$' + - patterns: + - pattern-either: + - pattern: (string $S).$M(...); + - pattern: '"$L".$M(...);' + - metavariable-regex: + metavariable: $M + regex: '^(?:Trim|TrimStart|TrimEnd|ToUpper|ToLower|ToUpperInvariant|ToLowerInvariant|Replace|Substring|Insert|Remove|PadLeft|PadRight|Split|Contains|StartsWith|EndsWith|IndexOf|LastIndexOf|Equals|CompareTo|Normalize)$' + - patterns: + - pattern-either: + - pattern: (DateTime $D).$M(...); + - pattern: (DateTimeOffset $D).$M(...); + - pattern: (TimeSpan $D).$M(...); + - metavariable-regex: + metavariable: $M + regex: '^(?:Add|AddDays|AddHours|AddMinutes|AddSeconds|AddMilliseconds|AddMonths|AddYears|AddTicks|Subtract|ToUniversalTime|ToLocalTime|Negate|Duration)$' + - pattern: string.Intern($S); + - pattern-not-inside: $V = $E; + - pattern-not-inside: $TY $V = $E; + - pattern-not-inside: var $V = $E; + - pattern-not-inside: return $E; + - pattern-not-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|static|override|virtual|async|sealed|new)[ \t]+)*[\w.<>\[\],?]+[ \t]+\w+[ \t]*\([^()]*\)[ \t]*=>[^;]*;' + options: + implicit_deep_exprstmt: false + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.catch-general-exception + severity: ERROR + languages: + - csharp + message: >- + Catch a more specific exception type, or rethrow the exception at the end of this catch block. + Catching System.Exception also catches unexpected failures such as OutOfMemoryException that the code cannot handle. + pattern-regex: '\bcatch\b(?:[ \t]*\([ \t]*(?:System\.)?Exception(?:[ \t]+\w+)?[ \t]*\))?(?![ \t]*when\b)(?=\s*(?://[^\n]*\s*)*\{)(?!\s*(?://[^\n]*\s*)*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\bthrow\b[^;{}]*;\s*\})' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.tostring-returns-null + severity: ERROR + languages: + - csharp + message: >- + Return an empty string instead of null from this ToString() override. + Callers expect ToString() to always return a usable string. + pattern-either: + - patterns: + - pattern: return null; + - pattern-inside: | + override string ToString() { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + $P => { ... } + - pattern-not-inside: | + () => { ... } + - patterns: + - pattern: | + override string ToString() => null; + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.for-loop-wrong-direction + severity: ERROR + languages: + - csharp + message: >- + Correct the update clause of this for loop, it moves the counter away from the stop condition. + Such a loop runs until the counter overflows, which is almost certainly not intended. + pattern-either: + - pattern: for ($T $I = $X; $I < $Y; $I--) $S; + - pattern: for ($T $I = $X; $I <= $Y; $I--) $S; + - pattern: for ($T $I = $X; $I < $Y; --$I) $S; + - pattern: for ($T $I = $X; $I <= $Y; --$I) $S; + - pattern: for ($T $I = $X; $I < $Y; $I -= $N) $S; + - pattern: for ($T $I = $X; $I <= $Y; $I -= $N) $S; + - pattern: for ($T $I = $X; $I > $Y; $I++) $S; + - pattern: for ($T $I = $X; $I >= $Y; $I++) $S; + - pattern: for ($T $I = $X; $I > $Y; ++$I) $S; + - pattern: for ($T $I = $X; $I >= $Y; ++$I) $S; + - pattern: for ($T $I = $X; $I > $Y; $I += $N) $S; + - pattern: for ($T $I = $X; $I >= $Y; $I += $N) $S; + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.for-loop-never-runs + severity: ERROR + languages: + - csharp + message: >- + Correct the initial value or the condition of this for loop, its body never executes. + The condition is already false before the first iteration. + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: for ($T $I = $A; $I < $B; $U) $S; + - pattern: for ($T $I = $A; $I <= $B; $U) $S; + - metavariable-regex: + metavariable: $A + regex: '^-?\d+$' + - metavariable-regex: + metavariable: $B + regex: '^-?\d+$' + - metavariable-comparison: + comparison: int($A) > int($B) + - patterns: + - pattern: for ($T $I = $A; $I < $B; $U) $S; + - metavariable-regex: + metavariable: $A + regex: '^-?\d+$' + - metavariable-regex: + metavariable: $B + regex: '^-?\d+$' + - metavariable-comparison: + comparison: int($A) == int($B) + - patterns: + - pattern-either: + - pattern: for ($T $I = $A; $I > $B; $U) $S; + - pattern: for ($T $I = $A; $I >= $B; $U) $S; + - metavariable-regex: + metavariable: $A + regex: '^-?\d+$' + - metavariable-regex: + metavariable: $B + regex: '^-?\d+$' + - metavariable-comparison: + comparison: int($A) < int($B) + - patterns: + - pattern: for ($T $I = $A; $I > $B; $U) $S; + - metavariable-regex: + metavariable: $A + regex: '^-?\d+$' + - metavariable-regex: + metavariable: $B + regex: '^-?\d+$' + - metavariable-comparison: + comparison: int($A) == int($B) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.lock-not-released-on-all-paths + severity: ERROR + languages: + - csharp + message: >- + Release this lock in a finally block so that it is released on all execution paths. + A lock that is not released when an exception occurs or an early return happens can cause deadlocks. + pattern-either: + - patterns: + - pattern: $L.Enter($X); + - pattern-inside: | + $R $M(...) { ... $L.Exit($X); ... } + - pattern-not-inside: | + $R $M(...) { ... try { ... } finally { ... $L.Exit($X); ... } ... } + - patterns: + - pattern: $L.$ENTER(); + - metavariable-regex: + metavariable: $ENTER + regex: '^(?:EnterReadLock|EnterWriteLock|EnterUpgradeableReadLock|WaitOne|Wait)$' + - pattern-inside: | + $R $M(...) { ... $L.$EXIT(); ... } + - metavariable-regex: + metavariable: $EXIT + regex: '^(?:ExitReadLock|ExitWriteLock|ExitUpgradeableReadLock|ReleaseMutex|Release)$' + - pattern-not-inside: | + $R $M(...) { ... try { ... } finally { ... $L.$EXIT(); ... } ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.null-pointer-dereference + severity: ERROR + languages: + - csharp + message: >- + Do not dereference this variable, it is null at this point. + Accessing a member of a null reference throws a NullReferenceException. + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $T $X = null; + ... + - pattern-not-inside: | + $T $X = null; + ... + $X = $Y; + ... + - patterns: + - pattern-either: + - pattern-inside: | + if ($X == null) { ... } + ... + - pattern-inside: | + if ($X is null) { ... } + ... + - pattern-not-inside: | + if ($X == null) { ... return ...; } + ... + - pattern-not-inside: | + if ($X == null) { ... throw ...; } + ... + - pattern-not-inside: | + if ($X == null) { ... $X = $Y; ... } + ... + - pattern-not-inside: | + if ($X is null) { ... return ...; } + ... + - pattern-not-inside: | + if ($X is null) { ... throw ...; } + ... + - pattern-not-inside: | + if ($X is null) { ... $X = $Y; ... } + ... + - pattern-not-inside: | + if ($X == null) { ... continue; } + ... + - pattern-not-inside: | + if ($X == null) { ... break; } + ... + - pattern-not-inside: | + if ($X == null) $A; else $B; + ... + - pattern-not-inside: | + if ($X is null) $A; else $B; + ... + - pattern: $X.$F + - pattern-not: $X.Value + - pattern-not: $X.HasValue + - pattern-not: $X.GetValueOrDefault + - pattern-not-inside: $X = $Y + - pattern-not-inside: if (<... $X != null ...>) $S; + - pattern-not-inside: if (<... $X is not null ...>) $S; + - pattern-not-inside: $X != null && $E + - pattern-not-inside: $X == null || $E + - pattern-not-inside: | + ($P) => $E + - pattern-not-inside: | + () => $E + options: + constant_propagation: false + metadata: + category: correctness + cwe: "CWE-476: NULL Pointer Dereference" + confidence: MEDIUM + - id: codacy.csharp.correctness.ill-formed-format-string + severity: ERROR + languages: + - csharp + message: >- + Correct this composite format string, it is malformed or references a missing argument. + String.Format throws a FormatException at runtime when braces are unbalanced or an index is out of range. + patterns: + - pattern-either: + - pattern: string.Format("$F", ...) + - pattern: String.Format("$F", ...) + - pattern: $SB.AppendFormat("$F", ...) + - pattern: Console.WriteLine("$F", $A1, ...) + - pattern: Console.Write("$F", $A1, ...) + - pattern-either: + - patterns: + - pattern-either: + - pattern: $M("$F", ...) + - pattern: $O.$M("$F", ...) + - metavariable-regex: + metavariable: $F + regex: '^(?!(?:[^{}]|\{\{|\}\}|\{\s*\d+\s*(?:,\s*-?\d+\s*)?(?::[^{}]*)?\})*$)' + - patterns: + - pattern-either: + - pattern: $M("$F") + - pattern: $O.$M("$F") + - pattern-not: Console.WriteLine("$F") + - pattern-not: Console.Write("$F") + - metavariable-regex: + metavariable: $F + regex: '(?s).*(?- + Remove the 'virtual' modifier of this field-like event, or implement its add and remove accessors. + The compiler generates a separate backing field for each override, so subscribers of the base event are never notified. + pattern-regex: '\bvirtual[ \t]+event[ \t]+[\w.<>,? ]+?[ \t]+\K\w+(?=[ \t]*(?:=[^;]*)?;)' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.gethashcode-uses-mutable-field + severity: ERROR + languages: + - csharp + message: >- + Refactor GetHashCode() to not use this mutable field. + If the field changes while the object is stored in a hash-based collection, the object can no longer be found. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $T $F; ... } + - pattern-inside: | + class $C { ... $T $F = $I; ... } + - pattern-not-inside: | + class $C { ... readonly $T2 $F; ... } + - pattern-not-inside: | + class $C { ... readonly $T2 $F = $I2; ... } + - pattern-not-inside: | + class $C { ... const $T2 $F = $I2; ... } + - pattern-either: + - pattern-inside: | + override int GetHashCode() { ... } + - pattern-inside: | + override int GetHashCode() => $E; + - pattern-either: + - pattern: $F + - pattern: this.$F + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.flags-enum-members-not-initialized + severity: ERROR + languages: + - csharp + message: >- + Initialize all the members of this [Flags] enumeration explicitly with powers of two. + Implicit values continue with 3, 4, 5... which are not distinct bit flags, so bitwise combinations give wrong results. + pattern-regex: '\[[ \t]*(?:System\.)?Flags(?:Attribute)?[ \t]*\][^;{}]*?\benum[ \t]+\K\w+(?=(?:[ \t]*:[ \t]*[\w.]+)?\s*(?://[^\n]*\s*)*\{(?=(?:[^{}]*?,){3})[^{}]*?[{,]\s*(?://[^\n]*\s*)*\w+\s*(?://[^\n]*\s*)*[,}])' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.lock-on-non-readonly-field + severity: ERROR + languages: + - csharp + message: >- + Lock on a dedicated private readonly object instead. + If the locked field is reassigned, different threads can lock on different objects and the critical section is no longer protected. + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $T $F; ... } + - pattern-inside: | + class $C { ... $T $F = $I; ... } + - pattern-not-inside: | + class $C { ... readonly $T2 $F; ... } + - pattern-not-inside: | + class $C { ... readonly $T2 $F = $I2; ... } + - pattern-either: + - pattern: lock ($F) { ... } + - pattern: lock (this.$F) { ... } + - pattern: lock (new $T(...)) { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.lock-on-shared-resource + severity: ERROR + languages: + - csharp + message: >- + Lock on a dedicated private object instead of 'this', a Type or a string. + These objects can be locked by unrelated code, which can cause deadlocks. + pattern-either: + - pattern: lock (this) { ... } + - pattern: lock (typeof($T)) { ... } + - pattern: lock ("$S") { ... } + - pattern: lock ((string $S)) { ... } + - pattern: lock ($X.GetType()) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.condition-always-false + severity: ERROR + languages: + - csharp + message: >- + Change this condition so that it does not always evaluate to false. + The code guarded by an always false condition is unreachable. + patterns: + - pattern-either: + - pattern: if ($C) $S; + - pattern: while ($C) $S; + - metavariable-pattern: + metavariable: $C + pattern: "false" + - metavariable-regex: + metavariable: $C + regex: '^(?!.*\b(?:true|false)\b)(?:\w+|[\w.]+[ \t]*(?:==|!=|<=|>=|<|>)[ \t]*[\w.]+)$' + - pattern-not-inside: | + const bool $C = $V; + ... + - pattern-not-inside: | + class $K { ... const bool $C = $V; ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.condition-always-true + severity: ERROR + languages: + - csharp + message: >- + Change this condition so that it does not always evaluate to true. + An always true condition makes the check gratuitous and any else branch unreachable. + patterns: + - pattern-either: + - pattern: if ($C) $S; + - pattern: "$C ? $A : $B" + - metavariable-pattern: + metavariable: $C + pattern: "true" + - metavariable-regex: + metavariable: $C + regex: '^(?!.*\b(?:true|false)\b)(?:\w+|[\w.]+[ \t]*(?:==|!=|<=|>=|<|>)[ \t]*[\w.]+)$' + - pattern-not-inside: | + const bool $C = $V; + ... + - pattern-not-inside: | + class $K { ... const bool $C = $V; ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.stream-read-result-ignored + severity: ERROR + languages: + - csharp + message: >- + Use the number of bytes returned by this Read call. + Stream.Read may return fewer bytes than requested, so ignoring the result leads to incomplete or corrupted data. + patterns: + - pattern-either: + - pattern: $S.Read($B, $O, $C); + - pattern: await $S.ReadAsync($B, $O, $C, ...); + - pattern: await $S.ReadAsync($B); + - pattern: await $S.ReadAsync($B, $T); + - pattern-not-inside: $V = $E; + - pattern-not-inside: $TY $V = $E; + - pattern-not-inside: var $V = $E; + options: + implicit_deep_exprstmt: false + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.nan-comparison + severity: ERROR + languages: + - csharp + message: >- + Use double.IsNaN() or float.IsNaN() instead of comparing with NaN. + NaN is not equal to anything, not even itself, so this comparison always gives the same result. + patterns: + - pattern-either: + - pattern: $X == $NAN + - pattern: $X != $NAN + - pattern: $X < $NAN + - pattern: $X <= $NAN + - pattern: $X > $NAN + - pattern: $X >= $NAN + - pattern: $NAN == $X + - pattern: $NAN != $X + - metavariable-regex: + metavariable: $NAN + regex: '^(?:System\.)?(?:double|float|Double|Single)\.NaN$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.indexof-positive-check + severity: ERROR + languages: + - csharp + message: >- + Check whether this IndexOf result is '>= 0' instead of '> 0'. + Index 0 is a valid position, so '> 0' misses matches at the first position. + pattern-either: + - pattern: $X.IndexOf(...) > 0 + - pattern: 0 < $X.IndexOf(...) + - pattern: $X.IndexOfAny(...) > 0 + - pattern: 0 < $X.IndexOfAny(...) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.static-field-written-from-instance + severity: ERROR + languages: + - csharp + message: >- + Do not write this static field from an instance member. + Updating shared static state from instance methods is error-prone and not thread-safe. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... static $T $F; ... } + - pattern-inside: | + class $C { ... static $T $F = $I; ... } + - pattern-inside: | + interface $C { ... static $T $F = $I; ... } + - pattern-inside: | + $R $M(...) { ... } + - pattern-not-inside: | + static $R $M(...) { ... } + - pattern-either: + - pattern: $F = $V + - pattern: $F += $V + - pattern: $F -= $V + - pattern: $F++ + - pattern: $F-- + - pattern: ++$F + - pattern: --$F + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.static-field-in-generic-type + severity: WARNING + languages: + - csharp + message: >- + Make sure this static field is not expected to be shared among all constructed types of this generic type. + Each closed generic type, such as Cache and Cache, has its own copy of the static field. + patterns: + - pattern-either: + - pattern: | + class $C<$T> { ... static $FT $F; ... } + - pattern: | + class $C<$T> { ... static $FT $F = $I; ... } + - pattern-not: | + class $C<$T> { ... const $FT $F = $I; ... } + - metavariable-comparison: + comparison: not (str($T) in str($FT)) + - focus-metavariable: $F + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.non-existent-operator + severity: WARNING + languages: + - csharp + message: >- + Replace '=+', '=-' or '=!' with the intended operator, or remove the space after the unary operator. + 'x =- y' assigns '-y' to x, which is probably not what was meant by 'x -= y'. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^\n"]*?[\w\])][ \t]*\K=[+\-!](?=[ \t]+[\w(])' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.same-condition-tested-twice + severity: WARNING + languages: + - csharp + message: >- + Merge this if statement with the previous one, it tests the same condition. + Testing the same condition twice in a row is confusing and is often a mistake. + patterns: + - pattern-inside: | + if ($C) $A; + if ($C) $B; + - pattern: if ($C) $B; + - pattern-not-inside: | + if ($C) { ... $X = $V; ... } + if ($C) $B; + - pattern-not-inside: | + if ($C) $A; else $E; + if ($C) $B; + - pattern-not-inside: | + if ($C) $B; + if ($C) $Z; + options: + constant_propagation: false + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.doubled-prefix-operator + severity: WARNING + languages: + - csharp + message: >- + Remove the doubled '!' or '~' operator. + Applying the same prefix operator twice cancels it out and is usually a typo. + pattern-either: + - pattern: "!!$X" + - pattern: ~~$X + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.sql-keyword-without-whitespace + severity: WARNING + languages: + - csharp + message: >- + Add a space between these concatenated SQL fragments. + Without whitespace, words such as 'p.PhoneNumberFROM' are glued together and the query is invalid. + patterns: + - pattern-either: + - pattern: '"$A" + "$B"' + - pattern: '$P + "$A" + "$B"' + - metavariable-regex: + metavariable: $A + regex: '(?s)^.*\b(?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|SET|VALUES|JOIN|ORDER BY|GROUP BY|AND|OR)\b.*[^\s(]$' + - metavariable-regex: + metavariable: $B + regex: '^(?:SELECT|FROM|WHERE|SET|VALUES|INTO|JOIN|INNER|LEFT|RIGHT|OUTER|ORDER|GROUP|HAVING|AND|OR|LIMIT|UNION)\b' + - focus-metavariable: $B + options: + constant_propagation: false + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.unconstrained-generic-null-comparison + severity: WARNING + languages: + - csharp + message: >- + Use 'default' or add a 'class' constraint instead of comparing this unconstrained generic value with null. + When the type argument is a value type, the comparison is always false. + patterns: + - pattern-either: + - pattern: $X == null + - pattern: $X != null + - pattern: null == $X + - pattern: null != $X + - pattern-inside: | + $R $M<$T>(..., $T $X, ...) { ... } + - pattern-not-inside: | + $R $M<$T>(..., $T $X, ...) where $T : class { ... } + - pattern-not-inside: | + $R $M<$T>(..., $T $X, ...) where $T : class, $C2 { ... } + - pattern-not-inside: | + $R $M<$T>(..., $T $X, ...) where $T : notnull { ... } + - pattern-not-inside: | + $R $M<$T>(..., $T $X, ...) where $T : struct { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.reference-equals-value-type + severity: ERROR + languages: + - csharp + message: >- + Use Equals() or '==' instead of ReferenceEquals() to compare these value types. + Value types are boxed into new objects, so ReferenceEquals always returns false. + patterns: + - pattern-either: + - pattern: ReferenceEquals($A, $B) + - pattern: object.ReferenceEquals($A, $B) + - pattern: Object.ReferenceEquals($A, $B) + - metavariable-type: + metavariable: $A + types: [int, long, short, byte, double, float, decimal, bool, char, DateTime, TimeSpan, Guid, DateTimeOffset] + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.threadstatic-field-initialized + severity: ERROR + languages: + - csharp + message: >- + Do not initialize this [ThreadStatic] field inline, initialize it lazily instead. + The inline initializer runs only once, so the field keeps its default value in every other thread. + pattern-regex: '\[[ \t]*(?:System\.)?ThreadStatic(?:Attribute)?[ \t]*\]\s*(?://[^\n]*\s*)*(?:(?:public|private|protected|internal|static|readonly|volatile)[ \t]+)*[\w.<>\[\],?]+[ \t]+\K\w+(?=[ \t]*=[^=])' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.disposed-object-returned + severity: ERROR + languages: + - csharp + message: >- + Do not return this object, it is disposed at the end of the using statement. + The caller receives an object that can no longer be used. + pattern-either: + - patterns: + - pattern: return $X; + - pattern-either: + - pattern-inside: | + using (var $X = $E) { ... } + - pattern-inside: | + using ($T $X = $E) { ... } + - pattern-regex: '\busing[ \t]+(?:var|[\w.<>]+)[ \t]+(\w+)[ \t]*=[^;]*;(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\K\breturn[ \t]+\1[ \t]*;' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.threadstatic-on-instance-field + severity: ERROR + languages: + - csharp + message: >- + Make this [ThreadStatic] field static, or remove the attribute. + The ThreadStatic attribute is ignored on instance fields. + pattern-regex: '\[[ \t]*(?:System\.)?ThreadStatic(?:Attribute)?[ \t]*\]\s*(?://[^\n]*\s*)*(?:(?:public|private|protected|internal|readonly|volatile)[ \t]+)*(?!static\b)[\w.<>\[\],?]+[ \t]+\K\w+(?=[ \t]*[=;])' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.static-field-assigned-in-constructor + severity: ERROR + languages: + - csharp + message: >- + Do not update this static field from an instance constructor. + Every new instance overwrites the value shared by all instances. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... static $T $F; ... } + - pattern-inside: | + class $C { ... static $T $F = $I; ... } + - pattern-either: + - pattern: $F = $V + - pattern: $F += $V + - pattern: $F -= $V + - pattern: $F++ + - pattern: ++$F + - pattern-regex: '(?m)^[ \t]*(?:(?:public|protected|internal|private)[ \t]+)*(?!(?:if|while|for|foreach|switch|catch|using|lock|fixed|return|new|else|static)\b)[A-Z]\w*[ \t]*\((?:[^()]|\([^()]*\))*\)\s*(?::\s*(?:base|this)\s*\((?:[^()]|\([^()]*\))*\)\s*)?\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.async-void-method + severity: ERROR + languages: + - csharp + message: >- + Return a Task instead of void from this async method. + Exceptions thrown from async void methods cannot be caught by callers and the method cannot be awaited. + patterns: + - pattern-either: + - pattern: | + async void $M() { ... } + - pattern: | + async void $M($T1 $A) { ... } + - patterns: + - pattern: | + async void $M($T1 $A, $T2 $B) { ... } + - metavariable-regex: + metavariable: $T2 + regex: '^(?!.*EventArgs$)' + - pattern: | + async void $M($T1 $A, $T2 $B, $T3 $C, ...) { ... } + - focus-metavariable: $M + - metavariable-regex: + metavariable: $M + regex: '^(?!On[A-Z])' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.setter-ignores-value + severity: ERROR + languages: + - csharp + message: >- + Use the 'value' keyword in this accessor. + An accessor that ignores 'value' discards what the caller tries to set. + pattern-either: + - pattern-regex: '\b(?:set|init|add|remove)\s*\{(?!\s*\})(?!\s*throw\b)(?![^{}]*\bvalue\b)[^{}]*\}' + - pattern-regex: '\b(?:set|init)\s*=>(?![^;]*\bvalue\b)(?!\s*throw\b)[^;]*;' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.anonymous-delegate-unsubscribe + severity: ERROR + languages: + - csharp + message: >- + Unsubscribe with the same delegate instance that was used to subscribe. + Each lambda or anonymous method creates a new delegate, so removing it from an event does nothing. + pattern-regex: '-=\s*\K(?:(?:async\s+)?delegate\b|(?:async\s+)?\([^()]*\)\s*=>|(?:async\s+)?\w+\s*=>)' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.base-object-equality-call + severity: WARNING + languages: + - csharp + message: >- + Do not call the object base implementation of GetHashCode() or Equals() here. + For a class that directly extends object, these base methods use reference identity, which contradicts the value equality being implemented. + patterns: + - pattern-either: + - patterns: + - pattern: base.GetHashCode() + - pattern-either: + - pattern-inside: | + override int GetHashCode() { ... } + - pattern-inside: | + override int GetHashCode() => $E; + - patterns: + - pattern: base.Equals($X) + - pattern-either: + - pattern-inside: | + override bool Equals($T $O) { ... } + - pattern-inside: | + override bool Equals($T $O) => $E; + - pattern-not-inside: if (base.Equals($X)) $S; + - pattern-inside: | + class $C { ... } + - pattern-not-inside: | + class $C : $B { ... } + - pattern-not-inside: | + class $C : $B, $I { ... } + - pattern-not-inside: | + class $C : $B, $I, $J { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.static-field-initialization-order + severity: ERROR + languages: + - csharp + message: >- + Move this static field after the static fields it is initialized from. + Static fields are initialized in declaration order, so the referenced field still has its default value. + pattern-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|readonly)[ \t]+)*static[ \t]+(?:readonly[ \t]+)?[\w.<>\[\],?]+[ \t]+\K(\w+)[ \t]*=[^;]*?\b(\w+)\b[^;]*;(?=[\s\S]*?^[ \t]*(?:(?:public|private|protected|internal|readonly)[ \t]+)*static[ \t]+(?:readonly[ \t]+)?[\w.<>\[\],?]+[ \t]+\2[ \t]*[=;])' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.side-effect-in-debug-assert + severity: ERROR + languages: + - csharp + message: >- + Move this side effect out of the Debug.Assert call. + Debug.Assert calls are removed from release builds, so the side effect would not happen in production. + patterns: + - pattern-either: + - pattern: Debug.Assert(...) + - pattern: System.Diagnostics.Debug.Assert(...) + - pattern-either: + - pattern: Debug.Assert(<... $X = $Y ...>, ...) + - pattern: Debug.Assert(<... $X++ ...>, ...) + - pattern: Debug.Assert(<... $X-- ...>, ...) + - pattern: Debug.Assert(<... ++$X ...>, ...) + - pattern: Debug.Assert(<... --$X ...>, ...) + - patterns: + - pattern: Debug.Assert(<... $L.$M(...) ...>, ...) + - metavariable-regex: + metavariable: $M + regex: '^(?:Add|AddRange|Remove|RemoveAt|RemoveAll|Clear|Insert|Push|Pop|Enqueue|Dequeue|TryAdd|TryRemove|TryDequeue|TryPop|Set|Reset|Dispose|Close|Write|WriteLine|Delete|Move|Save|Execute|ExecuteNonQuery)$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.temporal-type-as-primary-key + severity: ERROR + languages: + - csharp + message: >- + Do not use a date or time type as the primary key of this entity. + Several rows can be created at the same instant, and clock precision differs between systems, which leads to duplicate keys. + pattern-either: + - pattern-regex: '\[[ \t]*Key[ \t]*\]\s*(?:public[ \t]+)?(?:System\.)?(?:DateTime|DateTimeOffset|DateOnly|TimeOnly|TimeSpan)\??[ \t]+\K\w+' + - pattern-regex: '(?m)^[ \t]*public[ \t]+(?:System\.)?(?:DateTime|DateTimeOffset|DateOnly|TimeOnly|TimeSpan)\??[ \t]+\KId(?=[ \t]*\{)' + - pattern-regex: '\bclass[ \t]+(\w+)\b[^{]*\{(?:[^{}]|\{[^{}]*\})*?\bpublic[ \t]+(?:System\.)?(?:DateTime|DateTimeOffset|DateOnly|TimeOnly|TimeSpan)\??[ \t]+\K\1Id(?=[ \t]*\{)' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.this-exposed-from-constructor + severity: ERROR + languages: + - csharp + message: >- + Make sure that exposing 'this' from this constructor is safe. + Other code, possibly on other threads, could access the object before it is fully constructed. + patterns: + - pattern-either: + - pattern: $O.$M(..., this, ...) + - pattern: $O.$F = this + - pattern-not: this.$M(..., this, ...) + - pattern-not: base.$M(..., this, ...) + - pattern-not: this.$F = this + - pattern-regex: '(?m)^[ \t]*(?:(?:public|protected|internal|private)[ \t]+)*(?!(?:if|while|for|foreach|switch|catch|using|lock|fixed|return|new|else|static)\b)[A-Z]\w*[ \t]*\((?:[^()]|\([^()]*\))*\)\s*(?::\s*(?:base|this)\s*\((?:[^()]|\([^()]*\))*\)\s*)?\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + metadata: + category: correctness + confidence: LOW + - id: codacy.csharp.correctness.base-equals-reference-check + severity: ERROR + languages: + - csharp + message: >- + Use object.ReferenceEquals() instead of base.Equals() to check for reference equality. + When the base class overrides Equals, base.Equals performs its value comparison instead of a reference check. + patterns: + - pattern: base.Equals($X) + - pattern-either: + - pattern-inside: | + override bool Equals($T $O) { ... } + - pattern-inside: | + override bool Equals($T $O) => $E; + - pattern-not-inside: if (base.Equals($X)) $S; + - pattern-either: + - pattern-inside: | + class $C : $B { ... } + - pattern-inside: | + class $C : $B, $I { ... } + - pattern-inside: | + class $C : $B, $I, $J { ... } + - metavariable-regex: + metavariable: $B + regex: '^(?!I[A-Z])(?!(?:System\.)?[Oo]bject$)' + metadata: + category: correctness + confidence: LOW + - id: codacy.csharp.correctness.gettype-on-type-instance + severity: WARNING + languages: + - csharp + message: >- + Remove this GetType() or IsInstanceOfType() call on a System.Type instance. + Calling it on a Type returns the runtime type of the Type object itself, which is almost never intended. + pattern-either: + - patterns: + - pattern: typeof($T).GetType() + - pattern-not: typeof(Type).GetType() + - pattern-not: typeof(System.Type).GetType() + - pattern: $X.GetType().GetType() + - pattern: (Type $T).GetType() + - pattern: $X.IsInstanceOfType(typeof($T)) + - pattern: $X.IsInstanceOfType((Type $T)) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.exception-rethrown-explicitly + severity: ERROR + languages: + - csharp + message: >- + Use 'throw;' instead of 'throw ex;' to rethrow this exception. + Rethrowing the exception variable resets its stack trace and loses the original failure location. + pattern-regex: '\bcatch\s*\(\s*[\w.]+\s+(\w+)\s*\)\s*(?:when\s*\((?:[^()]|\([^()]*\))*\)\s*)?\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\K\bthrow\s+\1\s*;' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.optional-on-ref-or-out-parameter + severity: ERROR + languages: + - csharp + message: >- + Remove the [Optional] attribute from this ref or out parameter. + Callers must always provide ref and out arguments, so the attribute is misleading. + pattern-regex: '\[[ \t]*(?:System\.Runtime\.InteropServices\.)?Optional(?:Attribute)?[ \t]*\]\s*\K(?:ref|out)\b' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.invalid-dynamic-shift-operand + severity: ERROR + languages: + - csharp + message: >- + Use an integer as the right operand of this shift operation. + With a dynamic left operand, a non-integer shift count compiles but throws a RuntimeBinderException. + patterns: + - pattern-either: + - pattern: (dynamic $D) << $X + - pattern: (dynamic $D) >> $X + - metavariable-regex: + metavariable: $X + regex: '^(?:-?\d*\.\d+(?:[eE][+-]?\d+)?[fFdDmM]?|-?\d+[fFdDmM]|null|"[^"]*"|true|false)$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.default-value-on-parameter + severity: ERROR + languages: + - csharp + message: >- + Use [DefaultParameterValue] instead of [DefaultValue] on this parameter. + [DefaultValue] only informs designers and serializers; it does not give the parameter a default value. + pattern-regex: '[(,]\s*(?:\[[^\]]*\]\s*)*\[[ \t]*(?:[^\]]*,[ \t]*)?\K(?:System\.ComponentModel\.)?DefaultValue(?:Attribute)?[ \t]*\(' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.class-with-only-private-constructors + severity: WARNING + languages: + - csharp + message: >- + Add a non-private constructor or a static factory to this class, or remove it. + A class whose constructors are all private can never be instantiated. + patterns: + - pattern: | + class $C { ... private $C(...) { ... } ... } + - pattern-not: | + class $C { ... public $C(...) { ... } ... } + - pattern-not: | + class $C { ... protected $C(...) { ... } ... } + - pattern-not: | + class $C { ... internal $C(...) { ... } ... } + - pattern-not: | + class $C { ... static $R $M(...) { ... } ... } + - pattern-not: | + class $C { ... static $R $M(...) => $E; ... } + - pattern-not: | + class $C { ... static $T $F = $V; ... } + - pattern-not: | + class $C { ... static $T $P { get; } ... } + - pattern-not: | + class $C { ... static $T $P { get; } = $V; ... } + - pattern-not: | + class $C { ... static $T $P { get; set; } ... } + - pattern-not: | + class $C { ... static $T $P => $E; ... } + - pattern-not: | + static class $C { ... } + - pattern-not: | + class $C : SafeHandle { ... } + - pattern-not-inside: | + class $O { ... class $C { ... } ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.recursive-type-inheritance + severity: ERROR + languages: + - csharp + message: >- + Remove this recursive type inheritance. + A generic type that inherits from itself causes a TypeLoadException at runtime. + pattern-regex: '\bclass[ \t]+(\w+)[ \t]*<[^>{]*>[ \t]*:[ \t]*\K\1[ \t]*<' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.disposable-not-disposed + severity: ERROR + languages: + - csharp + message: >- + Dispose this object, or create it in a using statement. + Objects that hold unmanaged resources such as files, sockets or images must be disposed to release those resources promptly. + patterns: + - pattern-inside: | + $R $M(...) { ... } + - pattern-either: + - patterns: + - pattern-either: + - pattern: var $X = new $T(...); + - pattern: $TY $X = new $T(...); + - metavariable-regex: + metavariable: $T + regex: '^(?:System\.IO\.)?(?:FileStream|Bitmap|Image|WebClient|TcpClient|UdpClient|Socket|CancellationTokenSource|SqlConnection|SqlCommand|Mutex|Semaphore|SemaphoreSlim|Timer)$' + - patterns: + - pattern-either: + - pattern: var $X = new $T((string $A), ...); + - pattern: $TY $X = new $T((string $A), ...); + - metavariable-regex: + metavariable: $T + regex: '^(?:System\.IO\.)?(?:StreamReader|StreamWriter)$' + - pattern: var $X = File.Create(...); + - pattern: var $X = File.Open(...); + - pattern: var $X = Image.FromFile(...); + - pattern: var $X = Image.FromStream(...); + - pattern: $TY $X = File.Create(...); + - pattern: $TY $X = File.Open(...); + - pattern-not-regex: '\busing[ \t]+(?:var|[\w.<>]+)[ \t]+\w+[ \t]*=[^;]*;' + - pattern-not-inside: using (...) $S; + - pattern-not-inside: | + $R $M(...) { ... $X.Dispose(); ... } + - pattern-not-inside: | + $R $M(...) { ... $X?.Dispose(); ... } + - pattern-not-inside: | + $R $M(...) { ... $X.Close(); ... } + - pattern-not-inside: | + $R $M(...) { ... await $X.DisposeAsync(); ... } + - pattern-not-inside: | + $R $M(...) { ... return <... $X ...>; ... } + - pattern-not-inside: | + $R $M(...) { ... $F(..., <... $X ...>, ...); ... } + - pattern-not-inside: | + $R $M(...) { ... $O.$F(..., <... $X ...>, ...); ... } + - pattern-not-inside: | + $R $M(...) { ... $Y = <... $X ...>; ... } + - pattern-not-inside: | + $R $M(...) { ... using (<... $X ...>) $S; ... } + - focus-metavariable: $X + metadata: + category: correctness + cwe: "CWE-459: Incomplete Cleanup" + confidence: LOW + - id: codacy.csharp.correctness.class-owns-disposable-fields + severity: ERROR + languages: + - csharp + message: >- + Implement IDisposable in this class and dispose the disposable fields it creates. + A class that creates disposable members owns them and must offer a way to release their resources. + patterns: + - pattern-either: + - pattern: | + class $C { ... $T $F = new $D(...); ... } + - pattern: | + class $C { ... $R $M(...) { ... $F = new $D(...); ... } ... } + - pattern: | + class $C { ... $C(...) { ... $F = new $D(...); ... } ... } + - metavariable-regex: + metavariable: $D + regex: '^(?:System\.IO\.)?(?:FileStream|StreamReader|StreamWriter|BinaryReader|BinaryWriter|Bitmap|WebClient|TcpClient|UdpClient|Socket|CancellationTokenSource|SqlConnection|SqlCommand|Mutex|Semaphore|SemaphoreSlim|Timer|MemoryStream)$' + - pattern-not: | + class $C : IDisposable { ... } + - pattern-not: | + class $C : $B, IDisposable { ... } + - pattern-not: | + class $C : IDisposable, $I { ... } + - pattern-not: | + class $C : $B, IDisposable, $I { ... } + - pattern-not: | + class $C : $B, $I, IDisposable { ... } + - pattern-not: | + class $C : IAsyncDisposable { ... } + - pattern-not: | + class $C : $B, IAsyncDisposable { ... } + - pattern-not: | + class $C : IDisposable, IAsyncDisposable { ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.dispose-does-not-dispose-fields + severity: ERROR + languages: + - csharp + message: >- + Dispose this field in the Dispose method of its class. + A disposable class must release the disposable members it creates when it is disposed. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $T $F = new $D(...); ... } + - pattern-inside: | + class $C { ... $R $M(...) { ... $F = new $D(...); ... } ... } + - pattern-inside: | + class $C { ... $C(...) { ... $F = new $D(...); ... } ... } + - metavariable-regex: + metavariable: $D + regex: '^(?:System\.IO\.)?(?:FileStream|StreamReader|StreamWriter|BinaryReader|BinaryWriter|Bitmap|WebClient|TcpClient|UdpClient|Socket|CancellationTokenSource|SqlConnection|SqlCommand|Mutex|Semaphore|SemaphoreSlim|Timer|MemoryStream)$' + - pattern-inside: | + class $C { ... void Dispose() { ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose() { ... $F.Dispose(); ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose() { ... $F?.Dispose(); ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose() { ... $F.Close(); ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose(bool $B) { ... $F.Dispose(); ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose(bool $B) { ... $F?.Dispose(); ... } ... } + - pattern-not-inside: | + class $C { ... void Dispose(bool $B) { ... $F.Close(); ... } ... } + - pattern-either: + - pattern: $T $F = new $D(...); + - pattern: $F = new $D(...) + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.best-practice.dispose-method-without-idisposable + severity: WARNING + languages: + - csharp + message: >- + Implement IDisposable in this class, or rename this 'Dispose' method. + A method named Dispose in a class that is not disposable is misleading: it is not called by using statements. + patterns: + - pattern: | + class $C { ... $R $D() { ... } ... } + - metavariable-regex: + metavariable: $D + regex: '^Dispose$' + - pattern-not: | + class $C : $B { ... } + - pattern-not: | + class $C : $B, $I { ... } + - pattern-not: | + class $C : $B, $I, $J { ... } + - pattern-not: | + class $C : $B, $I, $J, $K { ... } + - focus-metavariable: $D + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.correctness.assertion-arguments-order + severity: WARNING + languages: + - csharp + message: >- + Swap these assertion arguments, the expected value must be passed first. + With the arguments reversed, failure messages report the actual value as the expected one. + patterns: + - pattern-either: + - pattern: Assert.AreEqual($ACTUAL, $EXPECTED, ...) + - pattern: Assert.AreNotEqual($ACTUAL, $EXPECTED, ...) + - pattern: Assert.AreSame($ACTUAL, $EXPECTED, ...) + - pattern: Assert.AreNotSame($ACTUAL, $EXPECTED, ...) + - pattern: Assert.Equal($ACTUAL, $EXPECTED, ...) + - pattern: Assert.NotEqual($ACTUAL, $EXPECTED, ...) + - pattern: Assert.Same($ACTUAL, $EXPECTED, ...) + - pattern: Assert.NotSame($ACTUAL, $EXPECTED, ...) + - metavariable-regex: + metavariable: $EXPECTED + regex: '^(?:-?\d[\w.]*|@?"(?:[^"\\]|\\.)*"|''(?:[^''\\]|\\.)+''|true|false|null)$' + - metavariable-regex: + metavariable: $ACTUAL + regex: '^(?!(?:-?\d[\w.]*|@?"(?:[^"\\]|\\.)*"|''(?:[^''\\]|\\.)+''|true|false|null)$)' + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.invalid-test-method-signature + severity: ERROR + languages: + - csharp + message: >- + Make this test method public, non-generic and returning void or Task. + Test frameworks silently ignore test methods with an unsupported signature. + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + [TestMethod] + $R $M(...) { ... } + - pattern: | + [DataTestMethod] + $R $M(...) { ... } + - pattern: | + [Test] + $R $M(...) { ... } + - pattern: | + [TestCase(...)] + $R $M(...) { ... } + - pattern-not: | + [TestMethod] + public $R $M(...) { ... } + - pattern-not: | + [DataTestMethod] + public $R $M(...) { ... } + - pattern-not: | + [Test] + public $R $M(...) { ... } + - pattern-not: | + [TestCase(...)] + public $R $M(...) { ... } + - pattern: | + [TestMethod] + async void $M(...) { ... } + - pattern: | + [DataTestMethod] + async void $M(...) { ... } + - pattern: | + [Test] + async void $M(...) { ... } + - pattern: | + [Fact] + async void $M(...) { ... } + - pattern: | + [Theory] + async void $M(...) { ... } + - pattern: | + [TestMethod] + $R $M<$T>(...) { ... } + - focus-metavariable: $M + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.service-contract-without-operations + severity: ERROR + languages: + - csharp + message: >- + Add at least one [OperationContract] method to this [ServiceContract] type. + A service contract without operations exposes nothing to the clients of the service. + pattern-regex: '\[[ \t]*ServiceContract\b[^\]]*\]\s*(?:\[[^\]]*\]\s*)*(?:(?:public|internal)[ \t]+)?(?:interface|class)[ \t]+\K\w+(?![^{]*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\[[ \t]*OperationContract\b)' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.best-practice.one-way-operation-returns-value + severity: INFO + languages: + - csharp + message: >- + Make this one-way operation return void. + One-way operations do not send a response, so their return value is never received by the caller. + pattern-regex: '\[[ \t]*OperationContract[ \t]*\((?![^)]*AsyncPattern[ \t]*=[ \t]*true)[^)]*IsOneWay[ \t]*=[ \t]*true[^)]*\)[ \t]*\]\s*(?:(?:public|internal)[ \t]+)?(?!void\b)[\w.<>\[\],?]+[ \t]+\K\w+' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.correctness.params-added-on-override + severity: WARNING + languages: + - csharp + message: >- + Remove the 'params' modifier from this override. + The modifier has no effect on overrides and misleads callers into thinking they can pass a variable number of arguments. + pattern-regex: '\boverride\b[^;{(=]*\((?:[^()]*,)?[ \t]*\Kparams\b' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.pure-method-returns-void + severity: ERROR + languages: + - csharp + message: >- + Remove the [Pure] attribute from this method, or make it return a value. + A pure method has no side effects, so a pure method returning void does nothing useful. + pattern-regex: '\[[ \t]*(?:System\.Diagnostics\.Contracts\.)?Pure(?:Attribute)?[ \t]*\]\s*(?://[^\n]*\s*)*(?:\[[^\]]*\]\s*)*(?:(?:public|private|protected|internal|static|virtual|override|sealed)[ \t]+)*void[ \t]+\K\w+' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.nullable-gettype-comparison + severity: ERROR + languages: + - csharp + message: >- + Remove this comparison of GetType() with a Nullable type, it is always false. + GetType() on a nullable value returns the underlying type, never Nullable. + pattern-regex: '\.GetType\(\)\s*[!=]=\s*typeof\(\s*(?:(?:System\.)?Nullable<[^>]+>|[\w.]+\?)\s*\)|typeof\(\s*(?:(?:System\.)?Nullable<[^>]+>|[\w.]+\?)\s*\)\s*[!=]=\s*[\w.]+\.GetType\(\)' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.nullable-value-without-check + severity: ERROR + languages: + - csharp + message: >- + Check that this nullable variable has a value before accessing '.Value'. + Accessing '.Value' on an empty nullable throws an InvalidOperationException. + patterns: + - pattern-either: + - pattern-inside: | + $T? $X = null; + ... + - patterns: + - pattern-inside: | + $T? $X = $E; + ... + - metavariable-pattern: + metavariable: $E + pattern-either: + - pattern: "$C ? $A : null" + - pattern: "$C ? null : $A" + - pattern: $X.Value + - pattern-not-inside: | + $X = $Y; + ... + - pattern-not-inside: if (<... $X.HasValue ...>) $S; + - pattern-not-inside: if (<... $X != null ...>) $S; + - pattern-not-inside: if (<... $X is not null ...>) $S; + - pattern-not-inside: $X.HasValue && $E + - pattern-not-inside: $X != null && $E + - pattern-not-inside: "$X.HasValue ? $A : $B" + - pattern-not-inside: "$X != null ? $A : $B" + - pattern-not-inside: | + if (!$X.HasValue) { ... return ...; } + ... + - pattern-not-inside: | + if ($X == null) { ... return ...; } + ... + - pattern-not-inside: | + if (!$X.HasValue) { ... throw ...; } + ... + - pattern-not-inside: | + if ($X == null) { ... throw ...; } + ... + options: + constant_propagation: false + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.not-implemented-exception + severity: WARNING + languages: + - csharp + message: >- + Implement this functionality instead of throwing NotImplementedException. + NotImplementedException marks unfinished code that will fail at runtime. + pattern-either: + - pattern: new NotImplementedException(...) + - pattern: new System.NotImplementedException(...) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.exception-thrown-from-unexpected-method + severity: ERROR + languages: + - csharp + message: >- + Remove this 'throw' statement from a method that is not expected to throw. + ToString, Equals, GetHashCode, Dispose, equality and implicit conversion operators, static constructors and event accessors should not throw exceptions. + patterns: + - pattern: throw $E; + - pattern-not: throw new NotImplementedException(...); + - pattern-not: throw new System.NotImplementedException(...); + - pattern-either: + - pattern-inside: | + override string ToString() { ... } + - pattern-inside: | + override bool Equals($T $O) { ... } + - pattern-inside: | + bool Equals($T $O) { ... } + - pattern-inside: | + override int GetHashCode() { ... } + - pattern-inside: | + void Dispose() { ... } + - patterns: + - pattern-regex: '\boperator[ \t]*(?:==|!=)[ \t]*\([^)]*\)\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + - patterns: + - pattern-regex: '\bimplicit[ \t]+operator\b[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + - patterns: + - pattern-regex: '(?m)^[ \t]*static[ \t]+\w+[ \t]*\([ \t]*\)\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + - patterns: + - pattern-regex: '\b(?:add|remove)\s*\{(?![^{}]*\bthrow[ \t]+new[ \t]+(?:System\.)?(?:InvalidOperation|NotSupported|Argument\w*)Exception\b)(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}' + - pattern-not-inside: | + try { ... } catch ($T2 $V) { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.assembly-load-from-path + severity: ERROR + languages: + - csharp + message: >- + Use Assembly.Load() instead of LoadFrom(), LoadFile() or LoadWithPartialName(). + These methods bypass the normal binding context and can load unexpected or duplicate versions of an assembly. + pattern-either: + - pattern: Assembly.LoadFrom(...) + - pattern: Assembly.LoadFile(...) + - pattern: Assembly.LoadWithPartialName(...) + - pattern: System.Reflection.Assembly.LoadFrom(...) + - pattern: System.Reflection.Assembly.LoadFile(...) + - pattern: System.Reflection.Assembly.LoadWithPartialName(...) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.thread-suspend-resume + severity: ERROR + languages: + - csharp + message: >- + Do not use Thread.Suspend() or Thread.Resume(); use proper synchronization primitives instead. + Suspending a thread at an arbitrary point can deadlock the application, and these methods are obsolete. + pattern-either: + - pattern: (Thread $T).Suspend() + - pattern: (Thread $T).Resume() + - pattern: Thread.CurrentThread.Suspend() + - pattern: Thread.CurrentThread.Resume() + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.event-handler-signature + severity: ERROR + languages: + - csharp + message: >- + Use a delegate with the signature 'void (object sender, EventArgs e)' for this event. + Event handlers following the standard signature work with the .NET event infrastructure and are expected by subscribers. + patterns: + - pattern-regex: '\bevent[ \t]+(\w+)[ \t]+\K\w+(?=[ \t]*;)' + - pattern-regex: '\bdelegate[ \t]+(?!void[ \t]+(\w+)[ \t]*\([ \t]*object\??[ \t]+\w+[ \t]*,[ \t]*[\w.]+[ \t]+\w+[ \t]*\))[\w.<>]+[ \t]+(\w+)[ \t]*\([^)]*\)[\s\S]*?\bevent[ \t]+\2[ \t]+\w+[ \t]*;' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.iserializable-incorrect-implementation + severity: ERROR + languages: + - csharp + message: >- + Implement ISerializable correctly: mark the type [Serializable] and add a serialization constructor. + Without them, the runtime cannot serialize or deserialize instances of the type. + pattern-either: + - patterns: + - pattern-regex: '\bclass[ \t]+\K\w+(?=[^{;]*:[^{;]*\bISerializable\b)' + - pattern-not-inside: | + class $C { ... $C(SerializationInfo $I, StreamingContext $X) { ... } ... } + - pattern-not-inside: | + class $C { ... $C(SerializationInfo $I, StreamingContext $X) : base(...) { ... } ... } + - patterns: + - pattern-regex: '\bclass[ \t]+\K\w+(?=[^{;]*:[^{;]*\bISerializable\b)' + - pattern-not-inside: | + [Serializable] + class $C { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.optional-field-without-deserialization-handler + severity: ERROR + languages: + - csharp + message: >- + Add a deserialization event handler to initialize the [OptionalField] members of this class. + Optional fields are not set when older serialized data is deserialized, so they keep their default values. + patterns: + - pattern-either: + - pattern: | + class $C { ... [OptionalField] $T $F; ... } + - pattern: | + class $C { ... [OptionalField(...)] $T $F; ... } + - pattern: | + class $C { ... [OptionalField] $T $F = $V; ... } + - pattern: | + class $C { ... [OptionalField(...)] $T $F = $V; ... } + - pattern-not: | + class $C { ... [OnDeserialized] $R $M(...) { ... } ... } + - pattern-not: | + class $C { ... [OnDeserializing] $R $M(...) { ... } ... } + - focus-metavariable: $C + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.serialization-handler-signature + severity: ERROR + languages: + - csharp + message: >- + Make this serialization event handler private, non-generic, returning void and taking a single StreamingContext parameter. + Handlers with another signature are not called, or raise errors during serialization. + patterns: + - pattern-either: + - patterns: + - pattern: | + [OnSerializing] + $R $M(...) { ... } + - pattern-not: | + [OnSerializing] + private void $M(StreamingContext $C) { ... } + - patterns: + - pattern: | + [OnSerialized] + $R $M(...) { ... } + - pattern-not: | + [OnSerialized] + private void $M(StreamingContext $C) { ... } + - patterns: + - pattern: | + [OnDeserializing] + $R $M(...) { ... } + - pattern-not: | + [OnDeserializing] + private void $M(StreamingContext $C) { ... } + - patterns: + - pattern: | + [OnDeserialized] + $R $M(...) { ... } + - pattern-not: | + [OnDeserialized] + private void $M(StreamingContext $C) { ... } + - focus-metavariable: $M + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.argument-exception-parameter-name + severity: ERROR + languages: + - csharp + message: >- + Pass the name of an existing parameter to the ArgumentException thrown by this method. + An argument exception without a valid parameter name does not tell the caller which argument is wrong. + pattern-either: + - pattern: new ArgumentException() + - pattern: new ArgumentNullException() + - pattern: new ArgumentOutOfRangeException() + - pattern-regex: '\b\K\w+[ \t]*(?:<[^<>()]*>)?[ \t]*\((?=[^()]*\)(?:\s*//[^\n]*)*\s*(?:where[^{]*)?\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\bnew[ \t]+(?:Argument(?:Null|OutOfRange)Exception[ \t]*\([ \t]*|ArgumentException[ \t]*\([ \t]*(?:[^,()]|\([^()]*\))+,[ \t]*)"(\w+)")(?![^()]*\b\1\b)' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.object-disposed-twice + severity: ERROR + languages: + - csharp + message: >- + Remove this redundant Dispose() call, the object is already disposed. + Disposing an object twice is a sign of confused ownership and some implementations throw ObjectDisposedException. + pattern-either: + - pattern-regex: '\b(\w+)\.Dispose\(\)[ \t]*;(?:(?!\b\1[ \t]*=[^=])(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\}))*?\K\b\1\.Dispose\(\)[ \t]*;' + - pattern-regex: '\busing[ \t]*\([ \t]*(?:var|[\w.<>]+)[ \t]+(\w+)[ \t]*=[^;{]*\)\s*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\K\b\1\.Dispose\(\)[ \t]*;' + - pattern-regex: '\busing[ \t]+(?:var|[\w.<>]+)[ \t]+(\w+)[ \t]*=[^;]*;(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\K\b\1\.Dispose\(\)[ \t]*;' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.suppress-finalize-outside-dispose + severity: ERROR + languages: + - csharp + message: >- + Call GC.SuppressFinalize() only from a Dispose implementation. + Suppressing finalization elsewhere can prevent unmanaged resources from ever being released. + patterns: + - pattern: GC.SuppressFinalize($X) + - pattern-not-inside: | + void Dispose() { ... } + - pattern-not-inside: | + void Dispose(bool $D) { ... } + - pattern-not-inside: | + ValueTask DisposeAsync() { ... } + - pattern-not-inside: | + Task DisposeAsync() { ... } + - pattern-not-regex: '\bvoid[ \t]+(?:System\.)?IDisposable\.Dispose[ \t]*\([ \t]*\)\s*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.nonsensical-size-comparison + severity: WARNING + languages: + - csharp + message: >- + Remove this comparison of a collection size or array length with a negative value, its result is always the same. + Sizes and lengths are never negative. + patterns: + - pattern-either: + - pattern: $X.$P >= 0 + - pattern: $X.$P < 0 + - pattern: 0 <= $X.$P + - pattern: 0 > $X.$P + - pattern: $X.$P() >= 0 + - pattern: $X.$P() < 0 + - metavariable-regex: + metavariable: $P + regex: '^(?:Count|Length|LongLength|LongCount)$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.exception-created-not-thrown + severity: ERROR + languages: + - csharp + message: >- + Throw this exception or remove its creation. + Creating an exception without throwing it has no effect, the 'throw' keyword was probably forgotten. + patterns: + - pattern: new $E(...); + - metavariable-regex: + metavariable: $E + regex: '.*Exception$' + - pattern-not-inside: $V = $X; + - pattern-not-inside: $TY $V = $X; + - pattern-not-inside: var $V = $X; + - pattern-not-inside: return $X; + - pattern-not-inside: throw $X; + - pattern-not-inside: $F(...); + - pattern-not-inside: $O.$F(...); + - pattern-not-regex: '=>\s*new\b[^;]*;' + options: + implicit_deep_exprstmt: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.lock-on-weak-identity-object + severity: ERROR + languages: + - csharp + message: >- + Lock on a dedicated private object instead of an object with a weak identity. + Objects such as strings, types, threads or some exceptions can be shared across application domains, which can cause deadlocks. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $T $F; ... } + - pattern-inside: | + class $C { ... $T $F = $I; ... } + - metavariable-regex: + metavariable: $T + regex: '^(?:System\.)?(?:string|String|Type|Thread|MemberInfo|ParameterInfo|MethodInfo|FieldInfo|PropertyInfo|ConstructorInfo|ExecutionEngineException|OutOfMemoryException|StackOverflowException|MarshalByRefObject)$' + - pattern-either: + - pattern: lock ($F) { ... } + - pattern: lock (this.$F) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.disposable-without-finalizer + severity: ERROR + languages: + - csharp + message: >- + Add a finalizer to this disposable type that holds unmanaged handles. + Without a finalizer, the unmanaged resource leaks when the object is not disposed explicitly. + patterns: + - pattern-regex: '\bclass[ \t]+\K\w+(?=[^{;]*:[^{;]*\bIDisposable\b)' + - pattern-either: + - pattern-inside: | + class $C { ... IntPtr $F; ... } + - pattern-inside: | + class $C { ... UIntPtr $F; ... } + - pattern-inside: | + class $C { ... HandleRef $F; ... } + - pattern-inside: | + class $C { ... IntPtr $F = $V; ... } + - pattern-not-regex: '\bclass[ \t]+(\w+)[\s\S]*?~\1[ \t]*\(' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.iequatable-class-not-sealed + severity: ERROR + languages: + - csharp + message: >- + Seal this class, or make its Equals method virtual. + Derived classes cannot change how equality is computed, which leads to inconsistent results when comparing instances of different types. + patterns: + - pattern-regex: '\bclass[ \t]+\K(\w+)(?=[^{;]*:[^{;]*\bIEquatable[ \t]*<[ \t]*\1[ \t]*>)' + - pattern-not-inside: | + sealed class $C { ... } + - pattern-not-inside: | + class $C { ... virtual bool Equals($T $O) { ... } ... } + - pattern-not-inside: | + class $C { ... virtual bool Equals($T $O) => $E; ... } + - pattern-not-inside: | + class $C { ... abstract bool Equals($T $O); ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.flags-enum-invalid-value + severity: ERROR + languages: + - csharp + message: >- + Use a power of two, or a combination of other members, for this [Flags] enumeration member. + Values that are neither single bits nor combinations of other flags make bitwise operations unreliable. + patterns: + - pattern-regex: '(?:[{,])\s*(?://[^\n]*\s*)*(?\w+)[ \t]*=[ \t]*(?\d+)\b(?=[^{}]*\})' + - pattern-regex: '\[[ \t]*(?:System\.)?Flags(?:Attribute)?[ \t]*\][^;{}]*?\benum\b[^{]*\{[^{}]*\}' + - metavariable-comparison: + comparison: int($VAL) > 0 and (int($VAL) & (int($VAL) - 1)) != 0 + - focus-metavariable: $NAME + metadata: + category: correctness + confidence: LOW + - id: codacy.csharp.correctness.collection-element-overwritten + severity: WARNING + languages: + - csharp + message: >- + Verify this element replacement, the previous value is overwritten without being used. + Assigning the same collection element twice in a row is usually a copy-paste mistake. + patterns: + - pattern-either: + - pattern-inside: | + $L[$I] = $A; + $L[$I] = $B; + - pattern-inside: | + $L.Add($I, $A); + $L[$I] = $B; + - pattern: $L[$I] = $B; + - pattern-not: $L[$I] = <... $L[$I] ...>; + options: + constant_propagation: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.empty-collection-accessed + severity: WARNING + languages: + - csharp + message: >- + Remove this access to an empty collection, or add elements to it first. + Reading, removing from or iterating over a collection that was just created empty is pointless and probably a bug. + patterns: + - pattern-either: + - pattern-inside: | + var $X = new $C(); + ... + - pattern-inside: | + $T $X = new $C(); + ... + - metavariable-regex: + metavariable: $C + regex: '^(?:System\.Collections\.Generic\.)?(?:List|HashSet|Dictionary|Queue|Stack|SortedSet|SortedDictionary|SortedList|LinkedList)<.*>$' + - pattern-either: + - patterns: + - pattern: $X.$M(...) + - metavariable-regex: + metavariable: $M + regex: '^(?:Remove|RemoveAt|RemoveAll|Contains|ContainsKey|ContainsValue|IndexOf|Find|FindAll|Exists|Clear|Pop|Dequeue|Peek|First|Last|ElementAt)$' + - pattern: foreach ($T2 $V in $X) $S; + - pattern: foreach (var $V in $X) $S; + - pattern-not-inside: | + $R $METH(...) { ... $X.Add(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.AddRange(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.Insert(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.Push(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.Enqueue(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.TryAdd(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X.UnionWith(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $X[$K] = $W; ... } + - pattern-not-inside: | + $R $METH(...) { ... $F(..., $X, ...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $O.$F(..., $X, ...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $Y = $X; ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.export-without-implementation + severity: ERROR + languages: + - csharp + message: >- + Implement the exported interface in this class, or change the type passed to the Export attribute. + MEF fails at runtime when an exported part does not implement the contract type it exports. + pattern-regex: '\[[ \t]*(?:Inherited)?Export[ \t]*\([ \t]*typeof[ \t]*\([ \t]*[\w.]+[ \t]*\)[^\]]*\]\s*(?:\[[^\]]*\]\s*)*(?:(?:public|internal|sealed|abstract|partial)[ \t]+)*class[ \t]+\K\w+(?=[ \t]*(?:<[^>]*>)?(?:\s*//[^\n]*)*\s*\{)' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.missing-stathread-on-windows-forms-main + severity: ERROR + languages: + - csharp + message: >- + Add the [STAThread] attribute to this Windows Forms entry point. + Windows Forms requires the single-threaded apartment model; without it, features such as the clipboard and dialogs fail. + patterns: + - pattern: | + static void Main(...) { ... Application.Run(...); ... } + - pattern-not: | + [STAThread] + static void Main(...) { ... } + - pattern-not: | + [System.STAThread] + static void Main(...) { ... } + - pattern-not: | + [STAThreadAttribute] + static void Main(...) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.invalid-event-arguments + severity: ERROR + languages: + - csharp + message: >- + Pass a non-null sender and a non-null EventArgs instance when raising this event. + Event handlers expect a valid sender for instance events and EventArgs.Empty when there is no data. + patterns: + - pattern-inside: | + class $C { ... event $T $E; ... } + - pattern-either: + - pattern: $E?.Invoke($S, null) + - pattern: $E.Invoke($S, null) + - pattern: $E($S, null) + - patterns: + - pattern-either: + - pattern: $E?.Invoke(null, $A) + - pattern: $E.Invoke(null, $A) + - pattern: $E(null, $A) + - pattern-not-inside: | + static $R $M(...) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.shared-part-instantiated + severity: ERROR + languages: + - csharp + message: >- + Get this shared MEF part from the composition container instead of creating it with 'new'. + Instantiating it directly creates a second instance, defeating the shared creation policy. + patterns: + - pattern: new $C(...) + - pattern-inside: | + [PartCreationPolicy(CreationPolicy.Shared)] + class $C { ... } + ... + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.part-creation-policy-without-export + severity: WARNING + languages: + - csharp + message: >- + Add an Export attribute to this class, or remove its PartCreationPolicy attribute. + The creation policy has no effect on classes that are not exported MEF parts. + pattern-regex: '(?m)^(?- + Move this argument validation to a non-iterator method that calls the iterator. + Code in an iterator method only runs when the result is enumerated, so invalid arguments are reported too late. + patterns: + - pattern: throw new $E(...); + - metavariable-regex: + metavariable: $E + regex: '^(?:System\.)?Argument\w*Exception$' + - pattern-inside: | + $R $M(...) { ... yield return $X; ... } + - pattern-not-inside: | + ($P) => { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.async-argument-validation + severity: ERROR + languages: + - csharp + message: >- + Move this argument validation to a non-async method that calls the async implementation. + Exceptions thrown in an async method are stored in the returned task, so callers only see them when they await it. + patterns: + - pattern: throw new $E(...); + - metavariable-regex: + metavariable: $E + regex: '^(?:System\.)?Argument\w*Exception$' + - pattern-inside: | + async $R $M(...) { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + async ($P) => { ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.blocking-async-call + severity: ERROR + languages: + - csharp + message: >- + Await this task instead of blocking on it. + Blocking with .Result, .Wait() or GetAwaiter().GetResult() can deadlock when a synchronization context is present and wastes threads. + pattern-either: + - patterns: + - pattern-either: + - pattern: $O.$M(...).Result + - pattern: $O.$M(...).Wait(...) + - pattern: $M(...).Result + - pattern: $M(...).Wait(...) + - metavariable-regex: + metavariable: $M + regex: '.*Async$' + - pattern: $X.GetAwaiter().GetResult() + - pattern: Task.WaitAll(...) + - pattern: Task.WaitAny(...) + - pattern: (Task $T).Wait(...) + - pattern: (Task<$R> $T).Result + - pattern: (Task<$R> $T).Wait(...) + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.begininvoke-without-endinvoke + severity: ERROR + languages: + - csharp + message: >- + Call EndInvoke for this BeginInvoke call, or pass a callback that calls it. + Without EndInvoke, resources are leaked and exceptions thrown by the delegate are lost. + patterns: + - pattern: $D.BeginInvoke(..., null, $STATE) + - pattern-inside: | + $R $M(...) { ... } + - pattern-not-inside: | + $R $M(...) { ... $D.EndInvoke(...); ... } + - pattern-not-inside: | + $R $M(...) { ... $V = $D.EndInvoke(...); ... } + - pattern-not-inside: | + $R $M(...) { ... var $V = $D.EndInvoke(...); ... } + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.null-returned-from-task-method + severity: ERROR + languages: + - csharp + message: >- + Return Task.CompletedTask or Task.FromResult() instead of null from this method. + Awaiting a null task throws a NullReferenceException. + patterns: + - pattern: return null; + - pattern-either: + - pattern-inside: | + Task $M(...) { ... } + - pattern-inside: | + Task<$T> $M(...) { ... } + - pattern-inside: | + ValueTask<$T> $M(...) { ... } + - pattern-not-inside: | + async $R $M(...) { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + () => { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.valuetask-consumed-incorrectly + severity: ERROR + languages: + - csharp + message: >- + Await this ValueTask only once, and do not block on it before it has completed. + A ValueTask may be backed by a pooled object that is reused after the first await. + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + ValueTask<$T> $V = $E; + ... + - pattern-inside: | + ValueTask $V = $E; + ... + - pattern: await $V + - pattern-regex: '\bawait[ \t]+(\w+)\b[\s\S]*?\K\bawait[ \t]+\1\b' + - patterns: + - pattern-either: + - pattern-inside: | + ValueTask<$T> $V = $E; + ... + - pattern-either: + - pattern: $V.Result + - pattern: $V.GetAwaiter().GetResult() + - pattern-not-inside: if (<... $V.IsCompleted ...>) $S; + - pattern-not-inside: if (<... $V.IsCompletedSuccessfully ...>) $S; + - pattern-not-inside: "$V.IsCompletedSuccessfully ? $A : $B" + - pattern-not-inside: "$V.IsCompleted ? $A : $B" + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.invalid-regular-expression + severity: ERROR + languages: + - csharp + message: >- + Correct the syntax of this regular expression. + An invalid pattern throws an ArgumentException when the regular expression is created or used. + patterns: + - pattern-either: + - pattern: new Regex("$P", ...) + - pattern: Regex.IsMatch($I, "$P", ...) + - pattern: Regex.Match($I, "$P", ...) + - pattern: Regex.Matches($I, "$P", ...) + - pattern: Regex.Replace($I, "$P", ...) + - pattern: Regex.Split($I, "$P", ...) + - metavariable-regex: + metavariable: $P + regex: '^(?!(?:[^()\[\]\\]|\\.|\[\^?\]?(?:[^\]\\]|\\.)*\]|\((?:[^()\[\]\\]|\\.|\[\^?\]?(?:[^\]\\]|\\.)*\]|\((?:[^()\[\]\\]|\\.|\[\^?\]?(?:[^\]\\]|\\.)*\]|\((?:[^()\[\]\\]|\\.|\[\^?\]?(?:[^\]\\]|\\.)*\])*\))*\))*\))*$)|^[*+?]' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.correctness.lock-on-local-variable + severity: ERROR + languages: + - csharp + message: >- + Lock on a field shared by all threads instead of this local variable. + Each call creates its own local object, so the lock does not synchronize anything. + patterns: + - pattern-either: + - pattern-inside: | + $R $M(...) { ... $T $X = $E; ... } + - pattern-inside: | + $R $M(...) { ... var $X = $E; ... } + - pattern: lock ($X) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.datetime-without-kind + severity: ERROR + languages: + - csharp + message: >- + Provide the DateTimeKind when creating this DateTime. + Without it, the kind is Unspecified and conversions between local time and UTC become ambiguous. + patterns: + - pattern-either: + - pattern: new DateTime($Y, $M, $D) + - pattern: new DateTime($Y, $M, $D, $H, $MI, $S) + - pattern: new DateTime($Y, $M, $D, $H, $MI, $S, $MS) + - pattern: new DateTime($TICKS) + - pattern: new System.DateTime($Y, $M, $D) + - pattern: new System.DateTime($Y, $M, $D, $H, $MI, $S) + - pattern-not: new DateTime($Y, $M, $D, $H, $MI, $S, DateTimeKind.$K) + - pattern-not: new DateTime($Y, $M, $D, $H, $MI, $S, System.DateTimeKind.$K) + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.date-parse-without-format-provider + severity: ERROR + languages: + - csharp + message: >- + Pass an IFormatProvider, such as CultureInfo.InvariantCulture, when parsing this date or time. + Without it, the parsing depends on the culture of the machine and can give different results or fail. + patterns: + - pattern-either: + - pattern: $T.Parse($S) + - pattern: $T.TryParse($S, $R) + - pattern: $T.ParseExact($S, $F, null) + - pattern: $T.ParseExact($S, $F, null, $ST) + - pattern: $T.TryParseExact($S, $F, null, $ST, $R) + - metavariable-regex: + metavariable: $T + regex: '^(?:System\.)?(?:DateTime|DateTimeOffset|TimeSpan|DateOnly|TimeOnly)$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.logging-arguments-in-message-arguments + severity: ERROR + languages: + - csharp + message: >- + Pass this exception as the dedicated exception parameter of the logging call instead of as a message argument. + Exceptions passed as message arguments lose their stack trace and are not handled by logging providers. + patterns: + - pattern-either: + - pattern-inside: | + try { ... } catch ($T $E) { ... } + - pattern-inside: | + try { ... } catch ($T $E) { ... } finally { ... } + - pattern: $L.$LOG("$MSG", ..., $E, ...) + - metavariable-regex: + metavariable: $LOG + regex: '^Log(?:Trace|Debug|Information|Warning|Error|Critical)?$' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.log-template-argument-order + severity: ERROR + languages: + - csharp + message: >- + Reorder the arguments of this logging call to match the order of the placeholders in the message template. + Placeholders are filled by position, so swapped arguments produce misleading log entries. + pattern-regex: '\.(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|Verbose|Debug|Information|Warning|Error|Fatal)[ \t]*\(\s*(?:[^"(),]+,\s*)*\K"[^"]*\{(\w+)(?:[,:][^}]*)?\}[^"]*\{(\w+)(?:[,:][^}]*)?\}[^"]*"\s*,\s*(?:[\w.]*\.)?(?i:\2)\s*,\s*(?:[\w.]*\.)?(?i:\1)\s*\)' + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.correctness.invalid-log-message-template + severity: ERROR + languages: + - csharp + message: >- + Correct the syntax of this log message template. + Placeholder names may only contain letters, digits and underscores, optionally followed by an alignment and a format. + patterns: + - pattern-either: + - pattern: $L.$LOG("$T", ...) + - pattern: $L.$LOG($X, "$T", ...) + - pattern: $L.$LOG($X, $Y, "$T", ...) + - metavariable-regex: + metavariable: $LOG + regex: '^(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|BeginScope|Verbose|Debug|Information|Warning|Error|Fatal)$' + - metavariable-regex: + metavariable: $T + regex: '(?s).*(?- + Make this [JSInvokable] method public. + JavaScript interop can only invoke public methods, so the call fails at runtime. + patterns: + - pattern: | + [JSInvokable] + $R $M(...) { ... } + - pattern-not: | + [JSInvokable] + public $R $M(...) { ... } + - focus-metavariable: $M + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.best-practice.test-class-without-tests + severity: WARNING + languages: + - csharp + message: >- + Add at least one test method to this test class. + A test class without tests gives the false impression that the tested code is covered. + pattern-either: + - patterns: + - pattern: | + [TestClass] + class $C { ... } + - pattern-not: | + [TestClass] + class $C { ... [TestMethod] $R $M(...) { ... } ... } + - pattern-not: | + [TestClass] + class $C { ... [DataTestMethod] $R $M(...) { ... } ... } + - pattern-not: | + [TestClass] + class $C { ... [AssemblyInitialize] $R $M(...) { ... } ... } + - pattern-not: | + [TestClass] + class $C { ... [AssemblyCleanup] $R $M(...) { ... } ... } + - pattern-not: | + [TestClass] + abstract class $C { ... } + - pattern-not: | + [TestClass] + class $C : $B { ... } + - focus-metavariable: $C + - patterns: + - pattern: | + [TestFixture] + class $C { ... } + - pattern-not: | + [TestFixture] + class $C { ... [Test] $R $M(...) { ... } ... } + - pattern-not: | + [TestFixture] + class $C { ... [TestCase(...)] $R $M(...) { ... } ... } + - pattern-not: | + [TestFixture] + class $C { ... [TestCaseSource(...)] $R $M(...) { ... } ... } + - pattern-not: | + [TestFixture] + class $C { ... [Theory] $R $M(...) { ... } ... } + - pattern-not: | + [TestFixture] + abstract class $C { ... } + - pattern-not: | + [TestFixture] + class $C : $B { ... } + - focus-metavariable: $C + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.test-without-assertion + severity: ERROR + languages: + - csharp + message: >- + Add at least one assertion to this test method. + A test without assertions only checks that no exception is thrown and gives a false sense of security. + pattern-regex: '\[[ \t]*(?:TestMethod|DataTestMethod|Test|TestCase|Fact|Theory)\b[^\]]*\]\s*(?:\[[^\]]*\]\s*)*(?:(?:public|private|protected|internal|async|static|virtual|override)[ \t]+)*[\w.<>]+[ \t]+\K\w+(?=[ \t]*\([^)]*\)(?:\s*//[^\n]*)*\s*\{(?:(?!\b(?:Assert\w*|Should\w*|Verify\w*|Received\w*|Expect\w*|Check|Throws\w*|Fail|Must\w*)\b)[^{}]|\{(?:(?!\b(?:Assert\w*|Should\w*|Verify\w*|Received\w*|Expect\w*|Check|Throws\w*|Fail|Must\w*)\b)[^{}]|\{(?:(?!\b(?:Assert\w*|Should\w*|Verify\w*|Received\w*|Expect\w*|Check|Throws\w*|Fail|Must\w*)\b)[^{}]|\{(?:(?!\b(?:Assert\w*|Should\w*|Verify\w*|Received\w*|Expect\w*|Check|Throws\w*|Fail|Must\w*)\b)[^{}])*\})*\})*\})*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.correctness.incomplete-assertion + severity: ERROR + languages: + - csharp + message: >- + Complete this assertion, it does not verify anything yet. + Calls such as 'actual.Should()' or 'Check.That(actual)' only start an assertion chain. + patterns: + - pattern-either: + - pattern: $X.Should(); + - pattern: Check.That($X); + - pattern: Check.ThatCode($X); + - pattern: $S.Received(); + - pattern: $S.Received($N); + - pattern: $S.DidNotReceive(); + - pattern: $S.ReceivedWithAnyArgs(); + - pattern-not-inside: $V = $E; + - pattern-not-inside: var $V = $E; + - pattern-not-inside: return $E; + options: + implicit_deep_exprstmt: false + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.security.console-output-logging + severity: ERROR + languages: + - csharp + message: >- + Use a dedicated logging framework instead of writing to the console. + Console output cannot be filtered, routed or secured, and may disclose sensitive information. + patterns: + - pattern-either: + - pattern: Console.Write(...) + - pattern: Console.WriteLine(...) + - pattern: Console.Out.$M(...) + - pattern: Console.Error.$M(...) + - pattern: System.Console.Write(...) + - pattern: System.Console.WriteLine(...) + - pattern-not-regex: '(?s)#if[ \t]+DEBUG\b.*?#endif' + - pattern-not-regex: '\[[ \t]*Conditional[ \t]*\([ \t]*"DEBUG"[ \t]*\)[ \t]*\][^{]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + metadata: + category: security + cwe: "CWE-532: Insertion of Sensitive Information into Log File" + owasp: "A09:2021 - Security Logging and Monitoring Failures" + confidence: LOW + - id: codacy.csharp.best-practice.hardcoded-uri + severity: WARNING + languages: + - csharp + message: >- + Do not hardcode this URI or absolute path, read it from configuration instead. + Hardcoded locations break when the application is deployed to another environment. + patterns: + - pattern: '"$S"' + - metavariable-regex: + metavariable: $S + regex: '^(?:[a-zA-Z][\w+.-]*://[^\s/]+\S*|[a-zA-Z]:\\{1,2}\S+|\\{2,4}\w\S+|/(?:[\w.-]+/)+[\w.-]+)$' + - metavariable-regex: + metavariable: $S + regex: '^(?!https?://(?:www\.)?(?:w3\.org|schemas\.|purl\.org|xmlns\.))' + - pattern-not-regex: '(?m)^[ \t]*\[[^\n]*\][ \t]*(?://[^\n]*)?$' + options: + constant_propagation: false + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.codestyle.empty-nested-block + severity: INFO + languages: + - csharp + message: >- + Fill this empty block, or remove it. + An empty block without a comment makes it unclear whether code is missing or the block is empty on purpose. + pattern-either: + - pattern-regex: '\b\K(?:if|while|for|foreach|lock|using|switch|fixed)[ \t]*\((?:[^()]|\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\))*\)\s*\{\s*\}' + - pattern-regex: '\b\K(?:else|try|finally|do)\s*\{\s*\}' + - pattern-regex: '\b\Kcatch\b(?:[ \t]*\([^()]*\))?(?:\s*when\s*\((?:[^()]|\([^()]*\))*\))?\s*\{\s*\}' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.magic-number + severity: INFO + languages: + - csharp + message: >- + Replace this magic number with a named constant. + Unnamed numeric literals hide their meaning and must be changed in many places when their value changes. + patterns: + - pattern: $N + - metavariable-regex: + metavariable: $N + regex: '^(?!(?:0+|1)(?:\.0+)?[uUlLfFdDmM]{0,2}$)(?:\d[\d_]*(?:\.\d+)?|0[xX][\da-fA-F_]+|0[bB][01_]+)[uUlLfFdDmM]{0,2}$' + - pattern-not-inside: $T $V = $E; + - pattern-not-inside: var $V = $E; + - pattern-not-inside: const $T $V = $E; + - pattern-not-inside: new $T(...) + - pattern-not-inside: | + override int GetHashCode() { ... } + - pattern-not-inside: | + enum $EN { ... } + - pattern-not-regex: '(?m)^[ \t]*\[[^\n]*\][ \t]*(?://[^\n]*)?$' + - pattern-not-regex: '\b\w+[ \t]*:[ \t]*-?[\d.]+\w*(?=[ \t]*[,)])' + - pattern-not-regex: '(?])=(?!=)[ \t]*-?\d[\w.]*(?=[ \t]*[,)])' + metadata: + category: codestyle + confidence: LOW + - id: codacy.csharp.best-practice.public-field + severity: WARNING + languages: + - csharp + message: >- + Make this field private and encapsulate it in a property. + Public fields expose the internal representation of a class and cannot be validated or changed later without breaking callers. + patterns: + - pattern-either: + - pattern: | + class $C { ... public $T $F; ... } + - pattern: | + class $C { ... public $T $F = $V; ... } + - pattern-not: | + class $C { ... public readonly $T $F; ... } + - pattern-not: | + class $C { ... public readonly $T $F = $V; ... } + - pattern-not: | + class $C { ... public const $T $F = $V; ... } + - pattern-not: | + class $C { ... public static readonly $T $F = $V; ... } + - pattern-not: | + [StructLayout(...)] + class $C { ... } + - pattern-not: | + [Serializable] + class $C { ... } + - pattern-not: | + class $C { ... public event $T $F; ... } + - focus-metavariable: $F + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.obsolete-without-explanation + severity: INFO + languages: + - csharp + message: >- + Add an explanation to this Obsolete attribute. + Callers need to know why the member is deprecated and what to use instead. + pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\K(?:System\.)?Obsolete(?:Attribute)?(?=[ \t]*(?:\([ \t]*\))?[ \t]*[,\]])' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.deprecated-code + severity: WARNING + languages: + - csharp + message: >- + Do not forget to remove this deprecated code someday. + Code marked as obsolete should eventually be removed to keep the code base clean. + pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\K(?:System\.)?Obsolete(?:Attribute)?\b' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.correctness.exit-method-call + severity: ERROR + languages: + - csharp + message: >- + Do not terminate the application from here. + Calling Environment.Exit or Application.Exit outside of the entry point prevents callers from cleaning up and makes the code hard to reuse. + patterns: + - pattern-either: + - pattern: Environment.Exit(...) + - pattern: Application.Exit(...) + - pattern: System.Environment.Exit(...) + - pattern-not-inside: | + static $R Main(...) { ... } + metadata: + category: correctness + confidence: HIGH + - id: codacy.csharp.performance.count-used-to-check-emptiness + severity: WARNING + languages: + - csharp + message: >- + Use Any() to test whether this collection is empty. + Count() may enumerate the whole sequence, while Any() stops at the first element. + pattern-either: + - pattern: $X.Count() > 0 + - pattern: $X.Count() != 0 + - pattern: $X.Count() >= 1 + - pattern: $X.Count() == 0 + - pattern: $X.Count() < 1 + - pattern: 0 < $X.Count() + - pattern: 0 != $X.Count() + - pattern: 0 == $X.Count() + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.null-returned-for-collection + severity: WARNING + languages: + - csharp + message: >- + Return an empty array or collection instead of null. + Returning null forces every caller to add a null check before iterating the result. + patterns: + - pattern: return null; + - pattern-inside: | + $R $M(...) { ... } + - metavariable-regex: + metavariable: $R + regex: '^(?:[\w.]+(?:<[^<>]*>)?\[\]|(?:System\.Collections\.Generic\.)?(?:IEnumerable|ICollection|IList|IReadOnlyList|IReadOnlyCollection|List|Collection|ISet|HashSet|IDictionary|IReadOnlyDictionary|Dictionary)(?:<.*>)?)$' + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + () => { ... } + - pattern-not-inside: | + $P => { ... } + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.unused-private-method-parameter + severity: WARNING + languages: + - csharp + message: >- + Remove this unused method parameter. + Unused parameters are misleading, and callers have to compute values that are never used. + pattern-regex: '(?m)^(?\[\],?]+[ \t]+(?!Main\b)\w+[ \t]*(?:<[^<>()]*>)?[ \t]*\((?:[^()]*,)?[ \t]*(?:(?:ref|out|in|params)[ \t]+)?[\w.<>\[\],?]+[ \t]+\K(\w+)(?=[ \t]*(?:=[^,()]*)?(?:,[^()]*)?\)[ \t]*(?://[^\n]*)?\s*\{(?!\s*\})(?!\s*throw[ \t]+new[ \t]+(?:System\.)?NotImplementedException)(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}])*\})*\})*\})*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.override-only-calls-base + severity: INFO + languages: + - csharp + message: >- + Remove this override, it only calls the overridden member. + An override that just forwards to the base implementation adds nothing. + patterns: + - pattern-either: + - pattern: | + override $R $M() { return base.$M(); } + - pattern: | + override $R $M($T1 $A) { return base.$M($A); } + - pattern: | + override $R $M($T1 $A, $T2 $B) { return base.$M($A, $B); } + - pattern: | + override $R $M($T1 $A, $T2 $B, $T3 $C) { return base.$M($A, $B, $C); } + - pattern: | + override void $M() { base.$M(); } + - pattern: | + override void $M($T1 $A) { base.$M($A); } + - pattern: | + override void $M($T1 $A, $T2 $B) { base.$M($A, $B); } + - pattern: | + override void $M($T1 $A, $T2 $B, $T3 $C) { base.$M($A, $B, $C); } + - focus-metavariable: $M + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.empty-method + severity: WARNING + languages: + - csharp + message: >- + Add a nested comment explaining why this method is empty, throw a NotSupportedException or complete the implementation. + An empty method may hide missing code and confuses readers about its purpose. + pattern-regex: '(?m)^[ \t]*(?![^\n]*\b(?:virtual|override|abstract|extern|partial|delegate)\b)(?:(?:public|private|protected|internal|static|async|unsafe|new|sealed)[ \t]+)*(?!(?:return|else|new|await|throw|yield|case|goto|using)\b)[\w.<>\[\],?]+[ \t]+\K(?!(?:if|while|for|foreach|switch|catch|using|lock|fixed|return|new|else|await|throw|typeof|nameof|sizeof|default|when)\b)\w+(?=[ \t]*(?:<[^<>()]*>)?[ \t]*\([^()]*\)[ \t]*(?:where[^{\n]*)?\s*\{\s*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.nested-code-block + severity: WARNING + languages: + - csharp + message: >- + Extract this nested code block into a separate method. + Bare nested blocks are usually a sign that the method does too many things. + pattern-regex: '(?m)[;{][ \t]*(?://[^\n]*)?\r?\n[ \t]*\K\{[ \t]*(?://[^\n]*)?$' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.performance.gc-collect + severity: ERROR + languages: + - csharp + message: >- + Remove this explicit garbage collection call. + Forcing a garbage collection is expensive and usually degrades performance; the runtime knows better when to collect. + pattern-either: + - pattern: GC.Collect(...) + - pattern: System.GC.Collect(...) + - pattern: GC.GetTotalMemory(true) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.codestyle.break-outside-switch + severity: INFO + languages: + - csharp + message: >- + Refactor this loop so that it does not need a 'break' statement. + Loops with break statements have several exit points, which makes them harder to understand. + patterns: + - pattern: break; + - pattern-not-inside: | + switch ($X) { case $A: ... } + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.logger-field-not-private-static-readonly + severity: WARNING + languages: + - csharp + message: >- + Make this logger field 'private static readonly'. + A logger is shared by all instances of a class and should not be exposed or reassigned. + patterns: + - pattern: | + class $C { ... $T $F = $INIT; ... } + - metavariable-regex: + metavariable: $T + regex: '^(?:log4net\.)?(?:ILog|Logger|NLog\.Logger|ILogger|Serilog\.ILogger)$' + - metavariable-regex: + metavariable: $INIT + regex: '(?s).*(?:LogManager\.Get(?:Current\w*)?Logger|Log\.ForContext|LoggerFactory|CreateLogger)' + - pattern-not: | + class $C { ... private static readonly $T $F = $INIT; ... } + - focus-metavariable: $F + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.security.hardcoded-ip-address + severity: ERROR + languages: + - csharp + message: >- + Make sure that using this hardcoded IP address is safe here. + Hardcoded addresses make the application harder to deploy and may expose infrastructure details. + patterns: + - pattern: '"$S"' + - metavariable-regex: + metavariable: $S + regex: '^(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)(?::\d{1,5})?$|^(?=[\da-fA-F:]*::?[\da-fA-F])(?:[\da-fA-F]{1,4}:){1,7}[\da-fA-F]{0,4}(?::[\da-fA-F]{1,4})*$' + - metavariable-regex: + metavariable: $S + regex: '^(?!127\.|0\.0\.0\.0|255\.255\.255\.255|2\.5\.|192\.0\.2\.|198\.51\.100\.|203\.0\.113\.|::1$|(?i:2001:db8))' + options: + constant_propagation: false + metadata: + category: security + cwe: "CWE-547: Use of Hard-coded, Security-relevant Constants" + confidence: MEDIUM + - id: codacy.csharp.correctness.culture-insensitive-string-operation + severity: ERROR + languages: + - csharp + message: >- + Specify a culture or a StringComparison for this string operation. + The result of this call depends on the culture of the machine, which can lead to unexpected behavior. + pattern-either: + - pattern: $S.ToLower() + - pattern: $S.ToUpper() + - pattern: string.Compare($A, $B) + - pattern: string.Compare($A, $B, true) + - pattern: string.Compare($A, $B, false) + - pattern: String.Compare($A, $B) + - pattern: $S.StartsWith("$X") + - pattern: $S.EndsWith("$X") + - pattern: (string $S).IndexOf("$X") + - pattern: (string $S).LastIndexOf("$X") + - pattern: $S.StartsWith((string $X)) + - pattern: $S.EndsWith((string $X)) + - pattern: (string $S).IndexOf((string $X)) + - pattern: (string $S).LastIndexOf((string $X)) + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.unused-code.unused-local-variable + severity: WARNING + languages: + - csharp + message: >- + Remove this unused local variable. + Unused variables clutter the code and may indicate a mistake. + patterns: + - pattern-inside: | + $R $METH(...) { ... } + - pattern-regex: '(?m)^[ \t]*(?!(?:using|return|throw|await|yield|else|goto|case|new|break|continue|const)\b)(?:var|[\w.]+(?:<[^;=()]*>)?(?:\[[, ]*\])*\??)[ \t]+\K(?!_\b)(\w+)(?=[ \t]*(?:=[^;]*)?;(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}])*\})*\})*\})*\})' + metadata: + category: unused-code + confidence: MEDIUM + - id: codacy.csharp.best-practice.ignored-test-without-reason + severity: WARNING + languages: + - csharp + message: >- + Add a reason explaining why this test is ignored. + Ignored tests without an explanation tend to be forgotten. + pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\K(?:Microsoft\.VisualStudio\.TestTools\.UnitTesting\.)?Ignore(?:Attribute)?(?=[ \t]*(?:\([ \t]*\))?[ \t]*[,\]])(?![^\n]*//)(?!(?:[^\]\n]*\])?\s*(?:\[[^\]]*\]\s*)*?\[[^\]]*\bWorkItem\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.string-concatenation-in-loop + severity: WARNING + languages: + - csharp + message: >- + Use a StringBuilder instead of concatenating strings in this loop. + Each concatenation allocates a new string, which makes building strings in loops slow. + patterns: + - pattern-either: + - pattern: $S += $X + - pattern: $S = $S + $X + - metavariable-type: + metavariable: $S + type: string + - pattern-either: + - pattern-inside: for ($T $I = $V; $C; $U) $B + - pattern-inside: foreach ($T $V in $E) $B + - pattern-inside: foreach (var $V in $E) $B + - pattern-inside: while ($C) $B + - pattern-inside: | + do { ... } while ($C); + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.abstract-class-without-implementation + severity: WARNING + languages: + - csharp + message: >- + Convert this abstract class into an interface. + An abstract class with only abstract members provides no shared implementation and prevents multiple inheritance. + patterns: + - pattern: | + abstract class $C { ... abstract $R $M(...); ... } + - pattern-not: | + abstract class $C : $B { ... } + - pattern-not: | + abstract class $C : $B, $I { ... } + - pattern-not: | + abstract class $C { ... $R2 $M2(...) { ... } ... } + - pattern-not: | + abstract class $C { ... $T $F; ... } + - pattern-not: | + abstract class $C { ... $T $F = $V; ... } + - pattern-not: | + abstract class $C { ... $C(...) { ... } ... } + - pattern-not-regex: '\babstract[ \t]+class[ \t]+(\w+)[^{]*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?(?' + - focus-metavariable: $C + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.comprehensibility.nested-switch + severity: INFO + languages: + - csharp + message: >- + Refactor this nested switch into a separate method. + Nested switch statements are hard to read and to maintain. + patterns: + - pattern-inside: | + switch ($X) { case $A: ... } + - pattern: | + switch ($Y) { case $B: ... } + - pattern-not: | + switch ($X) { case $A: ... } + metadata: + category: comprehensibility + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-tostring + severity: INFO + languages: + - csharp + message: >- + Remove this redundant ToString() call. + Calling ToString() on a string, or on an object that is concatenated with a string, is not needed. + pattern-either: + - pattern: (string $S).ToString() + - pattern: '"$L" + (object $O).ToString()' + - pattern: '(object $O).ToString() + "$L"' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.redundant-cast + severity: INFO + languages: + - csharp + message: >- + Remove this unnecessary cast, the expression already has this type. + Redundant casts add noise and hide which conversions really happen. + pattern-either: + - patterns: + - pattern: ($T)$X + - pattern-either: + - pattern-inside: | + $R $M(..., $T $X, ...) { ... } + - pattern-inside: | + $T $X = $INIT; + ... + - metavariable-regex: + metavariable: $T + regex: '^(?:int|long|short|byte|double|float|decimal|bool|char|string|object)$' + - patterns: + - pattern: $X.Cast<$T>() + - pattern-either: + - pattern-inside: | + $R $M(..., IEnumerable<$T> $X, ...) { ... } + - pattern-inside: | + $R $M(..., List<$T> $X, ...) { ... } + - pattern-inside: | + $R $M(..., $T[] $X, ...) { ... } + options: + constant_propagation: false + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.codestyle.redundant-inheritance + severity: INFO + languages: + - csharp + message: >- + Remove this redundant base type, it is implied by the compiler. + Classes implicitly inherit from object and enumerations use int by default. + pattern-either: + - pattern-regex: '\bclass[ \t]+\w+(?:<[^<>{]*>)?[ \t]*:[ \t]*\K(?:System\.)?[Oo]bject\b' + - pattern-regex: '\benum[ \t]+\w+[ \t]*:[ \t]*\K(?:int|Int32|System\.Int32)\b' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.empty-class + severity: WARNING + languages: + - csharp + message: >- + Remove this empty class, or add members to it. + An empty class is usually unfinished code and adds noise. + pattern-regex: '(?m)^(?{]*>)?(?=\s*\{\s*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.log-and-rethrow + severity: WARNING + languages: + - csharp + message: >- + Either log this exception and handle it, or rethrow it with some contextual information. + Logging an exception and rethrowing it leads to the same failure being logged several times. + pattern-regex: '\b\Kcatch[ \t]*\([ \t]*[\w.]+[ \t]+(\w+)[ \t]*\)(?:\s*when\s*\((?:[^()]|\([^()]*\))*\))?(?:\s*//[^\n]*)*\s*\{(?=(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\b\w*[Ll]og(?:ger)?\w*\.\w+[ \t]*\([^;]*\b\1\b)(?=(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\bthrow[ \t]*(?:\1[ \t]*)?;)' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.protected-member-in-sealed-class + severity: INFO + languages: + - csharp + message: >- + Make this member private or public, protected members are meaningless in a sealed class. + A sealed class cannot be inherited, so 'protected' only adds confusion. + patterns: + - pattern-inside: | + sealed class $C { ... } + - pattern-either: + - pattern: protected $T $F; + - pattern: protected $T $F = $V; + - pattern: | + protected $R $F(...) { ... } + - pattern-not: | + protected override $R $F(...) { ... } + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.simplify-type-check + severity: INFO + languages: + - csharp + message: >- + Use the 'is' operator to check the type of this expression. + The 'is' operator is shorter and clearer than 'as' with a null check or reflection based checks. + pattern-either: + - pattern: $X as $T != null + - pattern: $X as $T == null + - pattern: typeof($T).IsInstanceOfType($X) + - pattern: typeof($T).IsAssignableFrom($X.GetType()) + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.non-constant-visible-static-field + severity: ERROR + languages: + - csharp + message: >- + Make this static field private, readonly or const. + Visible mutable static fields can be changed from anywhere and are not thread-safe. + patterns: + - pattern-either: + - pattern: | + class $C { ... public static $T $F; ... } + - pattern: | + class $C { ... public static $T $F = $V; ... } + - pattern: | + class $C { ... protected static $T $F; ... } + - pattern: | + class $C { ... protected static $T $F = $V; ... } + - pattern-not: | + class $C { ... static readonly $T $F; ... } + - pattern-not: | + class $C { ... static readonly $T $F = $V; ... } + - pattern-not: | + class $C { ... static event $T $F; ... } + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.unchecked-enumerable-sum + severity: WARNING + languages: + - csharp + message: >- + Remove the 'unchecked' context around this Sum call, or handle the OverflowException. + Enumerable.Sum always performs checked arithmetic, so 'unchecked' does not prevent overflow exceptions. + patterns: + - pattern: $X.Sum(...) + - pattern-either: + - pattern-inside: unchecked { ... } + - pattern-inside: unchecked($E) + - pattern-not-inside: | + try { ... } catch ($T $V) { ... } + - pattern-not-inside: | + try { ... } catch { ... } + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.parameter-name-as-string + severity: WARNING + languages: + - csharp + message: >- + Use nameof() instead of this string literal for the parameter name. + nameof() is checked by the compiler and stays correct when the parameter is renamed. + pattern-regex: '\b\w+[ \t]*(?:<[^<>()]*>)?[ \t]*\((?:[^()]*,)?[ \t]*(?:(?:ref|out|in|params|this)[ \t]+)?[\w.<>\[\],?]+[ \t]+(\w+)[ \t]*(?:=[^,()]*)?(?:,[^()]*)?\)(?:\s*//[^\n]*)*\s*(?:where[^{]*)?\{(?:(?!\n[ \t]*(?:(?:public|private|protected|internal)[ \t]+)[^\n;]*\()[\s\S])*?\bnew[ \t]+\w*Exception[ \t]*\((?:[^;"]|"[^"\n]*")*?\K"\1"' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.unused-code.unused-type-parameter + severity: INFO + languages: + - csharp + message: >- + Remove this unused type parameter. + A type parameter that is not used anywhere only makes the type or method harder to use. + pattern-either: + - pattern-regex: '(?m)^[ \t]*(?![^\n]*\boverride\b)(?:(?:public|private|protected|internal|static|virtual|async|unsafe|new|sealed)[ \t]+)*(?=[\w.]+[ \t]+\w+[ \t]*<[ \t]*(\w+)[ \t]*>)(?!\1\b)(?:void|[\w.]+)[ \t]+\w+[ \t]*<[ \t]*\K\w+(?=[ \t]*>[ \t]*\((?![^()]*\b\1\b)[^()]*\)(?:\s*//[^\n]*)*\s*(?:where[^{]*)?\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}])*\})*\})*\})*\})' + - pattern-regex: '\b(?:class|struct)[ \t]+\w+[ \t]*<[ \t]*\K(\w+)(?=[ \t]*>[^{;]*\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}]|\{(?:(?!\b\1\b)[^{}])*\})*\})*\})*\})' + metadata: + category: unused-code + confidence: MEDIUM + - id: codacy.csharp.best-practice.public-constant + severity: WARNING + languages: + - csharp + message: >- + Change this public constant into a static readonly field or property. + Constant values are copied into other assemblies at compile time, so changing them later requires recompiling every caller. + patterns: + - pattern-inside: | + public class $C { ... } + - pattern: public const $T $F = $V; + - pattern-regex: '(?m)^[ \t]*[^\n]*\bconst\b[^\n]*' + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.flags-zero-member-not-none + severity: WARNING + languages: + - csharp + message: >- + Rename this zero-value member of the [Flags] enumeration to 'None'. + 'None' clearly conveys that no flag is set. + patterns: + - pattern-regex: '(?:[{,])\s*(?://[^\n]*\s*)*(?\w+)[ \t]*=[ \t]*0+\b(?=[^{}]*\})' + - pattern-regex: '\[[ \t]*(?:System\.)?Flags(?:Attribute)?[ \t]*\][^;{}]*?\benum\b[^{]*\{[^{}]*\}' + - metavariable-regex: + metavariable: $NAME + regex: '^(?!None$)' + - focus-metavariable: $NAME + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.non-private-field + severity: WARNING + languages: + - csharp + message: >- + Make this field private and encapsulate it in a property. + Fields are not part of a good public API: they cannot be versioned, validated or declared in interfaces. + patterns: + - pattern-either: + - pattern-inside: | + public class $C { ... public $T $F; ... } + - pattern-inside: | + public class $C { ... public $T $F = $V; ... } + - pattern-not-inside: | + public class $C { ... public static $T $F; ... } + - pattern-not-inside: | + public class $C { ... public static $T $F = $V; ... } + - pattern-not-inside: | + public class $C { ... public event $T $F; ... } + - pattern-either: + - pattern: public $T $F; + - pattern: public $T $F = $V; + - pattern-regex: '(?m)^[ \t]*(?![^\n]*\bconst\b)[^\n]*' + - pattern-regex: '\bclass\b[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})*' + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.optional-parameter + severity: WARNING + languages: + - csharp + message: >- + Use method overloading instead of this optional parameter. + Default values are compiled into the calling code, so changing them later does not affect existing callers. + patterns: + - pattern-either: + - pattern: | + public $R $M(..., $T $P = $V, ...) { ... } + - pattern: | + protected $R $M(..., $T $P = $V, ...) { ... } + - focus-metavariable: $P + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.property-returns-collection-copy + severity: WARNING + languages: + - csharp + message: >- + Refactor this property into a method, it creates a copy of a collection on each access. + Callers expect property access to be cheap, so they may call it repeatedly, for example in a loop. + pattern-regex: '[\w.<>\[\],?]+[ \t]+\K\w+(?=(?:\s*//[^\n]*)*\s*(?:\{\s*get\s*\{\s*return\b|\{\s*get\s*=>|=>)\s*[^;{}()]*(?:\([^()]*\))?\.(?:ToList|ToArray|Clone|ToDictionary|ToHashSet)\(\)\s*;)' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.comprehensibility.multidimensional-array-parameter + severity: WARNING + languages: + - csharp + message: >- + Use a dedicated type instead of a multidimensional or jagged array parameter in this public method. + Such parameters are hard to understand and to use correctly. + pattern-regex: '\bpublic\b[^;{=()\n]*\((?:[^()]*,)?[ \t]*[\w.<>]+(?:\[\]\[\]|\[,+\])[\[\],]*[ \t]+\K\w+' + metadata: + category: comprehensibility + confidence: HIGH + - id: codacy.csharp.best-practice.property-getter-throws + severity: WARNING + languages: + - csharp + message: >- + Remove this exception from the property getter, or turn the property into a method. + Property getters are expected to be safe, simple operations. + patterns: + - pattern-either: + - pattern: throw new $E(...); + - pattern: throw new $E(...) + - focus-metavariable: $E + - metavariable-regex: + metavariable: $E + regex: '^(?!(?:System\.)?(?:NotImplementedException|NotSupportedException|InvalidOperationException|ObjectDisposedException)$)' + - pattern-either: + - pattern-regex: '\b\w+\s*\{\s*get\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}' + - pattern-regex: '\b\w+\s*\{\s*get\s*=>[^;]*;' + - pattern-regex: '\b\w+[ \t]*=>[ \t]*throw\b[^;]*;' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.write-only-property + severity: INFO + languages: + - csharp + message: >- + Add a getter to this property, or replace it with a method. + Properties that can be written but not read are counterintuitive. + patterns: + - pattern: | + class $C { ... $T $P { set { ... } } ... } + - focus-metavariable: $P + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.public-static-mutable-field + severity: WARNING + languages: + - csharp + message: >- + Make this mutable static field private, or use an immutable or read-only collection type. + Even a readonly field of a mutable type can be modified by any code that can access it. + patterns: + - pattern-either: + - pattern: | + class $C { ... public static $T $F; ... } + - pattern: | + class $C { ... public static $T $F = $V; ... } + - metavariable-regex: + metavariable: $T + regex: '^(?:[\w.]+(?:<[^<>]*>)?\[\]|(?:System\.Collections\.Generic\.)?(?:List|Dictionary|HashSet|SortedSet|SortedList|SortedDictionary|LinkedList|Queue|Stack|ICollection|IList|IDictionary|ISet|Collection|ObservableCollection)(?:<.*>)?)$' + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.field-shadows-parent-field + severity: INFO + languages: + - csharp + message: >- + Rename this field, it hides a field of the parent class. + A field with the same name as a base class field makes it unclear which one is used. + patterns: + - pattern-either: + - pattern-inside: | + class $P { ... $T $F; ... } + ... + - pattern-inside: | + class $P { ... $T $F = $I; ... } + ... + - pattern-either: + - pattern: | + class $C : $P { ... $T2 $G; ... } + - pattern: | + class $C : $P { ... $T2 $G = $V; ... } + - metavariable-comparison: + comparison: str($F) == str($G) + - focus-metavariable: $G + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.complexity.too-many-generic-parameters + severity: WARNING + languages: + - csharp + message: >- + Reduce the number of generic parameters of this type or method. + Types with more than 2 and methods with more than 3 generic parameters are hard to understand and to use. + pattern-either: + - pattern-regex: '\b(?:class|struct|interface|record)[ \t]+\K\w+(?=[ \t]*<[ \t]*\w+[ \t]*,[ \t]*\w+[ \t]*,[ \t]*\w+)' + - pattern-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|static|virtual|override|abstract|async|unsafe|new|sealed)[ \t]+)*(?!(?:return|else|new|await|throw|yield|case)\b)[\w.<>\[\],?]+[ \t]+\K\w+(?=[ \t]*<[ \t]*\w+[ \t]*,[ \t]*\w+[ \t]*,[ \t]*\w+[ \t]*,[ \t]*\w+[^<>]*>[ \t]*\()' + metadata: + category: complexity + confidence: HIGH + - id: codacy.csharp.codestyle.useless-bitwise-operation + severity: INFO + languages: + - csharp + message: >- + Remove this bitwise operation, it does not change the value. + Operations such as '& -1', '| 0' and '^ 0' always return the original operand. + pattern-either: + - pattern: $X & -1 + - pattern: -1 & $X + - pattern: $X | 0 + - pattern: 0 | $X + - pattern: $X ^ 0 + - pattern: 0 ^ $X + - pattern: $X &= -1 + - pattern: $X |= 0 + - pattern: $X ^= 0 + options: + constant_propagation: false + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.codestyle.control-character-in-string + severity: INFO + languages: + - csharp + message: >- + Replace this invisible or control character in the string literal with an escape sequence. + Raw tabs and other control characters are invisible in most editors and easily lost. + pattern-regex: '(?- + Handle this exception, or explain in a comment why it can be ignored. + Silently swallowing all exceptions hides failures, including security-relevant ones. + pattern-regex: '\b\Kcatch\b(?:[ \t]*\([ \t]*(?:System\.)?Exception(?:[ \t]+\w+)?[ \t]*\))?(?:\s*//[^\n]*)*\s*\{\s*\}' + metadata: + category: security + cwe: "CWE-390: Detection of Error Condition Without Action" + owasp: "A09:2021 - Security Logging and Monitoring Failures" + confidence: HIGH + - id: codacy.csharp.performance.non-constant-log-template + severity: WARNING + languages: + - csharp + message: >- + Use a constant message template and pass the values as arguments to this logging call. + Interpolated or concatenated templates are built even when the log level is disabled and break structured logging. + patterns: + - pattern-either: + - pattern: $L.$LOG($"...", ...) + - pattern: $L.$LOG($EX, $"...", ...) + - pattern: $L.$LOG("$S" + $X, ...) + - pattern: $L.$LOG($X + "$S", ...) + - pattern: $L.$LOG($EX, "$S" + $X, ...) + - pattern: $L.$LOG(string.Format(...), ...) + - metavariable-regex: + metavariable: $LOG + regex: '^(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|Trace|Debug|Info|Information|Warn|Warning|Error|Fatal|Verbose|DebugFormat|InfoFormat|WarnFormat|ErrorFormat|FatalFormat)$' + - metavariable-regex: + metavariable: $L + regex: '(?i).*log.*' + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.best-practice.boolean-literal-in-assertion + severity: WARNING + languages: + - csharp + message: >- + Use the dedicated boolean assertion instead of comparing with a boolean literal. + Assert.IsTrue or Assert.IsFalse express the intent better and produce clearer failure messages. + pattern-either: + - pattern: Assert.AreEqual(true, ...) + - pattern: Assert.AreEqual(false, ...) + - pattern: Assert.AreEqual($X, true, ...) + - pattern: Assert.AreEqual($X, false, ...) + - pattern: Assert.AreNotEqual(true, ...) + - pattern: Assert.AreNotEqual(false, ...) + - pattern: Assert.Equal(true, ...) + - pattern: Assert.Equal(false, ...) + - pattern: Assert.NotEqual(true, ...) + - pattern: Assert.NotEqual(false, ...) + - pattern: Assert.IsTrue(true, ...) + - pattern: Assert.IsTrue(false, ...) + - pattern: Assert.IsFalse(true, ...) + - pattern: Assert.IsFalse(false, ...) + - pattern: Assert.That($X, Is.EqualTo(true)) + - pattern: Assert.That($X, Is.EqualTo(false)) + options: + constant_propagation: false + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.catch-only-rethrows + severity: INFO + languages: + - csharp + message: >- + Add logic to this catch clause or remove it, it only rethrows the exception. + A catch clause that only rethrows has no effect. + pattern-regex: '\b\Kcatch\b(?:[ \t]*\([^()]*\))?(?:\s*//[^\n]*)*\s*\{\s*throw[ \t]*;\s*\}(?!\s*catch\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.thread-sleep-in-test + severity: WARNING + languages: + - csharp + message: >- + Do not use Thread.Sleep in this test, wait for a specific condition instead. + Sleeping makes tests slow and flaky, because the right duration depends on the machine. + patterns: + - pattern-either: + - pattern: Thread.Sleep(...) + - pattern: System.Threading.Thread.Sleep(...) + - pattern-either: + - pattern-inside: | + [TestMethod] + $R $M(...) { ... } + - pattern-inside: | + [DataTestMethod] + $R $M(...) { ... } + - pattern-inside: | + [Test] + $R $M(...) { ... } + - pattern-inside: | + [TestCase(...)] + $R $M(...) { ... } + - pattern-inside: | + [Fact] + $R $M(...) { ... } + - pattern-inside: | + [Theory] + $R $M(...) { ... } + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.field-could-be-readonly + severity: INFO + languages: + - csharp + message: >- + Make this field 'readonly', it is only assigned in its declaration or in constructors. + Readonly fields document that the value does not change after construction and prevent accidental modification. + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + class $C { ... } + - pattern: private $T $F = $V; + - patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $C(...) { ... $F = $X; ... } ... } + - pattern-inside: | + class $C { ... $C(...) { ... this.$F = $X; ... } ... } + - pattern-inside: | + class $C { ... $C(...) => this.$F = $X; ... } + - pattern-inside: | + class $C { ... $C(...) => $F = $X; ... } + - pattern: private $T $F; + - pattern-not-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + class $C { ... static $T $F; ... } + - pattern-not-inside: | + class $C { ... static $T $F = $V; ... } + - pattern-not-inside: | + class $C { ... readonly $T $F; ... } + - pattern-not-inside: | + class $C { ... readonly $T $F = $V; ... } + - pattern-not-inside: | + class $C { ... const $T $F = $V; ... } + - pattern-not-inside: | + class $C { ... [$ANNO] private $T $F; ... } + - pattern-not-inside: | + class $C { ... [$ANNO] private $T $F = $V; ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... this.$F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... <... $F++ ...>; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... <... $F-- ...>; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $F += $X; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $F -= $X; ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $FN(..., $F, ...); ... } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $O.$FN(..., $F, ...); ... } ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get { ... } set { ... $F = $X; ... } } ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get => $G; set => $F = $X; } ... } + - pattern-not-inside: | + class $C { ... $T2 $P => <... $F = $X ...>; ... } + - pattern-not-inside: | + class $C { ... $T2 $P => <... $F ??= $X ...>; ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get { ... $F = $X; ... } } ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get { ... $F = $X; ... } set { ... } } ... } + - pattern-not-inside: | + class $C { ... $R $MM(...) { ... $F ??= $X; ... } ... } + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.codestyle.simplify-linq-expression + severity: INFO + languages: + - csharp + message: >- + Simplify this LINQ expression. + A Where followed by a predicate-less call, or a cast and filter pair, can be written as a single call such as Any(predicate) or OfType(). + pattern-either: + - patterns: + - pattern: $S.Where($P).$M() + - metavariable-regex: + metavariable: $M + regex: '^(?:Any|Count|LongCount|First|FirstOrDefault|Last|LastOrDefault|Single|SingleOrDefault)$' + - pattern: $S.Select($X => $X as $T).Where($Y => $Y != null) + - pattern: $S.Select($X => $X as $T).Any($Y => $Y != null) + - pattern: $S.Where($X => $X is $T).Select($Y => ($T)$Y) + - pattern: $S.Where($X => $X is $T).Cast<$T>() + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.reflection-accessibility-bypass + severity: ERROR + languages: + - csharp + message: >- + Make sure that using reflection to access non-public members is safe here. + Bypassing accessibility breaks encapsulation and can expose functionality that was meant to be internal. + pattern-either: + - pattern: BindingFlags.NonPublic + - pattern: System.Reflection.BindingFlags.NonPublic + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.member-more-visible-than-type + severity: WARNING + languages: + - csharp + message: >- + Reduce the accessibility of this member to match the accessibility of its containing type. + A public member of an internal type is not really public, which is misleading. + patterns: + - pattern-either: + - pattern: | + internal class $C { ... public $R $M(...) { ... } ... } + - pattern: | + internal class $C { ... public $T $M; ... } + - pattern: | + internal class $C { ... public $T $M = $V; ... } + - pattern: | + internal class $C { ... public static $T $M = $V; ... } + - pattern-not: | + internal class $C { ... public override $R $M(...) { ... } ... } + - pattern-not: | + internal class $C : $B { ... } + - pattern-not: | + internal class $C : $B, $I { ... } + - pattern-not: | + internal class $C : $B, $I, $J { ... } + - focus-metavariable: $M + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.best-practice.type-check-on-this + severity: WARNING + languages: + - csharp + message: >- + Use polymorphism instead of testing the type of 'this'. + A base class that checks which subclass it is couples it to its subclasses. + pattern-either: + - pattern: this is $T + - pattern: this as $T + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.stringbuilder-never-read + severity: WARNING + languages: + - csharp + message: >- + Remove this StringBuilder or use its result. + Building a string that is never read wastes memory and processing time. + patterns: + - pattern-either: + - pattern: var $SB = new StringBuilder(...); + - pattern: StringBuilder $SB = new StringBuilder(...); + - pattern: var $SB = new System.Text.StringBuilder(...); + - pattern-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + $R $METH(...) { ... $SB.ToString(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... return <... $SB ...>; ... } + - pattern-not-inside: | + $R $METH(...) { ... $F(..., $SB, ...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $O.$F(..., $SB, ...); ... } + - pattern-not-inside: | + $R $METH(...) { ... $SB.CopyTo(...); ... } + - pattern-not-inside: | + $R $METH(...) { ... <... $SB.Length ...>; ... } + - pattern-not-inside: | + $R $METH(...) { ... <... $SB[$I] ...>; ... } + - pattern-not-inside: | + $R $METH(...) { ... $Y = $SB; ... } + - pattern-not-regex: '\b(?:if|while|return)\b[^;{]*\.Length' + - focus-metavariable: $SB + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.performance.multiple-orderby-calls + severity: WARNING + languages: + - csharp + message: >- + Use ThenBy() instead of this second OrderBy() call. + A second OrderBy discards the previous ordering, so only the last one is applied while both are computed. + pattern-either: + - pattern: $X.OrderBy(...).OrderBy(...) + - pattern: $X.OrderBy(...).OrderByDescending(...) + - pattern: $X.OrderByDescending(...).OrderBy(...) + - pattern: $X.OrderByDescending(...).OrderByDescending(...) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.missing-configure-await + severity: ERROR + languages: + - csharp + message: >- + Add '.ConfigureAwait(false)' to this awaited task in library code. + Capturing the synchronization context is unnecessary in libraries, costs performance and can cause deadlocks. + patterns: + - pattern: await $E + - pattern-not: await $X.ConfigureAwait(...) + - pattern-not: await Task.Yield() + metadata: + category: performance + confidence: LOW + - id: codacy.csharp.best-practice.nested-member-shadows-outer-member + severity: INFO + languages: + - csharp + message: >- + Rename this member, it hides a static member of the outer class. + Members of nested classes with the same names as static members of the outer class make it unclear which one is used. + patterns: + - pattern-either: + - pattern-inside: | + class $O { ... static $T $A; ... } + - pattern-inside: | + class $O { ... static $T $A = $V; ... } + - pattern-inside: | + class $O { ... static $T $A(...) { ... } ... } + - pattern-inside: | + class $O { ... class $I { ... } ... } + - pattern-inside: | + class $I { ... } + - pattern-either: + - pattern: $T2 $B; + - pattern: $T2 $B = $V2; + - pattern: | + $T2 $B(...) { ... } + - metavariable-comparison: + comparison: str($A) == str($B) + - focus-metavariable: $B + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.suppress-finalize-without-finalizer + severity: INFO + languages: + - csharp + message: >- + Remove this call to GC.SuppressFinalize, this sealed type has no finalizer. + Suppressing finalization only makes sense for types that declare a finalizer, directly or in a derived type. + patterns: + - pattern: GC.SuppressFinalize(this) + - pattern-regex: '\bsealed\b[^{;]*?\bclass[ \t]+(\w+)\b[^{]*\{(?:(?!~\1[ \t]*\()[^{}]|\{(?:(?!~\1[ \t]*\()[^{}]|\{(?:(?!~\1[ \t]*\()[^{}]|\{(?:(?!~\1[ \t]*\()[^{}])*\})*\})*\})*\}' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.duplicate-cast + severity: INFO + languages: + - csharp + message: >- + Use pattern matching ('is T t') instead of checking the type and casting it again. + Testing the type and then casting the same value performs the type check twice. + patterns: + - pattern-either: + - pattern: ($T)$X + - pattern: $X as $T + - pattern-inside: if ($X is $T) $S; + - pattern-not-inside: $X is $T + options: + constant_propagation: false + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.codestyle.default-value-passed-explicitly + severity: INFO + languages: + - csharp + message: >- + Remove this argument, it is the default value of the parameter. + Passing the default value explicitly is redundant and hides which arguments really matter. + pattern-either: + - patterns: + - pattern-inside: | + class $C { ... $R $M($T1 $A, $T2 $B = $V) { ... } ... } + - pattern: $M($X, $V) + - focus-metavariable: $V + - patterns: + - pattern-inside: | + class $C { ... $R $M($T1 $A, $T2 $B, $T3 $D = $V) { ... } ... } + - pattern: $M($X, $Y, $V) + - focus-metavariable: $V + - patterns: + - pattern-inside: | + class $C { ... $R $M($T1 $A, $T2 $B = $V, $T3 $D = $W) { ... } ... } + - pattern: $M($X, $V) + - focus-metavariable: $V + options: + constant_propagation: false + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.performance.use-string-isnullorempty + severity: WARNING + languages: + - csharp + message: >- + Use string.IsNullOrEmpty() to test whether this string is empty. + It expresses the intent better and also handles null values. + pattern-either: + - pattern: $S.Equals("") + - pattern: '"".Equals($S)' + - pattern: string.Equals($S, "") + - pattern: string.Equals("", $S) + - pattern: $S.Equals(string.Empty) + - pattern: string.Empty.Equals($S) + - pattern: (string $S).Length == 0 + - pattern: (string $S).Length != 0 + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.private-class-not-sealed + severity: ERROR + languages: + - csharp + message: >- + Seal this private class, it is never inherited. + Sealing classes that are not designed for inheritance lets the runtime optimize calls and documents the intent. + pattern-regex: '\b(?:private|file)[ \t]+(?:(?:partial|new|unsafe|internal|protected)[ \t]+)*(?:class|record)[ \t]+\K(\w+)\b(?![\s\S]*?(?::|,)[ \t]*\1\b)' + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.codestyle.empty-namespace + severity: INFO + languages: + - csharp + message: >- + Remove this empty namespace. + An empty namespace declaration adds nothing. + pattern-regex: '\bnamespace[ \t]+[\w.]+(?:\s*//[^\n]*)*\s*\{\s*\}' + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.unused-code.event-never-raised + severity: INFO + languages: + - csharp + message: >- + Remove this event or raise it somewhere. + An event that is never invoked misleads subscribers into waiting for notifications that never come. + pattern-regex: '\bevent[ \t]+[\w.<>,? ]+?[ \t]+\K(\w+)(?=[ \t]*;)(?![\s\S]*\b\1[ \t]*(?:\?\.Invoke|\.Invoke|\(|\)))(?![\s\S]*=[ \t]*\1[ \t]*;)' + metadata: + category: unused-code + confidence: MEDIUM + - id: codacy.csharp.best-practice.bitwise-operation-on-non-flags-enum + severity: WARNING + languages: + - csharp + message: >- + Add the [Flags] attribute to this enumeration, or do not combine its values with bitwise operators. + Combining members of an enumeration that is not meant to hold flags produces values that may not exist. + patterns: + - pattern-either: + - pattern: $E.$A | $E.$B + - pattern: $E.$A & $E.$B + - pattern: $E.$A ^ $E.$B + - pattern-inside: | + enum $E { ... } + ... + - pattern-not-inside: | + [Flags] + enum $E { ... } + ... + - pattern-not-inside: | + [System.Flags] + enum $E { ... } + ... + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.loop-could-use-linq + severity: INFO + languages: + - csharp + message: >- + Use a LINQ Where clause instead of filtering inside this loop. + A loop whose body only consists of a condition can be written more clearly with LINQ. + patterns: + - pattern-either: + - pattern: | + foreach (var $X in $C) { if ($P) $S; } + - pattern: | + foreach ($T $X in $C) { if ($P) $S; } + - pattern-not: | + foreach (var $X in $C) { if ($P) $S; else $E; } + - pattern-not: | + foreach ($T $X in $C) { if ($P) $S; else $E; } + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.caller-information-parameter-not-last + severity: WARNING + languages: + - csharp + message: >- + Move this caller information parameter to the end of the parameter list. + Caller information parameters are optional and filled by the compiler, so they belong after all other parameters. + pattern-regex: '\[[ \t]*(?:System\.Runtime\.CompilerServices\.)?Caller(?:FilePath|LineNumber|MemberName|ArgumentExpression)(?:Attribute)?\b[^\]]*\]\s*[\w.<>\[\]?]+[ \t]+\K\w+(?=[ \t]*(?:=[^,()]*)?,(?!\s*\[[ \t]*(?:System\.Runtime\.CompilerServices\.)?Caller)[^()]*\))' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.local-could-be-const + severity: WARNING + languages: + - csharp + message: >- + Declare this local variable as 'const', its value never changes. + Constants make it clear that the value is fixed and let the compiler inline it. + patterns: + - pattern-inside: | + $R $METH(...) { ... } + - pattern-regex: '(?m)^[ \t]*(?:var|int|long|short|byte|uint|ulong|double|float|decimal|bool|char|string)[ \t]+\K(\w+)(?=[ \t]*=[ \t]*(?:-?\d[\w.]*|@?"(?:[^"\\\n]|\\.)*"|''(?:[^''\\]|\\.)+''|true|false)[ \t]*;(?:(?!\b\1[ \t]*(?:=[^=]|\+\+|--|[-+*/%&|^]=|<<=|>>=|\?\?=)|(?:\+\+|--|\bref[ \t]+|\bout[ \t]+)\1\b)[^{}]|\{(?:(?!\b\1[ \t]*(?:=[^=]|\+\+|--|[-+*/%&|^]=|<<=|>>=|\?\?=)|(?:\+\+|--|\bref[ \t]+|\bout[ \t]+)\1\b)[^{}]|\{(?:(?!\b\1[ \t]*(?:=[^=]|\+\+|--|[-+*/%&|^]=|<<=|>>=|\?\?=)|(?:\+\+|--|\bref[ \t]+|\bout[ \t]+)\1\b)[^{}])*\})*\})*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.comprehensibility.nested-ternary + severity: INFO + languages: + - csharp + message: >- + Extract this nested conditional expression into an independent statement. + Nested ternary operators are hard to read. + pattern-either: + - pattern: "$A ? $B : $C ? $D : $E" + - pattern: "$A ? ($B ? $C : $D) : $E" + - pattern: "($A ? $B : $C) ? $D : $E" + metadata: + category: comprehensibility + confidence: HIGH + - id: codacy.csharp.performance.method-returns-constant + severity: INFO + languages: + - csharp + message: >- + Replace this method with a constant, it always returns the same value. + A method that only returns a literal is slower and less clear than a constant. + patterns: + - pattern-either: + - pattern: | + $R $M() { return $L; } + - pattern: | + $R $M() => $L; + - metavariable-regex: + metavariable: $L + regex: '^(?:-?\d[\w.]*|@?"(?:[^"\\]|\\.)*"|''(?:[^''\\]|\\.)+''|true|false)$' + - pattern-not: | + override $R $M() { ... } + - pattern-not: | + virtual $R $M() { ... } + - pattern-not: | + override $R $M() => $L; + - pattern-not: | + virtual $R $M() => $L; + - focus-metavariable: $M + options: + constant_propagation: false + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.best-practice.logger-category-mismatch + severity: WARNING + languages: + - csharp + message: >- + Name this logger after the enclosing type. + A logger named after another type makes log entries hard to attribute and filter. + patterns: + - pattern-inside: | + class $C { ... } + - pattern-either: + - pattern: $F.CreateLogger<$T>() + - pattern: $F.CreateLogger(typeof($T)) + - pattern: $F.CreateLogger(nameof($T)) + - pattern: LogManager.GetLogger(typeof($T)) + - pattern: LogManager.GetCurrentClassLogger(typeof($T)) + - metavariable-comparison: + comparison: str($T) != str($C) + - pattern-not-inside: | + class $C { ... class $N { ... } ... } + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.overlapping-overload-defaults + severity: WARNING + languages: + - csharp + message: >- + Remove the default values of this overload, or rename one of the methods. + Calls that omit the optional arguments resolve to the other overload, so the default values are never used. + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + class $C { ... $R $M($T $A) { ... } ... } + - pattern: | + $R2 $M($T2 $A2, $U $B = $V) { ... } + - metavariable-comparison: + comparison: str($T) == str($T2) + - patterns: + - pattern-inside: | + class $C { ... $R $M() { ... } ... } + - pattern: | + $R2 $M($U $B = $V) { ... } + - focus-metavariable: $M + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.expected-exception-attribute + severity: WARNING + languages: + - csharp + message: >- + Replace the ExpectedException attribute with an explicit assertion such as Assert.ThrowsException. + The attribute passes when any line of the test throws, not only the one that should. + pattern-regex: '\[[ \t]*\KExpectedException(?:Attribute)?\b(?=[^\]]*\](?:\s*//[^\n]*)*\s*(?:\[[^\]]*\](?:\s*//[^\n]*)*\s*)*(?:(?:public|private|internal|async|static)[ \t]+)*[\w.<>]+[ \t]+\w+[ \t]*\([^)]*\)\s*\{(?![^;{}]*;\s*\}))' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.check-before-assign + severity: INFO + languages: + - csharp + message: >- + Remove this redundant check and assign the value directly. + Checking whether a variable already holds the value before assigning it adds a condition without benefit. + patterns: + - pattern-either: + - pattern: | + if ($X != $A) { $X = $A; } + - pattern: | + if ($A != $X) { $X = $A; } + - pattern-not: | + if ($X != $A) { $X = $A; } else $E; + - metavariable-regex: + metavariable: $X + regex: '^[a-z_]\w*$' + options: + constant_propagation: false + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.public-constructor-in-abstract-class + severity: INFO + languages: + - csharp + message: >- + Make this constructor protected, its class is abstract. + Abstract classes cannot be instantiated, so a public constructor is misleading. + patterns: + - pattern-inside: | + abstract class $C { ... } + - pattern-regex: '\b(?:public|internal)[ \t]+\K(\w+)(?=[ \t]*\((?:[^()]|\([^()]*\))*\)(?:\s*//[^\n]*)*\s*(?::\s*(?:base|this)\s*\((?:[^()]|\([^()]*\))*\)\s*)?\{)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.default-parameter-value-without-optional + severity: WARNING + languages: + - csharp + message: >- + Add the [Optional] attribute to this parameter. + Without it, [DefaultParameterValue] has no effect and callers must still pass a value. + pattern-regex: '[(,]\s*(?=(?:\[[^\]]*\]\s*)*\[[^\]]*\bDefaultParameterValue\b)(?!(?:\[[^\]]*\]\s*)*\[[^\]]*\bOptional\b)(?:\[[^\]]*\]\s*)+[\w.<>\[\]?]+[ \t]+\K\w+' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.redundant-tochararray + severity: INFO + languages: + - csharp + message: >- + Remove this ToCharArray() call, strings can be indexed and enumerated directly. + Copying the string into a new array is unnecessary. + pattern-either: + - pattern: foreach (var $C in $S.ToCharArray()) $B + - pattern: foreach ($T $C in $S.ToCharArray()) $B + - pattern: $S.ToCharArray()[$I] + - pattern: $S.ToCharArray().Length + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.correctness.format-string-unused-arguments + severity: ERROR + languages: + - csharp + message: >- + Use all the arguments passed to this composite format string, or remove the unused ones. + An argument without a matching format item is silently ignored, which usually indicates a mistake. + patterns: + - pattern-either: + - pattern: string.Format("$F", ...) + - pattern: String.Format("$F", ...) + - pattern: $SB.AppendFormat("$F", ...) + - pattern: Console.WriteLine("$F", ...) + - pattern: Console.Write("$F", ...) + - pattern-either: + - patterns: + - pattern-either: + - pattern: $O.$M("$F", $A1) + - metavariable-regex: + metavariable: $F + regex: '^(?!(?s:.*)(?- + Assign this field or remove it, it always holds its default value. + A field that is read but never written is either useless or a sign of missing initialization. + patterns: + - pattern-inside: | + class $C { ... } + - pattern: private $T $F; + - pattern-not-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... $F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... this.$F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $C(...) { ... $F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $C(...) { ... this.$F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $C(...) => this.$F = $X; ... } + - pattern-not-inside: | + class $C { ... $C(...) => $F = $X; ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... $FN(..., $F, ...); ... } ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... $O.$FN(..., $F, ...); ... } ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... <... $F++ ...>; ... } ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... $F += $X; ... } ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get { ... } set { ... $F = $X; ... } } ... } + - pattern-not-inside: | + class $C { ... $T2 $P { get => $G; set => $F = $X; } ... } + - pattern-not-inside: | + class $C { ... $T2 $P => <... $F = $X ...>; ... } + - pattern-not-inside: | + class $C { ... $T2 $P => <... $F ??= $X ...>; ... } + - pattern-not-inside: | + class $C { ... $R $M(...) { ... $F ??= $X; ... } ... } + - pattern-not-inside: | + class $C { ... [$ANNO] private $T $F; ... } + - pattern-regex: '\bclass\b[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})*' + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.codestyle.redundant-member-initializer + severity: INFO + languages: + - csharp + message: >- + Remove this initializer, the constructor always overwrites it. + An initial value that is replaced before it can be used is dead code. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... $C(...) { $F = $X; ... } ... } + - pattern-inside: | + class $C { ... $C(...) { this.$F = $X; ... } ... } + - pattern-not-inside: | + class $C { ... $C(...) { ... } ... $C(...) { ... } ... } + - pattern: $T $F = $V; + - pattern-not-inside: | + $R $METH(...) { ... } + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.best-practice.non-public-exception-type + severity: WARNING + languages: + - csharp + message: >- + Make this exception type public. + Callers outside the assembly cannot catch a non-public exception specifically and have to catch a base type instead. + pattern-regex: '(?m)^[ \t]*(?![^\n]*\bpublic\b)(?:(?:internal|private|protected|sealed|abstract|partial)[ \t]+)*class[ \t]+\K\w+(?=[^{;]*:[ \t]*(?:[\w.]+\.)?\w*Exception\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.out-or-ref-parameter + severity: WARNING + languages: + - csharp + message: >- + Return values instead of using 'out' or 'ref' parameters in this public method. + Out and ref parameters are harder to use and to understand than return values. + pattern-regex: '(?m)^[ \t]*public\b(?![^\n]*\b(?:override|Deconstruct)\b)(?![^\n]*\bbool[ \t]+Try\w*[ \t]*(?:<[^>]*>)?[ \t]*\()[^;{=()\n]*?[ \t]\K\w+(?=[ \t]*(?:<[^<>()]*>)?[ \t]*\([^()]*\b(?:ref|out)[ \t]+[^()]*\))' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.equality-operator-on-reference-type + severity: WARNING + languages: + - csharp + message: >- + Remove this overload of operator==, it changes the meaning of '==' for a reference type. + Callers expect '==' on reference types to compare references, so overloading it is confusing. + pattern-regex: '\bclass[ \t]+\K\w+(?![^{;]*\bI(?:Comparable|Equatable)\b)(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*==)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*[+-][ \t]*\()' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.non-integral-indexer + severity: WARNING + languages: + - csharp + message: >- + Use a string or an integral type as the parameter of this indexer. + Indexers are expected to look up elements by position or by key. + pattern-regex: '\bthis[ \t]*\[[ \t]*\K(?!(?:string|String|int|Int32|long|Int64|short|Int16|uint|UInt32|ulong|UInt64|ushort|UInt16|byte|Byte|sbyte|SByte|char|Char|object|Object|Index|Range|T\w*)\b)[\w.<>?]+(?=[ \t]+\w+[ \t]*\])' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.codestyle.array-created-for-params + severity: INFO + languages: + - csharp + message: >- + Pass the elements directly instead of creating an array for this 'params' parameter. + The compiler creates the array automatically. + pattern-either: + - patterns: + - pattern-regex: '\b(\w+)[ \t]*\([^()]*\bparams\b[^()]*\)[\s\S]*?\b\1[ \t]*\((?:[^()]*,)?[ \t]*\Knew[ \t]*(?:[\w.<>]+)?[ \t]*\[[ \t]*\][ \t]*\{[^{}]*\}(?=[ \t]*\))' + - patterns: + - pattern-regex: '\b(\w+)[ \t]*\((?:[^()]*,)?[ \t]*\Knew[ \t]*(?:[\w.<>]+)?[ \t]*\[[ \t]*\][ \t]*\{[^{}]*\}(?=[ \t]*\))(?=[\s\S]*\b\1[ \t]*\([^()]*\bparams\b)' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.performance.empty-finalizer + severity: WARNING + languages: + - csharp + message: >- + Remove this empty finalizer. + An empty finalizer still forces the garbage collector to keep the object alive for an extra cycle. + pattern-regex: '~\w+[ \t]*\([ \t]*\)(?:\s*//[^\n]*)*\s*\{\s*\}' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.correctness.incorrect-idisposable-implementation + severity: ERROR + languages: + - csharp + message: >- + Implement the dispose pattern: seal this class or provide a protected virtual Dispose(bool) method. + Derived classes need Dispose(bool) to release their own resources correctly. + pattern-regex: '(?m)^[ \t]*(?![^\n]*\bsealed\b)[^\n]*?\bclass[ \t]+\K\w+\b(?=[^{;]*:[^{;]*\bIDisposable\b)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\bvoid[ \t]+Dispose[ \t]*\([ \t]*bool\b)' + metadata: + category: correctness + confidence: MEDIUM + - id: codacy.csharp.best-practice.readonly-mutable-field + severity: WARNING + languages: + - csharp + message: >- + Use an immutable collection type for this field, or make it private. + 'readonly' only prevents reassigning the field, the referenced array or collection can still be modified. + patterns: + - pattern-either: + - pattern: | + class $C { ... public readonly $T $F; ... } + - pattern: | + class $C { ... public readonly $T $F = $V; ... } + - pattern: | + class $C { ... protected readonly $T $F; ... } + - pattern: | + class $C { ... protected readonly $T $F = $V; ... } + - pattern: | + class $C { ... internal readonly $T $F; ... } + - pattern: | + class $C { ... internal readonly $T $F = $V; ... } + - metavariable-regex: + metavariable: $T + regex: '^(?:[\w.]+(?:<[^<>]*>)?\[\]|(?:System\.Collections\.Generic\.)?(?:List|Dictionary|HashSet|SortedSet|SortedList|SortedDictionary|LinkedList|Queue|Stack|Collection|ObservableCollection)(?:<.*>)?)$' + - focus-metavariable: $F + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.equals-without-iequatable + severity: INFO + languages: + - csharp + message: >- + Implement IEquatable in this type, it already provides Equals(T). + Implementing the interface lets generic collections use the strongly typed method. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... bool Equals($C $O) { ... } ... } + - pattern-inside: | + class $C { ... bool Equals($C $O) => $E; ... } + - pattern-regex: '\b(?:class|struct)[ \t]+\K(?\w+)(?![^{;]*\bIEquatable\b)' + - metavariable-comparison: + comparison: str($CLS) == str($C) + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.struct-without-iequatable + severity: WARNING + languages: + - csharp + message: >- + Implement IEquatable in this struct. + Without it, equality comparisons box the struct and use slow reflection-based field comparison. + pattern-regex: '(?m)^[ \t]*(?![^\n]*\bref[ \t]+struct\b)(?:(?:public|private|protected|internal|readonly|partial|record)[ \t]+)*struct[ \t]+\K\w+(?![^{;]*\bIEquatable\b)(?=[^{;]*\{)' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.get-executing-assembly + severity: WARNING + languages: + - csharp + message: >- + Use typeof(SomeType).Assembly instead of Assembly.GetExecutingAssembly(). + GetExecutingAssembly walks the call stack, which is much slower. + pattern-either: + - pattern: Assembly.GetExecutingAssembly() + - pattern: System.Reflection.Assembly.GetExecutingAssembly() + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.type-outside-namespace + severity: INFO + languages: + - csharp + message: >- + Move this type into a named namespace. + Types in the global namespace can collide with types from other code. + patterns: + - pattern-either: + - pattern: | + class $C { ... } + - pattern: | + interface $C { ... } + - pattern: | + enum $C { ... } + - pattern-not-inside: | + namespace $N { ... } + - pattern-not-inside: | + class $O { ... class $C { ... } ... } + - pattern-not-inside: | + class $O { ... interface $C { ... } ... } + - pattern-not-inside: | + class $O { ... enum $C { ... } ... } + - pattern-regex: '(?m)\A(?![\s\S]*^[ \t]*namespace[ \t]+[\w.]+[ \t]*;)[\s\S]*' + - focus-metavariable: $C + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.missing-assembly-version + severity: WARNING + languages: + - csharp + message: >- + Add an AssemblyVersion attribute to this assembly. + Without explicit version information, assemblies cannot be versioned or bound reliably. + pattern-regex: '\A(?![\s\S]*\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.Reflection\.)?AssemblyVersion)[\s\S]*?\K\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.Reflection\.)?Assembly\w+' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.non-generic-event-handler + severity: INFO + languages: + - csharp + message: >- + Use the generic EventHandler delegate instead of declaring this custom event handler delegate. + The generic delegate removes the need for custom delegate types. + pattern-regex: '\bdelegate[ \t]+void[ \t]+\K\w+(?=[ \t]*\([ \t]*object\??[ \t]+\w+[ \t]*,[ \t]*[\w.]+[ \t]+\w+[ \t]*\))' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.non-generic-collection + severity: INFO + languages: + - csharp + message: >- + Implement the generic collection interfaces in this collection type. + Non-generic collections box their elements and lose type safety. + pattern-regex: '\bclass[ \t]+\K\w+(?=[^{;]*:[^{;]*\b(?:CollectionBase|ReadOnlyCollectionBase|DictionaryBase|IEnumerable(?![ \t]*<)|ICollection(?![ \t]*<)|IList(?![ \t]*<)|IDictionary(?![ \t]*<))\b)(?![^{;]*\b(?:IEnumerable|ICollection|IList|IDictionary|IReadOnlyCollection|IReadOnlyList)[ \t]*<)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.identical-branches + severity: WARNING + languages: + - csharp + message: >- + Remove this conditional structure or change one of its branches, they all have the same implementation. + When all branches are identical, the condition is useless or one branch is wrong. + pattern-either: + - patterns: + - pattern: if ($C) $S; else $S; + - pattern-not: if ($C) $S; else if ($D) $T; + - pattern: if ($A) $S; else if ($B) $S; else $S; + - pattern: "$C ? $X : $X" + options: + constant_propagation: false + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.list-in-public-api + severity: WARNING + languages: + - csharp + message: >- + Expose a collection interface such as IList, IReadOnlyList or Collection instead of List. + List is designed for performance, not for inheritance, and exposing it prevents changing the implementation later. + pattern-either: + - pattern-regex: '(?m)^[ \t]*public[ \t]+(?![^\n]*\boverride\b)(?:(?:static|virtual|abstract|readonly|new|sealed|async)[ \t]+)*\K(?:System\.Collections\.Generic\.)?List<[^()\n=]*?>(?=[ \t]+\w+)' + - pattern-regex: '(?m)^[ \t]*public\b(?![^\n]*\boverride\b)[^;{=()\n]*\((?:[^()]*,)?[ \t]*\K(?:System\.Collections\.Generic\.)?List<[^()]*?>(?=[ \t]+\w+[ \t]*[,)=])' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.static-readonly-could-be-const + severity: WARNING + languages: + - csharp + message: >- + Declare this field 'const' instead of 'static readonly'. + Compile-time constants are inlined and avoid a field lookup at runtime. + pattern-regex: '\b(?:static[ \t]+readonly|readonly[ \t]+static)[ \t]+(?:int|long|short|byte|uint|ulong|ushort|sbyte|double|float|decimal|bool|char|string|String)[ \t]+\K\w+(?=[ \t]*=[ \t]*(?:-?\d[\w.]*|@?"(?:[^"\\\n]|\\.)*"|''(?:[^''\\]|\\.)+''|true|false)[ \t]*;)' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.static-constructor-only-initializes-fields + severity: WARNING + languages: + - csharp + message: >- + Initialize these static fields inline and remove this static constructor. + A static constructor prevents the runtime from optimizing type initialization. + pattern-regex: '(?m)^[ \t]*static[ \t]+\K\w+(?=[ \t]*\([ \t]*\)(?:\s*//[^\n]*)*\s*\{(?:\s*(?:this\.)?\w+[ \t]*=[^;{}]*;)+\s*\})' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.multidimensional-array + severity: WARNING + languages: + - csharp + message: >- + Use a jagged array instead of this multidimensional array. + Jagged arrays are faster to access and use memory more efficiently in .NET. + pattern-regex: '\b[\w.<>]+[ \t]*\[[ \t]*,[ \t,]*\](?=[ \t]+\w+)' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.compatibility.assembly-not-marked-cls-compliant + severity: WARNING + languages: + - csharp + message: >- + Mark this assembly with the CLSCompliant attribute. + Declaring CLS compliance tells other .NET languages whether they can safely use the public API. + pattern-regex: '\A(?![\s\S]*\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.)?CLSCompliant)[\s\S]*?\K\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.Reflection\.)?Assembly\w+' + metadata: + category: compatibility + confidence: LOW + - id: codacy.csharp.best-practice.assembly-com-visibility-not-explicit + severity: WARNING + languages: + - csharp + message: >- + Mark this assembly with the ComVisible attribute. + Stating COM visibility explicitly prevents types from being exposed to COM by accident. + pattern-regex: '\A(?![\s\S]*\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.Runtime\.InteropServices\.)?ComVisible)[\s\S]*?\K\[[ \t]*assembly[ \t]*:[ \t]*(?:System\.Reflection\.)?Assembly\w+' + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.best-practice.attribute-without-attribute-usage + severity: WARNING + languages: + - csharp + message: >- + Add an AttributeUsage attribute to this custom attribute class. + Without it, the attribute can be applied to any element, including ones it was not designed for. + patterns: + - pattern-either: + - pattern: | + class $C : $B { ... } + - pattern: | + class $C : $B, $I { ... } + - metavariable-regex: + metavariable: $B + regex: '.*Attribute$' + - pattern-not: | + [AttributeUsage(...)] + class $C : $B { ... } + - pattern-not: | + [AttributeUsage(...)] + class $C : $B, $I { ... } + - pattern-not: | + [System.AttributeUsage(...)] + class $C : $B { ... } + - focus-metavariable: $C + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.string-uri-overload-not-delegating + severity: WARNING + languages: + - csharp + message: >- + Call the System.Uri overload from this string overload. + Parsing the URI in one place avoids inconsistent handling between overloads. + pattern-either: + - pattern-regex: '\b(\w+)\b[ \t]*\([ \t]*string[ \t]+\w*(?i:ur[il]|urn)\w*[ \t]*\)(?:\s*//[^\n]*)*\s*\{(?![^{}]*\b\1[ \t]*\([ \t]*new[ \t]+(?:System\.)?Uri\b)[^{}]*\}(?=[\s\S]*\b\1[ \t]*\([ \t]*(?:System\.)?Uri[ \t]+\w+[ \t]*\))' + - pattern-regex: '\b(\w+)\b[ \t]*\([ \t]*(?:System\.)?Uri[ \t]+\w+[ \t]*\)[\s\S]*?\b\K\1(?=[ \t]*\([ \t]*string[ \t]+\w*(?i:ur[il]|urn)\w*[ \t]*\)(?:\s*//[^\n]*)*\s*\{(?![^{}]*\b\1[ \t]*\([ \t]*new[ \t]+(?:System\.)?Uri\b)[^{}]*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.collection-property-with-public-setter + severity: WARNING + languages: + - csharp + message: >- + Make the setter of this collection property private, or remove it. + Callers can modify the collection through the getter; replacing the whole collection is rarely intended. + pattern-regex: '(?m)^[ \t]*public[ \t]+(?![^\n]*\boverride\b)(?:(?:virtual|new|static)[ \t]+)*(?:System\.Collections\.(?:Generic|ObjectModel)\.)?(?:List|IList|ICollection|Collection|Dictionary|IDictionary|HashSet|ISet|SortedSet|SortedDictionary|ObservableCollection)<[^\n{]*?>[ \t]+\K\w+(?=[ \t]*\{[ \t]*get;[ \t]*set;)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.reserved-enum-member + severity: WARNING + languages: + - csharp + message: >- + Remove this 'Reserved' enumeration member. + Reserved members suggest a future value that may be renamed or reused later, which breaks existing code. + patterns: + - pattern-regex: '(?:[{,])\s*(?://[^\n]*\s*)*(?:\[[^\]]*\]\s*)*\K\w*Reserved\w*\b' + - pattern-regex: '\benum\b[^{]*\{[^{}]*\}' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.complexity.nested-generic-type-in-signature + severity: INFO + languages: + - csharp + message: >- + Simplify this parameter type, it nests generic types. + Nested generic types in public signatures are hard to read and to use. + pattern-regex: '(?m)^[ \t]*(?:public|protected)\b[^;{=()\n]*\((?:[^()]*,)?\s*\K[\w.]+<[^<>(),]*<[^()]*?>[^()]*?>(?=\s+\w+)' + metadata: + category: complexity + confidence: HIGH + - id: codacy.csharp.best-practice.type-parameter-not-inferable + severity: INFO + languages: + - csharp + message: >- + Use this type parameter in the parameter list so that it can be inferred. + Callers have to specify type arguments that cannot be inferred from the arguments. + pattern-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|static|virtual|override|async|abstract|new|sealed|unsafe|extern)[ \t]+)*(?!(?:return|new|await|yield|else|case|throw)\b)[\w.<>\[\],?]+[ \t]+\K\w+(?=[ \t]*<[ \t]*(\w+)[ \t]*>[ \t]*\((?![^()]*\b\1\b)[^()]*\)(?:\s*//[^\n]*)*\s*(?:where[^{;]*)?[{;=])' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.performance.enum-storage-not-int32 + severity: INFO + languages: + - csharp + message: >- + Use the default Int32 storage type for this enumeration. + Smaller storage types rarely save memory in practice and make interop and arithmetic harder. + pattern-regex: '\benum[ \t]+\w+[ \t]*:[ \t]*\K(?:byte|sbyte|short|ushort|long|ulong|uint|Byte|SByte|Int16|UInt16|Int64|UInt64|UInt32)\b' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.empty-interface + severity: WARNING + languages: + - csharp + message: >- + Remove this empty interface, or add members to it. + An empty interface provides no contract; use a custom attribute to mark types instead. + pattern-regex: '(?m)^(?{]*>)?(?=\s*(?::[ \t]*[\w.]+(?![\w.]*[ \t]*[<,]))?(?:\s*//[^\n]*)*\s*\{\s*\})' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.exception-missing-standard-constructors + severity: WARNING + languages: + - csharp + message: >- + Add the missing standard constructors to this exception class. + Exceptions should offer parameterless, message and message plus inner exception constructors so they can be created consistently. + pattern-regex: '\bclass[ \t]+\K(\w+)\b(?=[^{;]*:[ \t]*(?:[\w.]+\.)?\w*Exception\b)(?!(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b\1[ \t]*\([ \t]*\))(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b\1[ \t]*\([ \t]*string[ \t]+\w+[ \t]*\))(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b\1[ \t]*\([ \t]*string[ \t]+\w+[ \t]*,[ \t]*(?:System\.)?Exception[ \t]+\w+[ \t]*\)))' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.lowercase-string-normalization + severity: WARNING + languages: + - csharp + message: >- + Normalize this string to uppercase instead of lowercase. + Some characters cannot make a round trip when converted to lowercase, which makes comparisons unreliable. + pattern-either: + - pattern: $S.ToLower(...) + - pattern: $S.ToLowerInvariant() + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.ref-object-parameter + severity: WARNING + languages: + - csharp + message: >- + Use a generic method instead of this 'ref object' parameter. + Generic methods are type-safe and avoid boxing. + pattern-regex: '[(,][ \t]*\Kref[ \t]+(?:object|Object|System\.Object)\b(?=[ \t]+\w+)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.getter-method-could-be-property + severity: INFO + languages: + - csharp + message: >- + Convert this getter method into a property. + Parameterless methods that return a value are expected to be properties in .NET. + pattern-regex: '(?m)^[ \t]*(?:public|protected)[ \t]+(?![^\n]*\b(?:override|async|abstract)\b)(?:(?:virtual|static|new|sealed)[ \t]+)*(?!void\b|Task\b|ValueTask\b)[\w.<>,?]+(?])[ \t]+\KGet(?!Enumerator\b|Awaiter\b|Type\b|HashCode\b)\w+(?=[ \t]*\([ \t]*\))' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.inconsistent-operator-overloading + severity: WARNING + languages: + - csharp + message: >- + Implement the operators and methods that are consistent with the overloaded operators of this type. + Types overloading == must override Equals and GetHashCode, and types overloading arithmetic operators must overload ==. + pattern-either: + - pattern-regex: '(?m)^[ \t]*(?=[^\n]*\bpublic\b)[^\n]*?\b(?:class|struct)[ \t]+\K\w+\b(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*==)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boverride[ \t]+bool[ \t]+Equals\b)' + - pattern-regex: '(?m)^[ \t]*(?=[^\n]*\bpublic\b)[^\n]*?\b(?:class|struct)[ \t]+\K\w+\b(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*==)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boverride[ \t]+int[ \t]+GetHashCode\b)' + - pattern-regex: '(?m)^[ \t]*(?=[^\n]*\bpublic\b)[^\n]*?\b(?:class|struct)[ \t]+\K\w+\b(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*[-+*/%][ \t]*\()(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\boperator[ \t]*==)' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.compatibility.outdated-base-type + severity: WARNING + languages: + - csharp + message: >- + Do not derive this public type from an outdated base type. + Types such as ApplicationException, XmlDocument and the non-generic collection bases are obsolete designs. + pattern-regex: '(?m)^[ \t]*(?=[^\n]*\bpublic\b)[^\n]*?\bclass[ \t]+\K\w+(?=[^{;]*:[ \t]*(?:System\.(?:Collections\.|Xml\.)?)?(?:ApplicationException|XmlDocument|CollectionBase|DictionaryBase|Queue|ReadOnlyCollectionBase|SortedList|Stack)\b(?![ \t]*<))' + metadata: + category: compatibility + confidence: HIGH + - id: codacy.csharp.best-practice.string-literal-for-localizable-parameter + severity: WARNING + languages: + - csharp + message: >- + Load this user-facing text from a resource instead of hardcoding it. + String literals embedded in the code cannot be localized. + patterns: + - pattern-either: + - pattern: MessageBox.Show("$S", ...) + - pattern: $X.Text = "$S" + - pattern: $X.Caption = "$S" + - pattern: $X.ToolTipText = "$S" + - pattern: Console.Write("$S", ...) + - pattern: Console.WriteLine("$S", ...) + - metavariable-regex: + metavariable: $S + regex: '.*[A-Za-z]{2,}.*' + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.best-practice.missing-format-provider + severity: WARNING + languages: + - csharp + message: >- + Pass an IFormatProvider, such as CultureInfo.InvariantCulture, to this call. + Without it, formatting and parsing depend on the culture of the machine. + pattern-either: + - patterns: + - pattern: $T.Parse($S) + - metavariable-regex: + metavariable: $T + regex: '^(?:int|long|short|byte|uint|ulong|ushort|sbyte|double|float|decimal|Int32|Int64|Int16|Double|Single|Decimal)$' + - patterns: + - pattern: Convert.$M((string $S)) + - metavariable-regex: + metavariable: $M + regex: '^To(?:Int16|Int32|Int64|UInt16|UInt32|UInt64|Byte|SByte|Double|Single|Decimal|DateTime)$' + - pattern: string.Format("$F", ...) + - pattern: (int $X).ToString("$F") + - pattern: (long $X).ToString("$F") + - pattern: (double $X).ToString("$F") + - pattern: (decimal $X).ToString("$F") + - pattern: (DateTime $X).ToString("$F") + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.best-practice.datatable-without-locale + severity: WARNING + languages: + - csharp + message: >- + Set the Locale property of this DataTable or DataSet. + Without an explicit locale, comparisons and sorting depend on the culture of the machine. + patterns: + - pattern-either: + - pattern: var $D = new DataTable(...); + - pattern: var $D = new DataSet(...); + - pattern: DataTable $D = new DataTable(...); + - pattern: DataSet $D = new DataSet(...); + - pattern-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + $R $METH(...) { ... $D.Locale = $L; ... } + - focus-metavariable: $D + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.missing-string-comparison + severity: INFO + languages: + - csharp + message: >- + Pass a StringComparison to this string operation. + Making the comparison rules explicit avoids culture-dependent surprises. + pattern-either: + - pattern: string.Compare($A, $B) + - pattern: string.Compare($A, $B, true) + - pattern: string.Compare($A, $B, false) + - pattern: string.Equals((string $A), (string $B)) + - pattern: $S.StartsWith("$X") + - pattern: $S.EndsWith("$X") + - pattern: (string $S).IndexOf("$X") + - pattern: (string $S).LastIndexOf("$X") + - pattern: (string $S).CompareTo($X) + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.property-name-matches-get-method + severity: INFO + languages: + - csharp + message: >- + Rename this method or the property, their names only differ by the 'Get' prefix. + A property and a GetX method returning the same concept are confusing. + pattern-either: + - pattern-regex: '[\w.<>\[\],?]+[ \t]+(\w+)\b\s*(?:\{\s*(?:get|set|private|protected|internal)\b|=>)(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?[\w.<>\[\],?]+[ \t]+\KGet\1(?=[ \t]*\()' + - pattern-regex: '[\w.<>\[\],?]+[ \t]+\KGet(\w+)\b(?=[ \t]*\()(?=(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?[\w.<>\[\],?]+[ \t]+\1\b\s*(?:\{\s*(?:get|set|private|protected|internal)\b|=>))' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.performance.attribute-not-sealed + severity: WARNING + languages: + - csharp + message: >- + Seal this attribute class. + Sealed attributes are looked up faster by the runtime. + pattern-regex: '(?m)^[ \t]*(?![^\n]*\b(?:sealed|abstract|static)\b)[^\n]*?\bclass[ \t]+\K\w+(?=[^{;]*:[ \t]*(?:[\w.]+\.)?\w*Attribute\b)' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.compatibility.vararg-parameter + severity: WARNING + languages: + - csharp + message: >- + Use the 'params' keyword instead of '__arglist'. + The VarArgs calling convention is not CLS compliant and cannot be used from many .NET languages. + pattern-regex: '(?m)^[ \t]*(?:public|protected)\b(?![^\n]*\bextern\b)[^\n]*\([^()]*\K__arglist' + metadata: + category: compatibility + confidence: HIGH + - id: codacy.csharp.best-practice.operator-without-named-alternative + severity: WARNING + languages: + - csharp + message: >- + Add a method with a conventional name as an alternative to this operator overload. + Languages that do not support operator overloading can only use the named method, such as Add for '+'. + pattern-either: + - pattern-regex: '\A(?![\s\S]*\bAdd[ \t]*\()[\s\S]*?\boperator[ \t]*\K\+(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bSubtract[ \t]*\()[\s\S]*?\boperator[ \t]*\K-(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bMultiply[ \t]*\()[\s\S]*?\boperator[ \t]*\K\*(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bDivide[ \t]*\()[\s\S]*?\boperator[ \t]*\K/(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bMod[ \t]*\()[\s\S]*?\boperator[ \t]*\K%(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bBitwiseAnd[ \t]*\()[\s\S]*?\boperator[ \t]*\K&(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bBitwiseOr[ \t]*\()[\s\S]*?\boperator[ \t]*\K\|(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\bXor[ \t]*\()[\s\S]*?\boperator[ \t]*\K\^(?=[ \t]*\([^(),]*,[^()]*\))' + - pattern-regex: '\A(?![\s\S]*\b(?:Compare|CompareTo)[ \t]*\()[\s\S]*?\boperator[ \t]*\K(?:<=?|>=?)(?=[ \t]*\()' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.method-overloads-not-grouped + severity: INFO + languages: + - csharp + message: >- + Move this overload next to the other overloads of the same method. + Keeping overloads together makes the available signatures easy to find. + pattern-regex: '(?m)^[ \t]*(?:(?:public|private|protected|internal|static|virtual|override|async|abstract|new|sealed|unsafe|extern)[ \t]+)*(?!(?:return|else|new|await|throw|yield|case|goto|using|var)\b)[\w.<>\[\],?]+[ \t]+(\w+)[ \t]*(?:<[^<>]*>)?[ \t]*\([^()]*\)[ \t]*(?://[^\n]*)?\s*(?:\{|=>)(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?^[ \t]*(?:(?:public|private|protected|internal|static|virtual|override|async|abstract|new|sealed|unsafe|extern)[ \t]+)*(?!(?:return|else|new|await|throw|yield|case|goto|using|var)\b)[\w.<>\[\],?]+[ \t]+(?!\1\b)\w+[ \t]*(?:<[^<>]*>)?[ \t]*\([^()]*\)[ \t]*(?://[^\n]*)?\s*(?:\{|=>)(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?^[ \t]*(?:(?:public|private|protected|internal|static|virtual|override|async|abstract|new|sealed|unsafe|extern)[ \t]+)*(?!(?:return|else|new|await|throw|yield|case|goto|using|var)\b)[\w.<>\[\],?]+[ \t]+\K\1(?=[ \t]*(?:<[^<>]*>)?[ \t]*\()' + metadata: + category: codestyle + confidence: LOW + - id: codacy.csharp.best-practice.identical-method-implementations + severity: WARNING + languages: + - csharp + message: >- + Merge this method with the other method that has the same implementation. + Duplicated method bodies must be kept in sync and are often copy-paste mistakes. + pattern-regex: '[\w.<>\[\],?]+[ \t]+(\w+)[ \t]*\([^()]*\)(?:\s*//[^\n]*)*\s*(\{(?:[^{}]|\{[^{}]*\})*?;(?:[^{}]|\{[^{}]*\})*?;(?:[^{}]|\{[^{}]*\})*\})(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?[\w.<>\[\],?]+[ \t]+\K(?!\1\b)\w+(?=[ \t]*\([^()]*\)(?:\s*//[^\n]*)*\s*\2)' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.redundant-null-check-with-is + severity: INFO + languages: + - csharp + message: >- + Remove this redundant null check, the 'is' operator already returns false for null. + Combining a null check with a type check adds noise. + pattern-either: + - pattern: $X != null && $X is $T + - pattern: $X is $T && $X != null + - pattern: $X == null || !($X is $T) + - pattern: "!($X is $T) || $X == null" + options: + constant_propagation: false + metadata: + category: codestyle + confidence: HIGH + - id: codacy.csharp.best-practice.extension-method-on-object + severity: INFO + languages: + - csharp + message: >- + Do not extend 'object' with this extension method. + Extension methods on object appear on every type, which clutters IntelliSense and is rarely intended. + pattern-regex: '\bstatic\b[^;{=()\n]*[ \t]\K\w+(?=[ \t]*(?:<[^<>]*>)?[ \t]*\([ \t]*this[ \t]+(?:object|Object|System\.Object)\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.extension-method-in-same-namespace + severity: WARNING + languages: + - csharp + message: >- + Add this method to the extended class instead of declaring an extension method in the same namespace. + When the extended type is in the same namespace, the method can be a regular member. + pattern-regex: '\bnamespace[ \t]+[\w.]+(?:(?!\bnamespace\b)[\s\S])*?\b(?:class|struct)[ \t]+(\w+)\b(?:(?!\bnamespace\b)[\s\S])*?\([ \t]*\Kthis[ \t]+\1\b' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.parameterless-guid-creation + severity: WARNING + languages: + - csharp + message: >- + Use Guid.Empty or Guid.NewGuid() instead of this parameterless Guid creation. + 'new Guid()' creates an empty GUID, which is unclear and often a mistake. + pattern-either: + - pattern: new Guid() + - pattern: new System.Guid() + - pattern: default(Guid) + - pattern-regex: '\bGuid[ \t]+\w+[ \t]*=[ \t]*\Knew[ \t]*\([ \t]*\)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.substring-before-indexof + severity: WARNING + languages: + - csharp + message: >- + Use the overload with a start index instead of calling Substring before this search. + Substring allocates a new string just to search in it. + patterns: + - pattern: $S.Substring($I).$M(...) + - metavariable-regex: + metavariable: $M + regex: '^(?:IndexOf|IndexOfAny|LastIndexOf|LastIndexOfAny)$' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.increment-in-expression + severity: WARNING + languages: + - csharp + message: >- + Extract this increment or decrement operator into a separate statement. + Mixing increments with other operations or arguments makes the evaluation order hard to follow. + pattern-either: + - pattern: '$X++ + $Y' + - pattern: '$Y + $X++' + - pattern: '$X-- + $Y' + - pattern: '$Y + $X--' + - pattern: '++$X + $Y' + - pattern: '$Y + ++$X' + - pattern: '--$X + $Y' + - pattern: '$Y + --$X' + - pattern: '$X++ - $Y' + - pattern: '$Y - $X++' + - pattern: '$X-- - $Y' + - pattern: '$Y - $X--' + - pattern: '++$X - $Y' + - pattern: '$Y - ++$X' + - pattern: '--$X - $Y' + - pattern: '$Y - --$X' + - pattern: '$X++ * $Y' + - pattern: '$Y * $X++' + - pattern: '$X-- * $Y' + - pattern: '$Y * $X--' + - pattern: '++$X * $Y' + - pattern: '$Y * ++$X' + - pattern: '--$X * $Y' + - pattern: '$Y * --$X' + - pattern: '$X++ / $Y' + - pattern: '$Y / $X++' + - pattern: '$X-- / $Y' + - pattern: '$Y / $X--' + - pattern: '++$X / $Y' + - pattern: '$Y / ++$X' + - pattern: '--$X / $Y' + - pattern: '$Y / --$X' + - pattern: '$X++ % $Y' + - pattern: '$Y % $X++' + - pattern: '$X-- % $Y' + - pattern: '$Y % $X--' + - pattern: '++$X % $Y' + - pattern: '$Y % ++$X' + - pattern: '--$X % $Y' + - pattern: '$Y % --$X' + - pattern: '$F(..., $X++, ...)' + - pattern: '$O.$F(..., $X++, ...)' + - pattern: '$F(..., $X--, ...)' + - pattern: '$O.$F(..., $X--, ...)' + - pattern: '$F(..., ++$X, ...)' + - pattern: '$O.$F(..., ++$X, ...)' + - pattern: '$F(..., --$X, ...)' + - pattern: '$O.$F(..., --$X, ...)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.parameter-name-differs-from-declaration + severity: INFO + languages: + - csharp + message: >- + Rename this parameter to match the name used in the interface, base or partial declaration. + Different names for the same parameter confuse callers that use named arguments. + pattern-regex: '\b(\w+)[ \t]*\([ \t]*([\w.<>\[\]?]+)[ \t]+(\w+)\b[ \t]*\)[ \t]*;[\s\S]*?[\w.<>\[\],?]+[ \t]+\1[ \t]*\([ \t]*\2[ \t]+\K(?!\3\b)\w+(?=[ \t]*\)(?:\s*//[^\n]*)*\s*(?:\{|=>))' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.codestyle.mergeable-try-statements + severity: INFO + languages: + - csharp + message: >- + Merge this try statement with the previous one, they have the same catch clause. + Separate try statements with identical handlers duplicate code. + pattern-regex: '\btry\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\}\s*(catch\b[^{]*\{(?:[^{}]|\{[^{}]*\})*\})\s*(?:[^{};]*;\s*)*\btry\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\}\s*\K\1' + metadata: + category: codestyle + confidence: MEDIUM + - id: codacy.csharp.best-practice.untestable-system-clock + severity: WARNING + languages: + - csharp + message: >- + Use an injectable clock or TimeProvider instead of reading the system clock directly. + Static clock access cannot be controlled in unit tests, which makes time-dependent code hard to test. + pattern-either: + - pattern: DateTime.Now + - pattern: DateTime.UtcNow + - pattern: DateTime.Today + - pattern: DateTimeOffset.Now + - pattern: DateTimeOffset.UtcNow + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.stateful-azure-function + severity: WARNING + languages: + - csharp + message: >- + Do not store state in static fields of this Azure Function. + Function instances are created and recycled by the platform, so static state is lost or shared unpredictably. + patterns: + - pattern-either: + - pattern-inside: | + class $C { ... static $T $F; ... } + - pattern-inside: | + class $C { ... static $T $F = $I; ... } + - pattern-either: + - pattern-inside: | + [FunctionName($N)] + $R $FN(...) { ... } + - pattern-inside: | + [Function($N)] + $R $FN(...) { ... } + - pattern-either: + - pattern: $F = $V + - pattern: $F += $V + - pattern: $F -= $V + - pattern: $F++ + - pattern: $F-- + - pattern: ++$F + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.performance.client-created-per-azure-function-invocation + severity: ERROR + languages: + - csharp + message: >- + Reuse this client instead of creating it on each Azure Function invocation. + Creating clients such as HttpClient or storage clients for every call exhausts sockets and slows down the function. + patterns: + - pattern-either: + - pattern-inside: | + [FunctionName($N)] + $R $FN(...) { ... } + - pattern-inside: | + [Function($N)] + $R $FN(...) { ... } + - pattern: new $T(...) + - metavariable-regex: + metavariable: $T + regex: '^(?:System\.Net\.Http\.)?(?:HttpClient|BlobServiceClient|BlobContainerClient|BlobClient|QueueClient|QueueServiceClient|TableClient|TableServiceClient|CosmosClient|DocumentClient|ServiceBusClient|EventHubProducerClient|EventHubConsumerClient|SecretClient|KeyClient|CertificateClient|SearchClient)$' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.azure-function-without-error-handling + severity: WARNING + languages: + - csharp + message: >- + Wrap the body of this Azure Function in a try/catch block that logs failures. + Unhandled exceptions are hard to monitor and diagnose without explicit logging. + patterns: + - pattern-either: + - pattern: | + [FunctionName($N)] + $R $FN(...) { ... } + - pattern: | + [Function($N)] + $R $FN(...) { ... } + - pattern-not: | + [FunctionName($N)] + $R $FN(...) { ... try { ... } catch ($T $E) { ... } ... } + - pattern-not: | + [FunctionName($N)] + $R $FN(...) { ... try { ... } catch { ... } ... } + - pattern-not: | + [Function($N)] + $R $FN(...) { ... try { ... } catch ($T $E) { ... } ... } + - focus-metavariable: $FN + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.performance.blocking-call-in-azure-function + severity: ERROR + languages: + - csharp + message: >- + Await this call instead of blocking inside the Azure Function. + Blocking calls waste threads of the function host and can exhaust the thread pool. + patterns: + - pattern-either: + - pattern-inside: | + [FunctionName($N)] + $R $FN(...) { ... } + - pattern-inside: | + [Function($N)] + $R $FN(...) { ... } + - pattern-either: + - pattern: $X.Result + - pattern: $X.Wait(...) + - pattern: $X.GetAwaiter().GetResult() + - pattern: Thread.Sleep(...) + - pattern: Task.WaitAll(...) + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.best-practice.azure-function-failure-not-logged + severity: ERROR + languages: + - csharp + message: >- + Log this failure at warning level or above in the Azure Function. + Failures that are not logged, or only logged at debug level, are invisible in production monitoring. + patterns: + - pattern-either: + - pattern-inside: | + [FunctionName($N)] + $R $FN(...) { ... } + - pattern-inside: | + [Function($N)] + $R $FN(...) { ... } + - pattern-regex: '\b\Kcatch\b(?:[ \t]*\([^()]*\))?(?:\s*//[^\n]*)*\s*\{(?!(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\.(?:Log(?:Error|Critical|Warning|Information)?|Error|Fatal|Warn|Warning|TrackException)[ \t]*\()' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.exclude-from-coverage-without-justification + severity: WARNING + languages: + - csharp + message: >- + Add a Justification to this ExcludeFromCodeCoverage attribute. + Excluding code from coverage without explaining why makes the exclusion impossible to review. + pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\K(?:System\.Diagnostics\.CodeAnalysis\.)?ExcludeFromCodeCoverage(?:Attribute)?\b(?![ \t]*\([^)]*\bJustification\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.datetime-now-for-timing + severity: WARNING + languages: + - csharp + message: >- + Use a Stopwatch to measure elapsed time instead of DateTime.Now. + DateTime.Now has a low resolution and jumps when the clock is adjusted, for example at daylight saving changes. + pattern-either: + - pattern: DateTime.Now - $X + - pattern: $X - DateTime.Now + - pattern: DateTime.Now.Subtract($X) + - pattern: $X.Subtract(DateTime.Now) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.local-time-recorded + severity: WARNING + languages: + - csharp + message: >- + Use DateTime.UtcNow instead of DateTime.Now or DateTime.Today to record this instant. + Local times are ambiguous across time zones and daylight saving transitions. + pattern-either: + - pattern: DateTime.Now + - pattern: DateTime.Today + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.datetime-instead-of-datetimeoffset + severity: WARNING + languages: + - csharp + message: >- + Use DateTimeOffset instead of DateTime. + DateTimeOffset keeps the offset from UTC, which avoids time zone ambiguities. + pattern-either: + - pattern: DateTime.Now + - pattern: DateTime.UtcNow + - pattern: DateTime.Today + - pattern: new DateTime(...) + metadata: + category: best-practice + confidence: LOW + - id: codacy.csharp.best-practice.manual-timezone-conversion + severity: INFO + languages: + - csharp + message: >- + Pass the time zone identifier directly to TimeZoneInfo.FindSystemTimeZoneById. + Since .NET 6, IANA and Windows identifiers are both supported, so converting them manually is unnecessary. + pattern-either: + - pattern: TZConvert.IanaToWindows(...) + - pattern: TZConvert.WindowsToIana(...) + - pattern: TZConvert.RailsToIana(...) + - pattern: TZConvert.RailsToWindows(...) + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.hardcoded-date-format + severity: WARNING + languages: + - csharp + message: >- + Use a standard format or an IFormatProvider instead of hardcoding this date format. + Custom date formats are easily misunderstood by users from other cultures and are error-prone. + patterns: + - pattern-either: + - pattern: DateTime.$P.ToString("$F") + - pattern: DateTimeOffset.$P.ToString("$F") + - pattern: (DateTime $D).ToString("$F") + - pattern: (DateTimeOffset $D).ToString("$F") + - metavariable-regex: + metavariable: $F + regex: '^(?![dDfFgGmMoOrRsStTuUyY]$).*[dMyHhmsfFtz]' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.unix-epoch-created-manually + severity: INFO + languages: + - csharp + message: >- + Use DateTime.UnixEpoch or DateTimeOffset.UnixEpoch instead of creating this date. + The predefined field is clearer and avoids mistakes in the date components or kind. + pattern-either: + - pattern: new DateTime(1970, 1, 1) + - pattern: new DateTime(1970, 1, 1, 0, 0, 0) + - pattern: new DateTime(1970, 1, 1, 0, 0, 0, $K) + - pattern: new DateTime(1970, 1, 1, 0, 0, 0, 0, $K) + - pattern: new DateTimeOffset(1970, 1, 1, 0, 0, 0, $O) + - pattern: new System.DateTime(1970, 1, 1) + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.use-find-instead-of-firstordefault + severity: WARNING + languages: + - csharp + message: >- + Use Find() instead of FirstOrDefault() on this list or array. + The collection specific method avoids the overhead of LINQ enumeration. + pattern-either: + - pattern: (List<$T> $L).FirstOrDefault($P) + - pattern: ($T[] $L).FirstOrDefault($P) + - pattern: (ImmutableList<$T> $L).FirstOrDefault($P) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.use-trueforall-instead-of-all + severity: WARNING + languages: + - csharp + message: >- + Use TrueForAll() instead of All() on this list or array. + The collection specific method avoids the overhead of LINQ enumeration. + pattern-either: + - pattern: (List<$T> $L).All($P) + - pattern: ($T[] $L).All($P) + - pattern: (ImmutableList<$T> $L).All($P) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.use-exists-instead-of-any + severity: WARNING + languages: + - csharp + message: >- + Use Exists() instead of Any() with a predicate on this list or array. + The collection specific method avoids the overhead of LINQ enumeration. + pattern-either: + - pattern: (List<$T> $L).Any($P) + - pattern: ($T[] $L).Any($P) + - pattern: (ImmutableList<$T> $L).Any($P) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.orderby-before-where + severity: WARNING + languages: + - csharp + message: >- + Call Where() before OrderBy() in this query. + Filtering first means fewer elements need to be sorted. + pattern-either: + - pattern: $X.OrderBy(...).Where(...) + - pattern: $X.OrderByDescending(...).Where(...) + - pattern: $X.ThenBy(...).Where(...) + - pattern: $X.ThenByDescending(...).Where(...) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.enumerable-method-instead-of-indexing + severity: WARNING + languages: + - csharp + message: >- + Use indexing instead of this Enumerable method on a list or array. + Calls such as First(), Last() or ElementAt() go through LINQ instead of using direct index access. + pattern-either: + - pattern: (List<$T> $L).First() + - pattern: (List<$T> $L).Last() + - pattern: (List<$T> $L).ElementAt($I) + - pattern: ($T[] $L).First() + - pattern: ($T[] $L).Last() + - pattern: ($T[] $L).ElementAt($I) + - pattern: (IList<$T> $L).First() + - pattern: (IList<$T> $L).Last() + - pattern: (IList<$T> $L).ElementAt($I) + - pattern: (IReadOnlyList<$T> $L).First() + - pattern: (IReadOnlyList<$T> $L).Last() + - pattern: (IReadOnlyList<$T> $L).ElementAt($I) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.enumerable-min-max-on-sorted-set + severity: WARNING + languages: + - csharp + message: >- + Use the Min or Max property of this sorted set instead of the Enumerable method. + The properties return the value directly instead of enumerating the set. + pattern-either: + - pattern: (SortedSet<$T> $S).Min() + - pattern: (SortedSet<$T> $S).Max() + - pattern: (ImmutableSortedSet<$T> $S).Min() + - pattern: (ImmutableSortedSet<$T> $S).Max() + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.string-overload-for-single-char + severity: WARNING + languages: + - csharp + message: >- + Use the char overload of StartsWith or EndsWith for this single character. + The char overload is faster and is not affected by culture-specific comparison rules. + patterns: + - pattern-either: + - pattern: $S.StartsWith("$C") + - pattern: $S.EndsWith("$C") + - metavariable-regex: + metavariable: $C + regex: '^(?:[^\\]|\\.)$' + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.concurrentdictionary-lambda-captures-key + severity: WARNING + languages: + - csharp + message: >- + Use the lambda parameter instead of capturing the key in this ConcurrentDictionary call. + Capturing the key allocates a closure on every call. + patterns: + - pattern-either: + - pattern: $D.GetOrAdd($K, ($P) => <... $K ...>) + - pattern: $D.GetOrAdd($K, $P => <... $K ...>) + - pattern: $D.AddOrUpdate($K, $P => <... $K ...>, ...) + - pattern: $D.AddOrUpdate($K, $A, ($P, $V) => <... $K ...>) + - metavariable-regex: + metavariable: $K + regex: '^\w+$' + - metavariable-comparison: + comparison: str($P) != str($K) + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.performance.enumerable-first-last-on-linkedlist + severity: WARNING + languages: + - csharp + message: >- + Use the First or Last property of this LinkedList instead of the Enumerable method. + The properties return the node directly instead of enumerating the list. + pattern-either: + - pattern: (LinkedList<$T> $L).First() + - pattern: (LinkedList<$T> $L).Last() + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.performance.any-with-equality-instead-of-contains + severity: WARNING + languages: + - csharp + message: >- + Use Contains() instead of Any() with an equality check. + Contains is clearer and can use an optimized lookup such as a hash set. + patterns: + - pattern-either: + - pattern: $C.Any($X => $X == $V) + - pattern: $C.Any($X => $V == $X) + - pattern-not: $C.Any($X => $X == <... $X ...>) + - pattern-not: $C.Any($X => <... $X ...> == $X) + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.performance.formattablestring-instead-of-string-create + severity: WARNING + languages: + - csharp + message: >- + Use string.Create() instead of FormattableString for this interpolated string. + string.Create formats directly into the result without allocating an intermediate FormattableString. + pattern-either: + - pattern: FormattableString.Invariant(...) + - pattern: FormattableString.CurrentCulture(...) + metadata: + category: performance + confidence: HIGH + - id: codacy.csharp.best-practice.caught-exception-not-logged + severity: WARNING + languages: + - csharp + message: >- + Pass the caught exception to this logging call. + Logging only a message loses the stack trace and the details of the failure. + patterns: + - pattern-either: + - pattern-inside: | + try { ... } catch ($T $E) { ... } + - pattern-inside: | + try { ... } catch ($T $E) { ... } finally { ... } + - pattern: $L.$LOG(...) + - pattern-not: $L.$LOG(..., $E, ...) + - metavariable-regex: + metavariable: $LOG + regex: '^(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|Trace|Debug|Info|Information|Warn|Warning|Error|Fatal|Verbose)$' + - metavariable-regex: + metavariable: $L + regex: '(?i).*log.*' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.trace-write + severity: WARNING + languages: + - csharp + message: >- + Use Trace.TraceError, Trace.TraceWarning or Trace.TraceInformation instead of Trace.Write. + Trace.Write and Trace.WriteLine do not carry a severity, which makes the output hard to filter. + pattern-either: + - pattern: Trace.Write(...) + - pattern: Trace.WriteLine(...) + - pattern: System.Diagnostics.Trace.Write(...) + - pattern: System.Diagnostics.Trace.WriteLine(...) + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.generic-logger-type-mismatch + severity: WARNING + languages: + - csharp + message: >- + Use the enclosing type as the type argument of this ILogger. + The type argument defines the logging category, so a different type makes log entries hard to attribute. + pattern-regex: '\bclass[ \t]+(\w+)\b(?:(?!\b(?:class|struct|interface|record)\b)[\s\S])*?\bILogger[ \t]*<[ \t]*\K(?!\1[ \t]*>)[\w.]+(?=[ \t]*>[ \t]+\w+[ \t]*[,)])' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.trace-writelineif-with-traceswitch + severity: WARNING + languages: + - csharp + message: >- + Use the TraceSwitch level with Trace.TraceError, TraceWarning or TraceInformation instead of Trace.WriteLineIf. + WriteLineIf with a switch level writes the message without its severity, which is misleading. + patterns: + - pattern-either: + - pattern: Trace.WriteLineIf($S.$LEVEL, ...) + - pattern: Trace.WriteIf($S.$LEVEL, ...) + - metavariable-regex: + metavariable: $LEVEL + regex: '^Trace(?:Error|Warning|Info|Verbose)$' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.best-practice.duplicate-log-template-placeholder + severity: WARNING + languages: + - csharp + message: >- + Use unique names for the placeholders of this message template. + Structured logging stores values by placeholder name, so duplicated names lose information. + patterns: + - pattern-either: + - pattern: $L.$LOG("$T", ...) + - pattern: $L.$LOG($X, "$T", ...) + - metavariable-regex: + metavariable: $LOG + regex: '^(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|BeginScope|Verbose|Debug|Information|Warning|Error|Fatal)$' + - metavariable-regex: + metavariable: $T + regex: '(?s).*(?- + Use PascalCase for the named placeholders of this message template. + Consistent placeholder names make structured logs easier to query. + patterns: + - pattern-either: + - pattern: $L.$LOG("$T", ...) + - pattern: $L.$LOG($X, "$T", ...) + - metavariable-regex: + metavariable: $LOG + regex: '^(?:Log(?:Trace|Debug|Information|Warning|Error|Critical)?|BeginScope|Verbose|Debug|Information|Warning|Error|Fatal)$' + - metavariable-regex: + metavariable: $T + regex: '(?s).*(?- + Use a forward slash instead of a backslash in this route template. + Backslashes are not route separators, so the route does not match what was intended. + pattern-either: + - pattern-regex: '\[[ \t]*\K(?:Route|Http(?:Get|Post|Put|Delete|Patch|Head|Options))[ \t]*\([ \t]*(?:template:[ \t]*)?(?:@\"[^\"]*\\|\"(?:[^\"\\]|\\[^\\])*\\\\)' + - pattern-regex: '\bMap\w*[ \t]*\([^;]*?\K(?:@\"[^\"]*\\[^\"]*\"|\"(?:[^\"\\]|\\[^\\])*\\\\[^\"]*\")' + metadata: + category: compatibility + confidence: HIGH + - id: codacy.csharp.best-practice.absolute-action-route-template + severity: WARNING + languages: + - csharp + message: >- + Use relative route templates for the actions of this controller. + Action templates starting with '/' ignore the route prefix of the controller. + pattern-regex: '\[[ \t]*Route[ \t]*\([^\]]*\][^{]*?\bclass[ \t]+\K\w+(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\[[ \t]*(?:Http(?:Get|Post|Put|Delete|Patch|Head|Options)|Route)[ \t]*\([ \t]*(?:template:[ \t]*)?\"/)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\[[ \t]*(?:Http(?:Get|Post|Put|Delete|Patch|Head|Options)|Route)[ \t]*\([ \t]*(?:template:[ \t]*)?\"(?!/))' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.raw-request-data-in-controller + severity: WARNING + languages: + - csharp + message: >- + Use model binding instead of reading the request data directly. + Model binding validates and converts the input, and documents the expected parameters. + patterns: + - pattern-either: + - pattern-inside: | + class $C : $B { ... } + - pattern-inside: | + class $C : $B, $I { ... } + - metavariable-regex: + metavariable: $B + regex: '.*Controller(?:Base)?$' + - pattern-either: + - pattern: Request.Form + - pattern: Request.Query + - pattern: Request.Headers + - pattern: Request.RouteValues + - pattern: Request.QueryString + - pattern: HttpContext.Request.Form + - pattern: HttpContext.Request.Query + - pattern-not-inside: Request.Form.$F + - pattern-not-inside: Request.Query.$F + - pattern-not-inside: Request.Headers.$F + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.action-route-without-controller-route + severity: WARNING + languages: + - csharp + message: >- + Add a Route attribute to this controller, one of its actions defines a route template. + Mixing conventional routing on the controller with attribute routing on actions leads to unexpected URLs. + pattern-regex: '(?m)(?:\A|^(?![ \t]*\[)[^\n]*\r?\n)(?:[ \t]*\[(?![^\]]*\bRoute\b)[^\]]*\][^\n]*\r?\n)*[ \t]*(?:public[ \t]+)?(?:(?:sealed|abstract|partial)[ \t]+)*class[ \t]+\K\w+(?=[^{;]*:[ \t]*\w*Controller(?:Base)?\b)(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\[[ \t]*(?:Http(?:Get|Post|Put|Delete|Patch|Head|Options)|Route)[ \t]*\([ \t]*(?:template:[ \t]*)?\"[^\"]+\")' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.api-controller-derives-from-controller + severity: WARNING + languages: + - csharp + message: >- + Derive this API controller from ControllerBase instead of Controller. + Controller adds view support that API controllers do not use. + pattern-regex: '\[[ \t]*ApiController[ \t]*\](?![^{]*\bNonController\b)[^{]*?\bclass[ \t]+\K\w+(?=[^{;]*:[ \t]*(?:Microsoft\.AspNetCore\.Mvc\.)?Controller\b(?![ \t]*Base))(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b(?:View|PartialView|ViewComponent|ViewBag|ViewData|TempData|Json)\b)' + metadata: + category: best-practice + confidence: HIGH + - id: codacy.csharp.performance.httpclient-created-per-call + severity: ERROR + languages: + - csharp + message: >- + Use IHttpClientFactory or a shared HttpClient instead of creating one here. + Creating an HttpClient for each call can exhaust sockets under load. + patterns: + - pattern: new HttpClient(...) + - pattern-inside: | + $R $M(...) { ... } + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.best-practice.api-action-without-http-verb + severity: WARNING + languages: + - csharp + message: >- + Annotate this API action with an HTTP verb attribute such as [HttpGet] or [HttpPost]. + Without it, the action accepts every HTTP method and is documented ambiguously. + patterns: + - pattern-inside: | + [ApiController] + class $C { ... } + - pattern: | + public $R $M(...) { ... } + - pattern-not: | + [HttpGet] + public $R $M(...) { ... } + - pattern-not: | + [HttpGet(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpPost] + public $R $M(...) { ... } + - pattern-not: | + [HttpPost(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpPut] + public $R $M(...) { ... } + - pattern-not: | + [HttpPut(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpDelete] + public $R $M(...) { ... } + - pattern-not: | + [HttpDelete(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpPatch] + public $R $M(...) { ... } + - pattern-not: | + [HttpPatch(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpHead] + public $R $M(...) { ... } + - pattern-not: | + [HttpHead(...)] + public $R $M(...) { ... } + - pattern-not: | + [HttpOptions] + public $R $M(...) { ... } + - pattern-not: | + [HttpOptions(...)] + public $R $M(...) { ... } + - pattern-not: | + [AcceptVerbs] + public $R $M(...) { ... } + - pattern-not: | + [AcceptVerbs(...)] + public $R $M(...) { ... } + - pattern-not: | + [NonAction] + public $R $M(...) { ... } + - pattern-not: | + [NonAction(...)] + public $R $M(...) { ... } + - pattern-not: | + [ApiExplorerSettings] + public $R $M(...) { ... } + - pattern-not: | + [ApiExplorerSettings(...)] + public $R $M(...) { ... } + - focus-metavariable: $M + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.performance.blocking-call-in-async-method + severity: ERROR + languages: + - csharp + message: >- + Use the asynchronous counterpart of this blocking call and await it. + Blocking inside an async method wastes a thread and reduces scalability. + patterns: + - pattern-inside: | + async $R $M(...) { ... } + - pattern-not-inside: | + ($P) => { ... } + - pattern-not-inside: | + () => { ... } + - pattern-either: + - patterns: + - pattern: File.$F(...) + - metavariable-regex: + metavariable: $F + regex: '^(?:ReadAllText|ReadAllBytes|ReadAllLines|WriteAllText|WriteAllBytes|WriteAllLines|AppendAllText|AppendAllLines)$' + - patterns: + - pattern: $S.$F(...) + - metavariable-regex: + metavariable: $F + regex: '^(?:SaveChanges|ReadToEnd|CopyTo|Flush)$' + - pattern: $S.Read($B, $O, $C) + - pattern: $S.Write($B, $O, $C) + - pattern: Thread.Sleep(...) + - pattern: $X.Wait() + - pattern: $X.GetAwaiter().GetResult() + metadata: + category: performance + confidence: MEDIUM + - id: codacy.csharp.best-practice.model-state-not-validated + severity: WARNING + languages: + - csharp + message: >- + Check ModelState.IsValid in this controller action before using its input. + Without the check, invalid input is processed as if it were valid. + patterns: + - pattern-not-inside: | + [ApiController] + class $C { ... } + - pattern-regex: '\[[ \t]*Http(?:Post|Put|Patch)\b[^\]]*\]\s*(?:\[[^\]]*\]\s*)*public[ \t]+(?:(?:async|virtual|override|new)[ \t]+)*[\w.<>]+[ \t]+\K\w+(?=[ \t]*\([ \t]*(?:\[[^\]]*\][ \t]*)?(?!(?:string|int|long|bool|Guid|DateTime|decimal|double)\b)[A-Z][\w.<>]*[ \t]+\w+[^)]*\)(?:\s*//[^\n]*)*\s*\{(?:(?!\bModelState\b)[^{}]|\{(?:(?!\bModelState\b)[^{}]|\{(?:(?!\bModelState\b)[^{}])*\})*\})*\})' + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.best-practice.action-without-produces-response-type + severity: WARNING + languages: + - csharp + message: >- + Annotate this action with a ProducesResponseType attribute that specifies the type of the returned value. + API documentation generators cannot infer the response type of IActionResult actions. + patterns: + - pattern-inside: | + [ApiController] + class $C { ... } + - pattern-either: + - pattern: | + $R $M(...) { ... return Ok($X); } + - pattern: | + $R $M(...) { ... return Created($U, $X); } + - pattern: | + $R $M(...) { ... return CreatedAtAction(...); } + - metavariable-regex: + metavariable: $R + regex: '^(?:Task<)?(?:IActionResult|ActionResult|IResult)>?$' + - pattern-not: | + [ProducesResponseType(typeof($T), ...)] + $R $M(...) { ... } + - pattern-not: | + [ProducesResponseType<$T>(...)] + $R $M(...) { ... } + - focus-metavariable: $M + metadata: + category: best-practice + confidence: MEDIUM + - id: codacy.csharp.security.predictable-password-salt + severity: ERROR + languages: + - csharp + message: >- + Use a random salt generated by a cryptographic random number generator for this password hash. + A constant or predictable salt lets attackers precompute hashes and crack passwords faster. + pattern-either: + - patterns: + - pattern-either: + - pattern: new Rfc2898DeriveBytes($P, $SALT, ...) + - pattern: Rfc2898DeriveBytes.Pbkdf2($P, $SALT, ...) + - pattern: new PasswordDeriveBytes($P, $SALT, ...) + - metavariable-pattern: + metavariable: $SALT + pattern-either: + - pattern: Encoding.$E.GetBytes("$S") + - pattern: 'new byte[] { ... }' + - patterns: + - pattern-either: + - pattern: new Rfc2898DeriveBytes($P, $SALT, ...) + - pattern: Rfc2898DeriveBytes.Pbkdf2($P, $SALT, ...) + - pattern: new PasswordDeriveBytes($P, $SALT, ...) + - pattern-either: + - pattern-inside: | + $T $SALT = Encoding.$E.GetBytes("$S"); + ... + - pattern-inside: | + var $SALT = Encoding.$E.GetBytes("$S"); + ... + - pattern-inside: | + $T $SALT = new byte[] { ... }; + ... + - pattern-inside: | + var $SALT = new byte[] { ... }; + ... + metadata: + category: security + cwe: 'CWE-759: Use of a One-Way Hash without a Salt' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: MEDIUM + - id: codacy.csharp.security.hardcoded-credentials + severity: ERROR + languages: + - csharp + message: >- + Remove this hardcoded credential and load it from a secure configuration source. + Credentials in source code can be read by anyone with access to the code or the compiled binaries. + pattern-either: + - patterns: + - pattern-either: + - pattern: $T $X = $LIT; + - pattern: var $X = $LIT; + - pattern: $X = $LIT + - pattern: $O.$X = $LIT + - pattern: 'new $C { ..., $X = $LIT, ... }' + - metavariable-regex: + metavariable: $X + regex: '(?i).*(?:password|passwd|pwd|passphrase).*' + - metavariable-regex: + metavariable: $LIT + regex: '^@?"(?=[^"]*\S)(?![^"]*\{\d+\})(?![^"]*[Pp]laceholder)[^"]+"$' + - focus-metavariable: $LIT + - patterns: + - pattern: '"$S"' + - metavariable-regex: + metavariable: $S + regex: '(?i)(?:.*[;&?](?:password|passwd|pwd|passphrase)=[^;&\s"]+.*|.*\b[a-z][\w+.-]*://[^:/@\s]+:[^@/\s]+@.*)' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-798: Use of Hard-coded Credentials' + owasp: 'A07:2021 - Identification and Authentication Failures' + confidence: MEDIUM + - id: codacy.csharp.security.cookie-without-secure-flag + severity: ERROR + languages: + - csharp + message: >- + Make sure that this cookie is only sent over HTTPS by setting its Secure flag. + Cookies without the Secure flag can be intercepted on unencrypted connections. + pattern-either: + - pattern: $C.Secure = false + - pattern: 'new CookieOptions { ..., Secure = false, ... }' + - patterns: + - pattern-either: + - pattern: var $C = new HttpCookie(...); + - pattern: HttpCookie $C = new HttpCookie(...); + - pattern-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + $R $METH(...) { ... $C.Secure = $V; ... } + metadata: + category: security + cwe: 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: MEDIUM + - id: codacy.csharp.security.database-connection-without-password + severity: ERROR + languages: + - csharp + message: >- + Set a password for this database connection, or use integrated security. + A database that accepts connections without a password can be accessed by anyone who can reach it. + patterns: + - pattern: '"$S"' + - pattern-not-inside: '"$S" + $X' + - metavariable-regex: + metavariable: $S + regex: '(?i)^(?!.*integrated\s*security\s*=\s*(?:true|sspi|yes))(?=.*\b(?:server|data\s*source|host)\s*=).*\b(?:password|pwd)\s*=\s*(?:;.*)?$' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-521: Weak Password Requirements' + owasp: 'A07:2021 - Identification and Authentication Failures' + confidence: HIGH + - id: codacy.csharp.security.weak-pseudorandom-number-generator + severity: ERROR + languages: + - csharp + message: >- + Make sure that using this pseudorandom number generator is safe here. + System.Random is predictable; use RandomNumberGenerator for security-sensitive values such as tokens or keys. + pattern-either: + - pattern: 'new Random(...)' + - pattern: 'new System.Random(...)' + - pattern: 'Random.Shared' + metadata: + category: security + cwe: 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: LOW + - id: codacy.csharp.security.custom-cryptographic-algorithm + severity: ERROR + languages: + - csharp + message: >- + Use a standard cryptographic algorithm instead of implementing your own. + Custom cryptography is almost always weaker than the well-reviewed standard implementations. + pattern-regex: '\bclass[ \t]+\K\w+(?=[^{;]*:[ \t]*(?:System\.Security\.Cryptography\.)?(?:HashAlgorithm|SymmetricAlgorithm|AsymmetricAlgorithm|KeyedHashAlgorithm|ICryptoTransform|DeriveBytes|RandomNumberGenerator|AsymmetricSignatureFormatter|AsymmetricKeyExchangeFormatter)\b)' + metadata: + category: security + cwe: 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.loose-file-permissions + severity: ERROR + languages: + - csharp + message: >- + Make sure that granting these permissions to everyone is safe here. + World-accessible files and directories can be read or modified by any user or process. + pattern-either: + - pattern: new FileSystemAccessRule("Everyone", ...) + - pattern: new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, ...), ...) + - patterns: + - pattern: $F.FileAccessPermissions = $P + - metavariable-regex: + metavariable: $P + regex: '(?s).*FileAccessPermissions\.(?:Other\w*|AllPermissions|DefaultPermissions).*' + metadata: + category: security + cwe: 'CWE-732: Incorrect Permission Assignment for Critical Resource' + owasp: 'A01:2021 - Broken Access Control' + confidence: MEDIUM + - id: codacy.csharp.security.xml-external-entity-processing + severity: ERROR + languages: + - csharp + message: >- + Disable external entity processing for this XML parser. + Resolving external entities exposes the application to XML External Entity (XXE) attacks. + pattern-either: + - pattern: 'new XmlUrlResolver()' + - pattern: '$X.DtdProcessing = DtdProcessing.Parse' + - pattern: '$X.ProhibitDtd = false' + - pattern: 'new XmlReaderSettings { ..., DtdProcessing = DtdProcessing.Parse, ... }' + metadata: + category: security + cwe: 'CWE-611: Improper Restriction of XML External Entity Reference' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: MEDIUM + - id: codacy.csharp.security.predictable-initialization-vector + severity: ERROR + languages: + - csharp + message: >- + Use a randomly generated initialization vector for this encryption. + A constant initialization vector makes identical plaintexts produce identical ciphertexts. + pattern-either: + - patterns: + - pattern-either: + - pattern: $A.CreateEncryptor($K, $IV) + - pattern: $A.IV = $IV + - metavariable-pattern: + metavariable: $IV + pattern-either: + - pattern: new byte[$N] + - pattern: 'new byte[] { ... }' + - pattern: Encoding.$E.GetBytes("$S") + - patterns: + - pattern-either: + - pattern: $A.CreateEncryptor($K, $IV) + - pattern: $A.IV = $IV + - pattern-either: + - pattern-inside: | + $T $IV = new byte[$N]; + ... + - pattern-inside: | + var $IV = new byte[$N]; + ... + - pattern-inside: | + var $IV = Encoding.$E.GetBytes("$S"); + ... + - pattern-inside: | + $T $IV = Encoding.$E.GetBytes("$S"); + ... + - pattern-not-inside: | + $T $IV = new byte[$N]; + ... + $RNG.$FILL($IV); + ... + - pattern-not-inside: | + var $IV = new byte[$N]; + ... + $RNG.$FILL($IV); + ... + metadata: + category: security + cwe: 'CWE-329: Generation of Predictable IV with CBC Mode' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: MEDIUM + - id: codacy.csharp.security.cookie-without-httponly-flag + severity: ERROR + languages: + - csharp + message: >- + Make sure that this cookie cannot be read by client-side scripts by setting its HttpOnly flag. + Cookies readable from JavaScript can be stolen through cross-site scripting attacks. + pattern-either: + - pattern: $C.HttpOnly = false + - pattern: 'new CookieOptions { ..., HttpOnly = false, ... }' + - patterns: + - pattern-either: + - pattern: var $C = new HttpCookie(...); + - pattern: HttpCookie $C = new HttpCookie(...); + - pattern-inside: | + $R $METH(...) { ... } + - pattern-not-inside: | + $R $METH(...) { ... $C.HttpOnly = $V; ... } + metadata: + category: security + cwe: 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: MEDIUM + - id: codacy.csharp.security.dangerous-safehandle-access + severity: ERROR + languages: + - csharp + message: >- + Do not call SafeHandle.DangerousGetHandle(). + The raw handle may be invalid or recycled, which can lead to resource leaks and handle recycling attacks. + pattern-either: + - pattern: '$H.DangerousGetHandle()' + metadata: + category: security + cwe: 'CWE-672: Operation on a Resource after Expiration or Release' + owasp: 'A04:2021 - Insecure Design' + confidence: HIGH + - id: codacy.csharp.security.com-security-call-in-managed-code + severity: WARNING + languages: + - csharp + message: >- + Do not call CoSetProxyBlanket or CoInitializeSecurity from managed code. + The runtime has already initialized COM security, so these calls are ignored or fail. + pattern-either: + - pattern: 'CoSetProxyBlanket(...)' + - pattern: 'CoInitializeSecurity(...)' + metadata: + category: security + cwe: 'CWE-648: Incorrect Use of Privileged APIs' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: HIGH + - id: codacy.csharp.security.uri-string-parameter + severity: ERROR + languages: + - csharp + message: >- + Use System.Uri instead of a string for this URI parameter. + Strings carry no URI validation, which leads to parsing and security issues. + pattern-regex: '(?m)^[ \t]*(?:public|protected)\b[^;{=()\n]*\((?:[^()]*,)?[ \t]*(?:string|String)[ \t]+\K(?=\w*?(?:(?<=[a-z])(?:Uri|Url|Urn)|\b(?:[Uu]ri|[Uu]rl|[Uu]rn))(?![a-z]))\w+(?=[ \t]*(?:=[^,()]*)?[,)])' + metadata: + category: security + cwe: 'CWE-20: Improper Input Validation' + owasp: 'A03:2021 - Injection' + confidence: MEDIUM + - id: codacy.csharp.security.uri-string-return-value + severity: ERROR + languages: + - csharp + message: >- + Return System.Uri instead of a string from this method. + Returning URIs as strings forces callers to parse them again, which is error-prone. + pattern-regex: '(?m)^[ \t]*(?:public|protected)[ \t]+(?:(?:static|virtual|override|abstract|new|sealed)[ \t]+)*(?:string|String)[ \t]+\K(?=\w*?(?:(?<=[a-z])(?:Uri|Url|Urn)|\b(?:[Uu]ri|[Uu]rl|[Uu]rn))(?![a-z]))\w+(?=[ \t]*\()' + metadata: + category: security + cwe: 'CWE-20: Improper Input Validation' + owasp: 'A03:2021 - Injection' + confidence: MEDIUM + - id: codacy.csharp.security.uri-string-property + severity: ERROR + languages: + - csharp + message: >- + Use System.Uri instead of a string for this URI property. + Strings carry no URI validation, which leads to parsing and security issues. + pattern-regex: '(?m)^[ \t]*(?:public|protected)[ \t]+(?:(?:static|virtual|override|abstract|new|sealed)[ \t]+)*(?:string|String)[ \t]+\K(?=\w*?(?:(?<=[a-z])(?:Uri|Url|Urn)|\b(?:[Uu]ri|[Uu]rl|[Uu]rn))(?![a-z]))\w+(?=(?:\s*//[^\n]*)*\s*(?:\{|=>))' + metadata: + category: security + cwe: 'CWE-20: Improper Input Validation' + owasp: 'A03:2021 - Injection' + confidence: MEDIUM + - id: codacy.csharp.security.visible-unmanaged-pointer + severity: ERROR + languages: + - csharp + message: >- + Make this pointer field private or readonly. + Visible pointers to unmanaged memory let other code read or corrupt that memory. + pattern-regex: '(?m)^[ \t]*(?:public|protected)[ \t]+(?![^\n]*\breadonly\b)(?:(?:static|internal|unsafe|volatile|new)[ \t]+)*(?:System\.)?(?:IntPtr|UIntPtr|nint|nuint|\w+\*+)[ \t]+\K\w+(?=[ \t]*[=;])' + metadata: + category: security + cwe: 'CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer' + owasp: 'A04:2021 - Insecure Design' + confidence: HIGH + - id: codacy.csharp.security.os-command-from-path + severity: ERROR + languages: + - csharp + message: >- + Use the full path of this executable instead of relying on the PATH environment variable. + An attacker who controls a directory in the PATH can make the application run a malicious program. + patterns: + - pattern-either: + - pattern: Process.Start("$X", ...) + - pattern: $P.StartInfo.FileName = "$X" + - pattern: $P.FileName = "$X" + - pattern: new ProcessStartInfo("$X", ...) + - pattern: 'new ProcessStartInfo { ..., FileName = "$X", ... }' + - metavariable-regex: + metavariable: $X + regex: '^(?![A-Za-z]:[\\/]|[\\/]|\.{1,2}[\\/]|%).+' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-426: Untrusted Search Path' + owasp: 'A03:2021 - Injection' + confidence: MEDIUM + - id: codacy.csharp.security.native-method-not-wrapped + severity: ERROR + languages: + - csharp + message: >- + Make this native method private and expose it through a wrapper that validates its input. + Visible native methods let callers pass unchecked data directly to unmanaged code. + pattern-regex: '(?m)^[ \t]*(?=[^\n]*\bextern\b)(?=[^\n(]*\b(?:public|protected|internal)\b)[^\n(]*?[ \t]\K\w+(?=[ \t]*\()' + metadata: + category: security + cwe: 'CWE-20: Improper Input Validation' + owasp: 'A03:2021 - Injection' + confidence: HIGH + - id: codacy.csharp.security.conflicting-transparency-annotations + severity: ERROR + languages: + - csharp + message: >- + Remove this transparency attribute, it conflicts with the one applied to the containing type. + Conflicting SecurityCritical and SecuritySafeCritical annotations make the effective security level unclear. + pattern-either: + - pattern-regex: '\[[ \t]*SecuritySafeCritical\b[^\]]*\][^{]*?\bclass\b[^{]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\[[ \t]*\KSecurityCritical\b' + - pattern-regex: '\[[ \t]*SecurityCritical\b[^\]]*\][^{]*?\bclass\b[^{]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\[[ \t]*\KSecuritySafeCritical\b' + metadata: + category: security + cwe: 'CWE-749: Exposed Dangerous Method or Function' + owasp: 'A04:2021 - Insecure Design' + confidence: HIGH + - id: codacy.csharp.security.visible-pinvoke-method + severity: ERROR + languages: + - csharp + message: >- + Make this P/Invoke method private or internal. + Public or protected P/Invoke methods expose unmanaged functionality to any caller. + pattern-regex: '\[[ \t]*(?:DllImport|LibraryImport)\b[^\]]*\]\s*(?:\[[^\]]*\]\s*)*(?=[^;{\n]*\b(?:public|protected)\b)[^;{\n(]*?[ \t]\K\w+(?=[ \t]*\()' + metadata: + category: security + cwe: 'CWE-749: Exposed Dangerous Method or Function' + owasp: 'A04:2021 - Insecure Design' + confidence: HIGH + - id: codacy.csharp.security.predictable-secure-random-seed + severity: ERROR + languages: + - csharp + message: >- + Seed this secure random number generator automatically instead of with a predictable value. + A fixed seed makes the generated values predictable, defeating their purpose. + pattern-either: + - pattern: SecureRandom.GetInstance($A, false) + - pattern: $G.SetSeed("$S") + - pattern: $G.AddSeedMaterial(Encoding.$E.GetBytes("$S")) + - patterns: + - pattern-either: + - pattern: $G.SetSeed($N) + - pattern: $G.AddSeedMaterial($N) + - metavariable-regex: + metavariable: $N + regex: '^-?\d+[lL]?$' + metadata: + category: security + cwe: 'CWE-330: Use of Insufficiently Random Values' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: MEDIUM + - id: codacy.csharp.security.weak-ssl-tls-protocol + severity: ERROR + languages: + - csharp + message: >- + Use TLS 1.2 or later instead of this weak protocol version. + SSL and TLS 1.0 and 1.1 have known vulnerabilities that allow encrypted traffic to be compromised. + patterns: + - pattern-either: + - pattern: SecurityProtocolType.$P + - pattern: SslProtocols.$P + - pattern: System.Net.SecurityProtocolType.$P + - pattern: System.Security.Authentication.SslProtocols.$P + - metavariable-regex: + metavariable: $P + regex: '^(?:Ssl2|Ssl3|Tls|Tls11|Default)$' + metadata: + category: security + cwe: 'CWE-326: Inadequate Encryption Strength' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.weak-cryptographic-key + severity: ERROR + languages: + - csharp + message: >- + Use a key of at least 2048 bits for RSA, or a named curve of at least 224 bits. + Short keys can be broken with modern computing power. + pattern-either: + - pattern: new RSACryptoServiceProvider() + - pattern: new DSACryptoServiceProvider(...) + - patterns: + - pattern-either: + - pattern: new RSACryptoServiceProvider($N, ...) + - pattern: RSA.Create($N) + - pattern: new RSACng($N) + - pattern: new RsaKeyGenerationParameters($E, $R, $N, $C) + - metavariable-regex: + metavariable: $N + regex: '^\d+$' + - metavariable-comparison: + comparison: int($N) < 2048 + - patterns: + - pattern: ECCurve.NamedCurves.$C + - metavariable-regex: + metavariable: $C + regex: '^(?:brainpoolP(?:160|192)|secp(?:112|128|160|192)|sect(?:113|131|163|193)|c2[pt]nb1[6-9]\d|prime192)\w*$' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-326: Inadequate Encryption Strength' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.unauthenticated-ldap-connection + severity: ERROR + languages: + - csharp + message: >- + Use an authenticated LDAP connection. + Anonymous or unauthenticated binds let anyone query the directory. + pattern-either: + - pattern: '$D.AuthenticationType = AuthenticationTypes.None' + - pattern: '$D.AuthenticationType = AuthenticationTypes.Anonymous' + - pattern: 'new DirectoryEntry($A, $B, $C, AuthenticationTypes.None)' + - pattern: 'new DirectoryEntry($A, $B, $C, AuthenticationTypes.Anonymous)' + metadata: + category: security + cwe: 'CWE-521: Weak Password Requirements' + owasp: 'A07:2021 - Identification and Authentication Failures' + confidence: HIGH + - id: codacy.csharp.security.csrf-protection-disabled + severity: ERROR + languages: + - csharp + message: >- + Make sure that disabling CSRF protection is safe here. + Without anti-forgery validation, other sites can trigger state-changing requests on behalf of authenticated users. + pattern-either: + - pattern: new IgnoreAntiforgeryTokenAttribute(...) + - pattern: $X.DisableAntiforgery() + - pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\KIgnoreAntiforgeryToken(?:Attribute)?\b' + metadata: + category: security + cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' + owasp: 'A01:2021 - Broken Access Control' + confidence: MEDIUM + - id: codacy.csharp.security.debug-feature-enabled + severity: ERROR + languages: + - csharp + message: >- + Make sure this debug feature is only enabled in development environments. + Developer exception pages reveal stack traces and configuration details to attackers. + patterns: + - pattern-either: + - pattern: $A.UseDeveloperExceptionPage(...) + - pattern: $A.UseDatabaseErrorPage(...) + - pattern: $A.UseMigrationsEndPoint(...) + - pattern-not-inside: if (<... $E.IsDevelopment() ...>) $S; + - pattern-not-inside: if (<... $E.IsDevelopment() ...>) $S; else $T; + - pattern-not-inside: if (<... $E.IsEnvironment("Development") ...>) $S; + metadata: + category: security + cwe: 'CWE-489: Active Debug Code' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: MEDIUM + - id: codacy.csharp.security.weak-hashing-algorithm + severity: ERROR + languages: + - csharp + message: >- + Use a strong hashing algorithm such as SHA-256 instead of this weak one. + MD5 and SHA-1 are vulnerable to collision attacks. + pattern-either: + - pattern: MD5.Create(...) + - pattern: SHA1.Create(...) + - pattern: MD5.HashData(...) + - pattern: SHA1.HashData(...) + - pattern: new MD5CryptoServiceProvider() + - pattern: new SHA1CryptoServiceProvider() + - pattern: new SHA1Managed() + - pattern: new HMACMD5(...) + - pattern: new HMACSHA1(...) + - pattern: new MD5Cng() + - pattern: new SHA1Cng() + - pattern: new MD2Digest() + - pattern: new MD4Digest() + - pattern: new MD5Digest() + - pattern: new Sha1Digest() + - patterns: + - pattern-either: + - pattern: HashAlgorithm.Create("$A") + - pattern: CryptoConfig.CreateFromName("$A") + - pattern: HMAC.Create("$A") + - metavariable-regex: + metavariable: $A + regex: '(?i)^(?:System\.Security\.Cryptography\.)?(?:MD5|SHA1|SHA|MD5CryptoServiceProvider|SHA1CryptoServiceProvider|HMACMD5|HMACSHA1)$' + metadata: + category: security + cwe: 'CWE-328: Use of Weak Hash' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.logger-configuration + severity: ERROR + languages: + - csharp + message: >- + Make sure that this logger configuration is safe. + Logging configuration decides what is logged and where, which can expose sensitive data or hide attacks. + pattern-either: + - pattern: '$H.ConfigureLogging(...)' + - pattern: '$S.AddLogging(...)' + - pattern: '$L.AddAzureWebAppDiagnostics(...)' + - pattern: '$L.AddConsole(...)' + - pattern: '$L.AddDebug(...)' + - pattern: '$L.AddEventLog(...)' + - pattern: '$L.AddEventSourceLogger(...)' + - pattern: '$L.AddTraceSource(...)' + - pattern: 'XmlConfigurator.Configure(...)' + - pattern: 'XmlConfigurator.ConfigureAndWatch(...)' + - pattern: 'BasicConfigurator.Configure(...)' + - pattern: 'DOMConfigurator.Configure(...)' + - pattern: 'LogManager.Configuration = $C' + - pattern: 'new LoggerConfiguration()' + metadata: + category: security + cwe: 'CWE-117: Improper Output Neutralization for Logs' + owasp: 'A09:2021 - Security Logging and Monitoring Failures' + confidence: LOW + - id: codacy.csharp.security.server-certificate-validation-disabled + severity: ERROR + languages: + - csharp + message: >- + Validate the server certificate instead of accepting all certificates. + Accepting any certificate allows man-in-the-middle attacks on encrypted connections. + pattern-either: + - patterns: + - pattern-either: + - pattern: $X.$CB = ($A, $B, $C, $D) => true + - pattern: $X.$CB += ($A, $B, $C, $D) => true + - pattern: '$X.$CB = ($A, $B, $C, $D) => { return true; }' + - pattern: '$X.$CB += ($A, $B, $C, $D) => { return true; }' + - pattern: '$X.$CB = delegate { return true; }' + - pattern: '$X.$CB += delegate { return true; }' + - pattern: '$X.$CB += delegate (...) { return true; }' + - pattern: 'new $H { ..., $CB = ($A, $B, $C, $D) => true, ... }' + - metavariable-regex: + metavariable: $CB + regex: '.*(?:CertificateValidationCallback|CertificateCustomValidationCallback)$' + - pattern: HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + metadata: + category: security + cwe: 'CWE-295: Improper Certificate Validation' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.unrestricted-archive-extraction + severity: ERROR + languages: + - csharp + message: >- + Make sure that expanding this archive is safe, by limiting its size, entry count and compression ratio. + Archive bombs can exhaust disk space and memory when extracted without limits. + pattern-either: + - pattern: '$E.ExtractToFile(...)' + - pattern: 'ZipFile.ExtractToDirectory(...)' + - pattern: '$A.ExtractToDirectory(...)' + metadata: + category: security + cwe: 'CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)' + owasp: 'A04:2021 - Insecure Design' + confidence: LOW + - id: codacy.csharp.security.permissive-cors-policy + severity: ERROR + languages: + - csharp + message: >- + Make sure that allowing requests from any origin is safe here. + A permissive CORS policy lets any website read responses on behalf of the user. + pattern-either: + - pattern: $H.Add("Access-Control-Allow-Origin", "*") + - pattern: $H.Add(HeaderNames.AccessControlAllowOrigin, "*") + - pattern: $H.Append("Access-Control-Allow-Origin", "*") + - pattern: $H.AppendHeader("Access-Control-Allow-Origin", "*") + - pattern: $H.AppendHeader(HeaderNames.AccessControlAllowOrigin, "*") + - pattern: $H["Access-Control-Allow-Origin"] = "*" + - pattern: $B.WithOrigins("*") + - pattern: $B.AllowAnyOrigin() + - pattern: new EnableCorsAttribute("*", ...) + - pattern-regex: '\[[ \t]*EnableCors[ \t]*\([^\]]*\borigins[ \t]*:[ \t]*"\*"' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' + owasp: 'A05:2021 - Security Misconfiguration' + confidence: MEDIUM + - id: codacy.csharp.security.clear-text-protocol + severity: ERROR + languages: + - csharp + message: >- + Use a secure protocol such as HTTPS, SFTP or SSH instead of this clear-text protocol. + Clear-text protocols send data without encryption, so it can be read or modified in transit. + pattern-either: + - patterns: + - pattern: '"$S"' + - metavariable-regex: + metavariable: $S + regex: '(?i)^(?:http|ftp|telnet)://(?!(?:localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0)(?:[:/]|$))(?!(?:www\.)?(?:w3\.org|schemas\.|purl\.org|xmlns\.|ns\.adobe\.com|json-schema\.org|java\.sun\.com|apache\.org/xml))\S+$' + - pattern: $C.EnableSsl = false + - pattern: 'new SmtpClient(...) { ..., EnableSsl = false, ... }' + - patterns: + - pattern: new $T(...) + - metavariable-regex: + metavariable: $T + regex: '.*Telnet.*' + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: MEDIUM + - id: codacy.csharp.security.weak-password-hashing + severity: ERROR + languages: + - csharp + message: >- + Use a sufficiently slow password hashing configuration, such as PBKDF2 with at least 100000 iterations. + Fast hashes let attackers test billions of password guesses per second. + pattern-either: + - pattern: new Rfc2898DeriveBytes($P, $S) + - patterns: + - pattern-either: + - pattern: new Rfc2898DeriveBytes($P, $S, $N, ...) + - pattern: Rfc2898DeriveBytes.Pbkdf2($P, $S, $N, ...) + - pattern: $O.IterationCount = $N + - pattern: 'new PasswordHasherOptions { ..., IterationCount = $N, ... }' + - metavariable-regex: + metavariable: $N + regex: '^\d+$' + - metavariable-comparison: + comparison: int($N) < 100000 + - patterns: + - pattern: OpenBsdBCrypt.Generate($P, $S, $N) + - metavariable-regex: + metavariable: $N + regex: '^\d+$' + - metavariable-comparison: + comparison: int($N) < 12 + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-916: Use of Password Hash With Insufficient Computational Effort' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: MEDIUM + - id: codacy.csharp.security.publicly-writable-directory + severity: ERROR + languages: + - csharp + message: >- + Make sure that using this publicly writable directory is safe here. + Other users can read, replace or create files in shared temporary directories. + pattern-either: + - patterns: + - pattern: '"$S"' + - metavariable-regex: + metavariable: $S + regex: '(?i)^(?:/(?:tmp|var/tmp|usr/tmp|dev/shm|dev/mqueue|run/lock|var/run/lock|library/caches|users/shared|private/tmp|private/var/tmp)(?:/.*)?|[a-z]:\\{1,2}windows\\{1,2}temp(?:\\.*)?|%(?:tmp|temp)%.*)$' + - pattern: Environment.GetEnvironmentVariable("TMP") + - pattern: Environment.GetEnvironmentVariable("TEMP") + - pattern: Environment.GetEnvironmentVariable("TMPDIR") + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-377: Insecure Temporary File' + owasp: 'A01:2021 - Broken Access Control' + confidence: MEDIUM + - id: codacy.csharp.security.insecure-temporary-file + severity: ERROR + languages: + - csharp + message: >- + Create temporary files securely instead of using Path.GetTempFileName(). + The predictable file name can be exploited by another process to read or tamper with the file. + pattern-either: + - pattern: 'Path.GetTempFileName()' + - pattern: 'System.IO.Path.GetTempFileName()' + metadata: + category: security + cwe: 'CWE-377: Insecure Temporary File' + owasp: 'A01:2021 - Broken Access Control' + confidence: HIGH + - id: codacy.csharp.security.insecure-cipher-mode-or-padding + severity: ERROR + languages: + - csharp + message: >- + Use a secure cipher mode such as GCM and OAEP padding for RSA. + ECB mode leaks patterns of the plaintext and PKCS#1 v1.5 padding is vulnerable to padding oracle attacks. + pattern-either: + - pattern: 'CipherMode.ECB' + - pattern: '$R.Encrypt($D, false)' + - pattern: 'RSAEncryptionPadding.Pkcs1' + - pattern: 'new Pkcs1Encoding(...)' + - pattern: 'new EcbBlockCipher(...)' + - pattern: 'new AesManaged { ..., Mode = CipherMode.ECB, ... }' + metadata: + category: security + cwe: 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.weak-cipher-algorithm + severity: ERROR + languages: + - csharp + message: >- + Use a strong cipher such as AES instead of this weak algorithm. + DES, 3DES, RC2, RC4 and Blowfish can be broken or are vulnerable to known attacks. + pattern-either: + - pattern: 'new DESCryptoServiceProvider()' + - pattern: 'DES.Create(...)' + - pattern: 'new TripleDESCryptoServiceProvider()' + - pattern: 'TripleDES.Create(...)' + - pattern: 'new RC2CryptoServiceProvider()' + - pattern: 'RC2.Create(...)' + - pattern: 'new DesEngine()' + - pattern: 'new DesEdeEngine()' + - pattern: 'new RC2Engine()' + - pattern: 'new RC4Engine()' + - pattern: 'new BlowfishEngine()' + - pattern: 'new AesFastEngine()' + - pattern: 'new TeaEngine()' + - pattern: 'new XteaEngine()' + - pattern: 'new IdeaEngine()' + - pattern: 'SymmetricAlgorithm.Create("DES")' + - pattern: 'SymmetricAlgorithm.Create("TripleDES")' + - pattern: 'SymmetricAlgorithm.Create("RC2")' + metadata: + category: security + cwe: 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.jwt-signature-not-verified + severity: ERROR + languages: + - csharp + message: >- + Verify the signature of this JSON Web Token. + Tokens that are decoded without verifying their signature can be forged by attackers. + pattern-either: + - pattern: '$D.Decode($T, $S, verify: false)' + - pattern: $D.Decode($T, $S, false) + - pattern: $B.DoNotVerifySignature() + - pattern: 'new TokenValidationParameters { ..., RequireSignedTokens = false, ... }' + - pattern: 'new TokenValidationParameters { ..., ValidateIssuerSigningKey = false, ... }' + - pattern: $P.RequireSignedTokens = false + - pattern-regex: '\bnew[ \t]+JwtBuilder[ \t]*\([ \t]*\)(?:(?!\bMustVerifySignature\b)[^;])*?\.\KDecode\b' + metadata: + category: security + cwe: 'CWE-347: Improper Verification of Cryptographic Signature' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.excessive-request-content-length + severity: ERROR + languages: + - csharp + message: >- + Make sure that allowing large or unlimited request bodies is safe here. + Very large requests can exhaust memory and disk, leading to denial of service. + pattern-either: + - pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\KDisableRequestSizeLimit(?:Attribute)?\b' + - patterns: + - pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\K(?:RequestSizeLimit[ \t]*\([ \t]*|RequestFormLimits[ \t]*\([^)]*\bMultipartBodyLengthLimit[ \t]*=[ \t]*)(?\d+)' + - metavariable-comparison: + comparison: int($SIZE) > 8388608 + metadata: + category: security + cwe: 'CWE-770: Allocation of Resources Without Limits or Throttling' + owasp: 'A04:2021 - Insecure Design' + confidence: MEDIUM + - id: codacy.csharp.security.request-validation-disabled + severity: ERROR + languages: + - csharp + message: >- + Make sure that disabling ASP.NET request validation is safe here. + Request validation helps protect against cross-site scripting attacks. + pattern-either: + - pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\KValidateInput[ \t]*\([ \t]*false[ \t]*\)' + - pattern-regex: '\[[ \t]*(?:[^\]\n]*,[ \t]*)?\KAllowHtml(?:Attribute)?\b' + - pattern: $R.Unvalidated + metadata: + category: security + cwe: 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + owasp: 'A03:2021 - Injection' + confidence: MEDIUM + - id: codacy.csharp.security.deserialization-without-validation + severity: ERROR + languages: + - csharp + message: >- + Validate the deserialized data of this type in the same way as its constructor does. + Deserialization bypasses constructors, so invariants enforced there can be violated by crafted data. + pattern-regex: '\[[ \t]*Serializable[ \t]*\][^{]*?\bclass[ \t]+\K(\w+)\b(?=[^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b\1[ \t]*\([^()]+\)\s*\{(?:[^{}]|\{[^{}]*\})*?(?:\{[^{}]*?)?\bthrow\b)(?![^{;]*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*?\b(?:OnDeserialized|IDeserializationCallback|OnDeserialization)\b)' + metadata: + category: security + cwe: 'CWE-502: Deserialization of Untrusted Data' + owasp: 'A08:2021 - Software and Data Integrity Failures' + confidence: MEDIUM + - id: codacy.csharp.security.unrestricted-deserialization + severity: ERROR + languages: + - csharp + message: >- + Restrict the types that can be deserialized by this serializer. + Unrestricted deserialization lets attackers instantiate arbitrary types and execute code. + pattern-either: + - patterns: + - pattern: $F.Deserialize(...) + - pattern-either: + - pattern-inside: | + var $F = new BinaryFormatter(...); + ... + - pattern-inside: | + BinaryFormatter $F = new BinaryFormatter(...); + ... + - pattern-not-inside: | + $F.Binder = $B; + ... + - pattern: new BinaryFormatter(...).Deserialize(...) + - pattern: new JavaScriptSerializer(new SimpleTypeResolver()) + - pattern: new NetDataContractSerializer(...) + - pattern: new SoapFormatter(...) + - pattern: new LosFormatter(...) + - pattern: new ObjectStateFormatter(...) + metadata: + category: security + cwe: 'CWE-502: Deserialization of Untrusted Data' + owasp: 'A08:2021 - Software and Data Integrity Failures' + confidence: MEDIUM + - id: codacy.csharp.security.xml-signature-checked-without-key + severity: ERROR + languages: + - csharp + message: >- + Check this XML signature against a trusted key or certificate. + Without a key, the signature is validated with whatever key the document itself provides. + pattern-either: + - pattern: '$S.CheckSignature()' + - pattern: '$S.CheckSignatureReturningKey(...)' + metadata: + category: security + cwe: 'CWE-347: Improper Verification of Cryptographic Signature' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.security.regex-without-timeout + severity: ERROR + languages: + - csharp + message: >- + Specify a timeout for this regular expression. + Without a timeout, a crafted input can make the regular expression run for a very long time (ReDoS). + pattern-either: + - pattern: new Regex($P) + - pattern: Regex.IsMatch($I, $P) + - pattern: Regex.Match($I, $P) + - pattern: Regex.Matches($I, $P) + - pattern: Regex.Replace($I, $P, $R) + - pattern: Regex.Split($I, $P) + - patterns: + - pattern-either: + - pattern: new Regex($P, $O) + - pattern: Regex.IsMatch($I, $P, $O) + - pattern: Regex.Match($I, $P, $O) + - pattern: Regex.Matches($I, $P, $O) + - pattern: Regex.Replace($I, $P, $R, $O) + - pattern: Regex.Split($I, $P, $O) + - metavariable-regex: + metavariable: $O + regex: '(?s)^(?!.*NonBacktracking).*RegexOptions\..*' + metadata: + category: security + cwe: 'CWE-1333: Inefficient Regular Expression Complexity' + owasp: 'A04:2021 - Insecure Design' + confidence: MEDIUM + - id: codacy.csharp.security.unsafe-code-block + severity: ERROR + languages: + - csharp + message: >- + Make sure that using unsafe code is safe here. + Unsafe code bypasses memory safety checks and can introduce buffer overflows and memory corruption. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^\n\"]*?\K\bunsafe\b' + metadata: + category: security + cwe: 'CWE-787: Out-of-bounds Write' + owasp: 'A04:2021 - Insecure Design' + confidence: HIGH + - id: codacy.csharp.security.hardcoded-jwt-secret + severity: ERROR + languages: + - csharp + message: >- + Do not hardcode the secret used to sign JSON Web Tokens. + Anyone who can read the secret can forge valid tokens. + pattern-either: + - pattern: new SymmetricSecurityKey(Encoding.$E.GetBytes("$S")) + - patterns: + - pattern: new SymmetricSecurityKey(Encoding.$E.GetBytes($K)) + - pattern-either: + - pattern-inside: | + class $C { ... const string $K = "$S"; ... } + - pattern-inside: | + $T $K = "$S"; + ... + - pattern-inside: | + var $K = "$S"; + ... + options: + constant_propagation: false + metadata: + category: security + cwe: 'CWE-798: Use of Hard-coded Credentials' + owasp: 'A02:2021 - Cryptographic Failures' + confidence: HIGH + - id: codacy.csharp.codestyle.redundant-double-parentheses + severity: INFO + languages: + - csharp + message: >- + Remove this redundant pair of parentheses. + Parentheses that only wrap another parenthesized expression add noise without changing the meaning. + pattern-regex: '(?m)^(?![ \t]*(?://|/?\*))[^\n"]*?(?])\K\([ \t]*\((?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))*\)[ \t]*\)' + metadata: + category: codestyle + confidence: MEDIUM diff --git a/docs/multiple-tests/codacy-rules-csharp-header/patterns.xml b/docs/multiple-tests/codacy-rules-csharp-header/patterns.xml new file mode 100644 index 0000000..c6f03d4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp-header/patterns.xml @@ -0,0 +1,4 @@ + + + + diff --git a/docs/multiple-tests/codacy-rules-csharp-header/results.xml b/docs/multiple-tests/codacy-rules-csharp-header/results.xml new file mode 100644 index 0000000..ba95804 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp-header/results.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/multiple-tests/codacy-rules-csharp-header/src/missing-copyright-header.cs b/docs/multiple-tests/codacy-rules-csharp-header/src/missing-copyright-header.cs new file mode 100644 index 0000000..5e28a3d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp-header/src/missing-copyright-header.cs @@ -0,0 +1,8 @@ +using System; // Noncompliant + +namespace Tests.Practices +{ + public class NoHeader + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp-header/src/with-block-header.cs b/docs/multiple-tests/codacy-rules-csharp-header/src/with-block-header.cs new file mode 100644 index 0000000..2ad6754 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp-header/src/with-block-header.cs @@ -0,0 +1,10 @@ +/* + * Example Product + * Copyright (c) 2024 Example Corp. + */ +namespace Tests.Practices +{ + public class WithBlockHeader + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp-header/src/with-header.cs b/docs/multiple-tests/codacy-rules-csharp-header/src/with-header.cs new file mode 100644 index 0000000..fa9dc66 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp-header/src/with-header.cs @@ -0,0 +1,9 @@ +// Copyright (c) Example Corp. All rights reserved. +// Licensed under the MIT license. + +namespace Tests.Practices +{ + public class WithHeader + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/patterns.xml b/docs/multiple-tests/codacy-rules-csharp/patterns.xml new file mode 100644 index 0000000..67f5014 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/patterns.xml @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/multiple-tests/codacy-rules-csharp/results.xml b/docs/multiple-tests/codacy-rules-csharp/results.xml new file mode 100644 index 0000000..47ec6b0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/results.xml @@ -0,0 +1,2744 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/multiple-tests/codacy-rules-csharp/src/absolute-action-route-template.cs b/docs/multiple-tests/codacy-rules-csharp/src/absolute-action-route-template.cs new file mode 100644 index 0000000..27f351c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/absolute-action-route-template.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + [Route("[controller]")] + public class ReviewsController : Controller // Noncompliant + { + [HttpGet("/reviews")] + public ActionResult Index() => View(); + + [HttpGet("/reviews/{id}")] + public ActionResult Get(int id) => View(); + } + + [Route("[controller]")] + public class MixedController : Controller + { + [HttpGet("/legacy")] + public ActionResult Legacy() => View(); + + [HttpGet("{id}")] + public ActionResult Get(int id) => View(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/abstract-class-without-implementation.cs b/docs/multiple-tests/codacy-rules-csharp/src/abstract-class-without-implementation.cs new file mode 100644 index 0000000..cb2b804 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/abstract-class-without-implementation.cs @@ -0,0 +1,20 @@ +namespace Tests.Practices +{ + public abstract class Animal // Noncompliant + { + public abstract void Move(); + public abstract void Feed(); + } + + public abstract class Lamp + { + private bool switchLamp = false; + + public abstract void Glow(); + + public void FlipSwitch() + { + switchLamp = !switchLamp; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/action-route-without-controller-route.cs b/docs/multiple-tests/codacy-rules-csharp/src/action-route-without-controller-route.cs new file mode 100644 index 0000000..c3ffc2b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/action-route-without-controller-route.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + public class PersonController : Controller // Noncompliant + { + public IActionResult Index(int? id) => View(); + + [HttpGet(template: "{sortBy}/{direction}")] + public IActionResult List(string sortBy, string direction) => View(); + } + + [Route("[controller]")] + public class RoutedController : Controller + { + [HttpGet("{id}")] + public IActionResult Get(int id) => View(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/action-without-produces-response-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/action-without-produces-response-type.cs new file mode 100644 index 0000000..0306c64 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/action-without-produces-response-type.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + public class Foo { } + + [ApiController] + [Route("[controller]")] + public class FooController : ControllerBase + { + [HttpGet("foo")] + public IActionResult GetFoo() // Noncompliant + { + return Ok(new Foo()); + } + + [HttpGet("bar")] + [ProducesResponseType(typeof(Foo), StatusCodes.Status200OK)] + public IActionResult GetBar() + { + return Ok(new Foo()); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/always-same-math-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/always-same-math-comparison.cs new file mode 100644 index 0000000..9e22879 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/always-same-math-comparison.cs @@ -0,0 +1,15 @@ +namespace Tests.Bugs +{ + class Comparisons + { + void M(float f, int i, byte b, double d) + { + if (f <= double.MaxValue) { } // Noncompliant + if (f > double.MaxValue) { } // Noncompliant + if (i < long.MinValue) { } // Noncompliant + if (b < -1) { } // Noncompliant + if (d <= double.MaxValue) { } + if (f <= float.MaxValue) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/anonymous-delegate-unsubscribe.cs b/docs/multiple-tests/codacy-rules-csharp/src/anonymous-delegate-unsubscribe.cs new file mode 100644 index 0000000..4c51b15 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/anonymous-delegate-unsubscribe.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Bugs +{ + class Events + { + event EventHandler myEvent; + + void DoWork() + { + myEvent += (s, e) => Console.WriteLine($"Event raised with sender {s}"); + myEvent -= (s, e) => Console.WriteLine($"Event raised with sender {s}"); // Noncompliant + myEvent += Handler; + myEvent -= Handler; + myEvent -= delegate (object s, EventArgs e) { }; // Noncompliant + } + + void Handler(object s, EventArgs e) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/any-with-equality-instead-of-contains.cs b/docs/multiple-tests/codacy-rules-csharp/src/any-with-equality-instead-of-contains.cs new file mode 100644 index 0000000..79a45bc --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/any-with-equality-instead-of-contains.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Contains + { + bool ValueExists(HashSet data) => + data.Any(x => x == 42); // Noncompliant + + bool ValueExists(List data, int value) => + data.Any(x => value == x); // Noncompliant + + bool Other(List data) => + data.Any(x => x == x * 2); + + bool Fine(List data) => + data.Contains(42); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/api-action-without-http-verb.cs b/docs/multiple-tests/codacy-rules-csharp/src/api-action-without-http-verb.cs new file mode 100644 index 0000000..455c10d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/api-action-without-http-verb.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + [ApiController] + [Route("api/[controller]")] + public class CustomerController : ControllerBase + { + [Route("Customer")] + public IActionResult ChangeCustomer(int id) // Noncompliant + { + return Ok(); + } + + [HttpGet("{id}")] + public IActionResult Get(int id) + { + return Ok(); + } + + [NonAction] + public IActionResult Helper() + { + return Ok(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/api-controller-derives-from-controller.cs b/docs/multiple-tests/codacy-rules-csharp/src/api-controller-derives-from-controller.cs new file mode 100644 index 0000000..85092c7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/api-controller-derives-from-controller.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + [ApiController] + public class MyController : Controller // Noncompliant + { + [HttpGet] + public IActionResult Get() => Ok(); + } + + [ApiController] + public class ViewController : Controller + { + [HttpGet] + public IActionResult Get() => View(); + } + + [ApiController] + public class GoodController : ControllerBase + { + [HttpGet] + public IActionResult Get() => Ok(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/argument-exception-parameter-name.cs b/docs/multiple-tests/codacy-rules-csharp/src/argument-exception-parameter-name.cs new file mode 100644 index 0000000..c7ec236 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/argument-exception-parameter-name.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Bugs +{ + class Args + { + public void Foo(Bar a, int[] b) // Noncompliant + { + throw new ArgumentNullException("c"); + } + + public void Baz(Bar a) + { + throw new ArgumentException(); // Noncompliant + } + + public void Good(Bar a, int[] b) + { + throw new ArgumentNullException("b"); + } + + public void Good2(Bar a) + { + throw new ArgumentNullException(nameof(a)); + } + } + + class Bar { } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/array-created-for-params.cs b/docs/multiple-tests/codacy-rules-csharp/src/array-created-for-params.cs new file mode 100644 index 0000000..8828e72 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/array-created-for-params.cs @@ -0,0 +1,15 @@ +namespace Tests.Style +{ + class Params + { + void Method(params string[] values) + { + } + + void Caller() + { + Method(new string[] { "s1", "s2" }); // Noncompliant + Method("s1", "s2"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/assembly-com-visibility-not-explicit.cs b/docs/multiple-tests/codacy-rules-csharp/src/assembly-com-visibility-not-explicit.cs new file mode 100644 index 0000000..0558476 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/assembly-com-visibility-not-explicit.cs @@ -0,0 +1,10 @@ +using System; +using System.Reflection; + +[assembly: AssemblyProduct("Library")] // Noncompliant +[assembly: CLSCompliant(true)] + +namespace MyLibrary +{ + public class Holder2 { } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/assembly-load-from-path.cs b/docs/multiple-tests/codacy-rules-csharp/src/assembly-load-from-path.cs new file mode 100644 index 0000000..bf22688 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/assembly-load-from-path.cs @@ -0,0 +1,15 @@ +using System.Reflection; + +namespace Tests.Bugs +{ + class Loader + { + static void Main(string[] args) + { + Assembly.LoadFrom("somepath.dll"); // Noncompliant + Assembly.LoadFile("somepath.dll"); // Noncompliant + Assembly.LoadWithPartialName("Something"); // Noncompliant + Assembly.Load("Something, Version=1.0.0.0"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/assembly-not-marked-cls-compliant.cs b/docs/multiple-tests/codacy-rules-csharp/src/assembly-not-marked-cls-compliant.cs new file mode 100644 index 0000000..f6fb6e0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/assembly-not-marked-cls-compliant.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +[assembly: AssemblyTitle("Library")] // Noncompliant +[assembly: AssemblyVersion("1.0.0.0")] + +namespace MyLibrary +{ + public class Holder { } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/assertion-arguments-order.cs b/docs/multiple-tests/codacy-rules-csharp/src/assertion-arguments-order.cs new file mode 100644 index 0000000..c582660 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/assertion-arguments-order.cs @@ -0,0 +1,23 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Bugs +{ + [TestClass] + public class Asserts + { + [TestMethod] + public void Exit() + { + var runner = new Runner(); + Assert.AreEqual(runner.ExitCode, 0, "Unexpected exit code"); // Noncompliant + Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code"); + Assert.AreEqual(runner.Name, "main"); // Noncompliant + } + } + + public class Runner + { + public int ExitCode { get; set; } + public string Name { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/assignment-in-sub-expression.cs b/docs/multiple-tests/codacy-rules-csharp/src/assignment-in-sub-expression.cs new file mode 100644 index 0000000..103e894 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/assignment-in-sub-expression.cs @@ -0,0 +1,34 @@ +using System; + +namespace Tests.Style +{ + public class Assignments + { + private object instance; + public object Instance => instance ?? (instance = new object()); + + string M(string str, int index, int length, Func f) + { + string result; + int a, b, c; + if (string.IsNullOrEmpty(result = str.Substring(index, length))) // Noncompliant + { + Use(a = 1); // Noncompliant + } + while ((index = Next()) > 0) + { + index--; + } + if ((c = Next()) != 0) + { + c++; + } + a = b = c = 10; + var d = Use(() => { int x = 1; x = 2; return x; }); + return result = str; // Noncompliant + } + + int Next() { return 0; } + int Use(object o) { return 0; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/async-argument-validation.cs b/docs/multiple-tests/codacy-rules-csharp/src/async-argument-validation.cs new file mode 100644 index 0000000..dba2b5a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/async-argument-validation.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + static class AsyncValidation + { + public static async Task SkipLinesAsync(this TextReader reader, int linesToSkip) + { + if (reader == null) { throw new ArgumentNullException(nameof(reader)); } // Noncompliant + for (var i = 0; i < linesToSkip; ++i) + { + await reader.ReadLineAsync(); + } + } + + public static Task SkipLines(this TextReader reader, int linesToSkip) + { + if (reader == null) { throw new ArgumentNullException(nameof(reader)); } + return reader.ReadLineAsync(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/async-await-as-identifier.cs b/docs/multiple-tests/codacy-rules-csharp/src/async-await-as-identifier.cs new file mode 100644 index 0000000..71df51c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/async-await-as-identifier.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; + +namespace Tests.Practices +{ + public class Keywords + { + public async Task M() + { + int await = 42; // Noncompliant + int async = 42; // Noncompliant + await Task.Delay(await); + var result = await Compute(); + } + + void N(string await) // Noncompliant + { + } + + async Task Compute() { return await Task.FromResult(1); } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/async-method-naming.cs b/docs/multiple-tests/codacy-rules-csharp/src/async-method-naming.cs new file mode 100644 index 0000000..37f97f3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/async-method-naming.cs @@ -0,0 +1,37 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Tests.Naming +{ + public class Reader : BaseReader + { + public Task Read(byte[] buffer, int offset, int count, CancellationToken cancellationToken) // Noncompliant + { + return Task.CompletedTask; + } + + public Task ReadAsync(byte[] buffer) + { + return Task.CompletedTask; + } + + public async Task Compute() // Noncompliant + { + return await Task.FromResult(1); + } + + public void SaveAsync() // Noncompliant + { + } + + public override Task Flush() + { + return Task.CompletedTask; + } + + public static async Task Main(string[] args) + { + await Task.Delay(1); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/async-void-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/async-void-method.cs new file mode 100644 index 0000000..6c3ac92 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/async-void-method.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + class Async + { + private async void ThrowExceptionAsync() // Noncompliant + { + await Task.Delay(1); + throw new InvalidOperationException(); + } + + public async void button1_Click(object sender, EventArgs e) + { + await Task.Delay(1); + } + + public async void OnClick(string data) + { + await Task.Delay(1); + } + + private async Task FineAsync() + { + await Task.Delay(1); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/attribute-not-sealed.cs b/docs/multiple-tests/codacy-rules-csharp/src/attribute-not-sealed.cs new file mode 100644 index 0000000..3cd268d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/attribute-not-sealed.cs @@ -0,0 +1,21 @@ +using System; + +namespace Tests.Performance +{ + [AttributeUsage(AttributeTargets.All)] + public class MyAttribute : Attribute // Noncompliant + { + public string Name { get; } + + public MyAttribute(string name) => Name = name; + } + + [AttributeUsage(AttributeTargets.All)] + public sealed class SealedAttribute : Attribute + { + } + + public abstract class BaseAttribute : Attribute + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/attribute-without-attribute-usage.cs b/docs/multiple-tests/codacy-rules-csharp/src/attribute-without-attribute-usage.cs new file mode 100644 index 0000000..6189fd3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/attribute-without-attribute-usage.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Practices +{ + public sealed class MyAttribute : Attribute // Noncompliant + { + private string text; + + public MyAttribute(string text) + { + this.text = text; + } + } + + [AttributeUsage(AttributeTargets.Class)] + public sealed class GoodAttribute : Attribute + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/azure-function-failure-not-logged.cs b/docs/multiple-tests/codacy-rules-csharp/src/azure-function-failure-not-logged.cs new file mode 100644 index 0000000..04841c3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/azure-function-failure-not-logged.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Extensions.Logging; + +namespace Tests.Azure +{ + public static class Functions + { + [FunctionName("Foo")] + public static async Task Run(HttpRequest req, ILogger log) + { + try + { + await Task.Yield(); + } + catch (InvalidOperationException ex) // Noncompliant + { + log.LogDebug("Something failed"); + } + try + { + await Task.Yield(); + } + catch (Exception ex) + { + log.LogError(ex, "Give details that will help investigations"); + } + return new OkResult(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/azure-function-without-error-handling.cs b/docs/multiple-tests/codacy-rules-csharp/src/azure-function-without-error-handling.cs new file mode 100644 index 0000000..acba2b3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/azure-function-without-error-handling.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Extensions.Logging; + +namespace Tests.Azure +{ + public static class Functions + { + [FunctionName("HttpExample")] + public static async Task Run(HttpRequest req) // Noncompliant + { + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + return new OkObjectResult(requestBody); + } + + [FunctionName("Safe")] + public static async Task Safe(HttpRequest req, ILogger log) + { + try + { + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + return new OkObjectResult(requestBody); + } + catch (Exception ex) + { + log.LogError(ex, "Failed"); + throw; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/backslash-in-route-template.cs b/docs/multiple-tests/codacy-rules-csharp/src/backslash-in-route-template.cs new file mode 100644 index 0000000..81fb824 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/backslash-in-route-template.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + [Route(@"Something\[controller]")] // Noncompliant + public class HomeController : Controller + { + [HttpGet] + public ActionResult Index() => View(); + + [HttpGet("good/{id}")] + public ActionResult Get(int id) => View(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/base-equals-reference-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/base-equals-reference-check.cs new file mode 100644 index 0000000..cb7738d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/base-equals-reference-check.cs @@ -0,0 +1,31 @@ +namespace Tests.Bugs +{ + class Base + { + private int baseField; + + public override bool Equals(object other) + { + if (base.Equals(other)) + { + return true; + } + return this.baseField == ((Base)other).baseField; + } + + public override int GetHashCode() => baseField; + } + + class Derived : Base + { + private int derivedField; + + public override bool Equals(object other) + { + bool same = base.Equals(other); // Noncompliant + return same && this.derivedField == ((Derived)other).derivedField; + } + + public override int GetHashCode() => derivedField; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/base-object-equality-call.cs b/docs/multiple-tests/codacy-rules-csharp/src/base-object-equality-call.cs new file mode 100644 index 0000000..01bd29a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/base-object-equality-call.cs @@ -0,0 +1,35 @@ +namespace Tests.Bugs +{ + class MyClass + { + private readonly int x; + public MyClass(int x) => this.x = x; + + public override bool Equals(object obj) => + base.Equals(obj); // Noncompliant + + public override int GetHashCode() => + x.GetHashCode() ^ base.GetHashCode(); // Noncompliant + } + + class Guarded + { + public override bool Equals(object obj) + { + if (base.Equals(obj)) + { + return true; + } + return false; + } + + public override int GetHashCode() => 1; + } + + class Derived : MyClass + { + public Derived() : base(1) { } + public override int GetHashCode() => base.GetHashCode(); + public override bool Equals(object obj) => obj is Derived; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/begininvoke-without-endinvoke.cs b/docs/multiple-tests/codacy-rules-csharp/src/begininvoke-without-endinvoke.cs new file mode 100644 index 0000000..c4023c4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/begininvoke-without-endinvoke.cs @@ -0,0 +1,20 @@ +namespace Tests.Bugs +{ + public delegate string AsyncMethodCaller(); + + public class Program + { + public static void Main() + { + AsyncMethodCaller caller = () => "x"; + var result = caller.BeginInvoke(null, null); // Noncompliant + } + + public static void Fine() + { + AsyncMethodCaller caller = () => "x"; + var asyncResult = caller.BeginInvoke(null, null); + var value = caller.EndInvoke(asyncResult); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/bitwise-operation-on-non-flags-enum.cs b/docs/multiple-tests/codacy-rules-csharp/src/bitwise-operation-on-non-flags-enum.cs new file mode 100644 index 0000000..49d8864 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/bitwise-operation-on-non-flags-enum.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Practices +{ + enum Permissions + { + None = 0, + Read = 1, + Write = 2, + Execute = 4 + } + + [Flags] + enum Access + { + None = 0, + Read = 1, + Write = 2 + } + + class Usage + { + void M() + { + var x = Permissions.Read | Permissions.Write; // Noncompliant + var y = Access.Read | Access.Write; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/blocking-async-call.cs b/docs/multiple-tests/codacy-rules-csharp/src/blocking-async-call.cs new file mode 100644 index 0000000..d6c1401 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/blocking-async-call.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + public static class DeadlockDemo + { + private static async Task DelayAsync() + { + await Task.Delay(1000); + return 1; + } + + public static void Test() + { + var value = DelayAsync().Result; // Noncompliant + DelayAsync().Wait(); // Noncompliant + DelayAsync().GetAwaiter().GetResult(); // Noncompliant + var other = new Operation().Result; + } + + public static async Task Fine() + { + var value = await DelayAsync(); + } + } + + public class Operation + { + public int Result { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-async-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-async-method.cs new file mode 100644 index 0000000..05dde17 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-async-method.cs @@ -0,0 +1,25 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Tests.Performance +{ + class Async + { + public async Task Examples(Stream stream, string path) + { + var array = new byte[1024]; + stream.Read(array, 0, 1024); // Noncompliant + var text = File.ReadAllText(path); // Noncompliant + Thread.Sleep(10); // Noncompliant + await stream.ReadAsync(array, 0, 1024); + var good = await File.ReadAllTextAsync(path); + } + + public void Sync(Stream stream) + { + var array = new byte[1024]; + stream.Read(array, 0, 1024); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-azure-function.cs b/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-azure-function.cs new file mode 100644 index 0000000..3590bcb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/blocking-call-in-azure-function.cs @@ -0,0 +1,18 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; + +namespace Tests.Azure +{ + public static class Functions + { + [FunctionName("HttpExample")] + public static IActionResult Run(HttpRequest req) + { + string requestBody = new StreamReader(req.Body).ReadToEndAsync().Result; // Noncompliant + return new OkObjectResult(requestBody); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/boolean-literal-in-assertion.cs b/docs/multiple-tests/codacy-rules-csharp/src/boolean-literal-in-assertion.cs new file mode 100644 index 0000000..a0879a0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/boolean-literal-in-assertion.cs @@ -0,0 +1,19 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class Asserts + { + [TestMethod] + public void M() + { + bool someResult = Compute(); + Assert.AreEqual(false, someResult); // Noncompliant + Assert.AreEqual(true, someResult); // Noncompliant + Assert.IsFalse(someResult); + } + + bool Compute() => true; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/break-outside-switch.cs b/docs/multiple-tests/codacy-rules-csharp/src/break-outside-switch.cs new file mode 100644 index 0000000..c2f8d43 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/break-outside-switch.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Style +{ + public class Loops + { + void M(int x) + { + int i = 0; + while (true) + { + if (i == 10) + { + break; // Noncompliant + } + Console.WriteLine(i); + i++; + } + switch (x) + { + case 1: + Console.WriteLine(x); + break; + default: + break; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/caller-information-parameter-not-last.cs b/docs/multiple-tests/codacy-rules-csharp/src/caller-information-parameter-not-last.cs new file mode 100644 index 0000000..4f20ab8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/caller-information-parameter-not-last.cs @@ -0,0 +1,16 @@ +using System.Runtime.CompilerServices; + +namespace Tests.Practices +{ + class Tracing + { + void TraceMessage([CallerFilePath] string filePath = "", // Noncompliant + string message = null) + { + } + + void Fine(string message, [CallerFilePath] string filePath = "", [CallerLineNumber] int line = 0) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/catch-general-exception.cs b/docs/multiple-tests/codacy-rules-csharp/src/catch-general-exception.cs new file mode 100644 index 0000000..84380a9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/catch-general-exception.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace Tests.Bugs +{ + class Catches + { + void M() + { + try + { + File.ReadAllText("a"); + } + catch (Exception e) // Noncompliant + { + Console.WriteLine(e.Message); + } + + try + { + File.ReadAllText("a"); + } + catch (IOException e) + { + Console.WriteLine(e.Message); + } + + try + { + File.ReadAllText("a"); + } + catch (Exception e) when (e is IOException) + { + Console.WriteLine(e.Message); + } + + try + { + File.ReadAllText("a"); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + throw; + } + + try + { + File.ReadAllText("a"); + } + catch // Noncompliant + { + Console.WriteLine("failed"); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/catch-null-reference-exception.cs b/docs/multiple-tests/codacy-rules-csharp/src/catch-null-reference-exception.cs new file mode 100644 index 0000000..adf23ae --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/catch-null-reference-exception.cs @@ -0,0 +1,35 @@ +using System; + +namespace Tests.Bugs +{ + class Catches + { + public int GetLengthPlusTwo(string str) + { + try + { + return str.Length + 2; + } + catch (NullReferenceException e) // Noncompliant + { + return 2; + } + } + + public int Other(string str) + { + try + { + return int.Parse(str); + } + catch (System.NullReferenceException) // Noncompliant + { + return 0; + } + catch (FormatException) + { + return -1; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/catch-only-rethrows.cs b/docs/multiple-tests/codacy-rules-csharp/src/catch-only-rethrows.cs new file mode 100644 index 0000000..5334e83 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/catch-only-rethrows.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; + +namespace Tests.Practices +{ + class Rethrow + { + string M(string fileName) + { + string s = ""; + try + { + s = File.ReadAllText(fileName); + } + catch (Exception e) // Noncompliant + { + throw; + } + + try + { + s = File.ReadAllText(fileName); + } + catch (IOException) + { + throw; + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + return s; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/caught-exception-not-logged.cs b/docs/multiple-tests/codacy-rules-csharp/src/caught-exception-not-logged.cs new file mode 100644 index 0000000..2c45aef --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/caught-exception-not-logged.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using Microsoft.Extensions.Logging; + +namespace Tests.Practices +{ + class Saver + { + private readonly ILogger logger; + + public bool Save() + { + try + { + DoSave(); + return true; + } + catch (IOException ex) + { + logger.LogError("Saving failed."); // Noncompliant + return false; + } + } + + public bool SaveLogged() + { + try + { + DoSave(); + return true; + } + catch (IOException ex) + { + logger.LogError(ex, "Saving failed."); + return false; + } + } + + void DoSave() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/check-before-assign.cs b/docs/multiple-tests/codacy-rules-csharp/src/check-before-assign.cs new file mode 100644 index 0000000..a6fda66 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/check-before-assign.cs @@ -0,0 +1,21 @@ +namespace Tests.Performance +{ + class Checks + { + public int MyProperty { get; set; } + + void M(int a) + { + int x = 0; + if (x != a) // Noncompliant + { + x = a; + } + if (MyProperty != a) + { + MyProperty = a; + } + System.Console.WriteLine(x); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/class-owns-disposable-fields.cs b/docs/multiple-tests/codacy-rules-csharp/src/class-owns-disposable-fields.cs new file mode 100644 index 0000000..c699835 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/class-owns-disposable-fields.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; + +namespace Tests.Bugs +{ + public class ResourceHolder // Noncompliant + { + private FileStream fs; + + public void OpenResource(string path) + { + this.fs = new FileStream(path, FileMode.Open); + } + } + + public class DisposableHolder : IDisposable + { + private FileStream fs = new FileStream("a", FileMode.Open); + + public void Dispose() + { + fs.Dispose(); + } + } + + public class NotOwner + { + private readonly Stream stream; + + public NotOwner(Stream stream) + { + this.stream = stream; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/class-with-only-private-constructors.cs b/docs/multiple-tests/codacy-rules-csharp/src/class-with-only-private-constructors.cs new file mode 100644 index 0000000..db6d954 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/class-with-only-private-constructors.cs @@ -0,0 +1,25 @@ +namespace Tests.Bugs +{ + public class MyClass // Noncompliant + { + private MyClass() { } + public int Value { get; set; } + } + + public class Singleton + { + private Singleton() { } + public static Singleton Instance { get; } = new Singleton(); + } + + public class Factory + { + private Factory() { } + public static Factory Create() => new Factory(); + } + + public class Normal + { + public Normal() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/clear-text-protocol.cs b/docs/multiple-tests/codacy-rules-csharp/src/clear-text-protocol.cs new file mode 100644 index 0000000..a3ce826 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/clear-text-protocol.cs @@ -0,0 +1,19 @@ +using System.Net.Mail; + +namespace Tests.Security +{ + class Protocols + { + void M() + { + var urlHttp = "http://example.com"; // Noncompliant + var urlFtp = "ftp://anonymous@example.com"; // Noncompliant + var urlTelnet = "telnet://anonymous@example.com"; // Noncompliant + var local = "http://localhost:8080/api"; + var ns = "http://www.w3.org/2001/XMLSchema"; + var secure = "https://example.com"; + using var smtp = new SmtpClient("host", 25); + smtp.EnableSsl = false; // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/client-created-per-azure-function-invocation.cs b/docs/multiple-tests/codacy-rules-csharp/src/client-created-per-azure-function-invocation.cs new file mode 100644 index 0000000..e1c9814 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/client-created-per-azure-function-invocation.cs @@ -0,0 +1,22 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; + +namespace Tests.Azure +{ + public class HttpExample + { + private static readonly HttpClient shared = new HttpClient(); + + [FunctionName("HttpExample")] + public async Task Run(HttpRequest req) + { + using var client = new HttpClient(); // Noncompliant + var response = await client.GetAsync("https://example.com"); + var other = await shared.GetAsync("https://example.com"); + return new OkObjectResult(response.StatusCode); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/close-brace-at-line-start.cs b/docs/multiple-tests/codacy-rules-csharp/src/close-brace-at-line-start.cs new file mode 100644 index 0000000..320d4a8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/close-brace-at-line-start.cs @@ -0,0 +1,22 @@ +namespace Tests.Style +{ + public class Braces + { + void M(bool condition) + { + if (condition) { + DoSomething();} // Noncompliant + if (condition) { DoSomething(); } + if (condition) + { + DoSomething(); + } + var s = $"value {condition}"; + } + + public int Prop { get; set; } + + void DoSomething() { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/collection-element-overwritten.cs b/docs/multiple-tests/codacy-rules-csharp/src/collection-element-overwritten.cs new file mode 100644 index 0000000..0652ef1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/collection-element-overwritten.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Overwrite + { + void M(List list, Dictionary dictionary, int index, string key) + { + list[index] = "value 1"; + list[index] = "value 2"; // Noncompliant + + dictionary.Add(key, "value 1"); + dictionary[key] = "value 2"; // Noncompliant + + list[index] = "a"; + list[index + 1] = "b"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/collection-passed-to-own-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/collection-passed-to-own-method.cs new file mode 100644 index 0000000..192368c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/collection-passed-to-own-method.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Bugs +{ + class Collections + { + void M() + { + var list = new List(); + list.AddRange(list); // Noncompliant + var u = list.Union(list); // Noncompliant + var other = new List(); + list.AddRange(other); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/collection-property-with-public-setter.cs b/docs/multiple-tests/codacy-rules-csharp/src/collection-property-with-public-setter.cs new file mode 100644 index 0000000..9148b3f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/collection-property-with-public-setter.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Tests.Practices +{ + public class Holder + { + public List Strings { get; set; } // Noncompliant + public List ReadOnly { get; private set; } + public string[] Array { get; set; } + public IList Numbers { get; } = new List(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/com-security-call-in-managed-code.cs b/docs/multiple-tests/codacy-rules-csharp/src/com-security-call-in-managed-code.cs new file mode 100644 index 0000000..91a230e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/com-security-call-in-managed-code.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Security +{ + class Com + { + [DllImport("ole32.dll")] + static extern int CoSetProxyBlanket([MarshalAs(UnmanagedType.IUnknown)] object pProxy, uint dwAuthnSvc, uint dwAuthzSvc, IntPtr pServerPrincName, uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthInfo, uint dwCapabilities); + + void M(object proxy) + { + var hres1 = CoSetProxyBlanket(proxy, 0, 0, IntPtr.Zero, 0, 0, IntPtr.Zero, 0); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/commented-out-code.cs b/docs/multiple-tests/codacy-rules-csharp/src/commented-out-code.cs new file mode 100644 index 0000000..9b40377 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/commented-out-code.cs @@ -0,0 +1,19 @@ +namespace Tests.Style +{ + public class Comments + { + // This method computes the total amount for the given order. + int Compute(int a) + { + // int b = a * 2; // Noncompliant + // a = a + 1; // Noncompliant + // DoSomething(a); // Noncompliant + // if (a > 3) { // Noncompliant + // } // Noncompliant + // return a; // Noncompliant + // Note that the value is never negative + /// XML documentation is ignored + return a; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/concurrentdictionary-lambda-captures-key.cs b/docs/multiple-tests/codacy-rules-csharp/src/concurrentdictionary-lambda-captures-key.cs new file mode 100644 index 0000000..20e1902 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/concurrentdictionary-lambda-captures-key.cs @@ -0,0 +1,13 @@ +using System.Collections.Concurrent; + +namespace Tests.Performance +{ + class Caches + { + int UpdateValue(ConcurrentDictionary dict, int key) => + dict.GetOrAdd(key, _ => key + 42); // Noncompliant + + int Good(ConcurrentDictionary dict, int key) => + dict.GetOrAdd(key, x => x + 42); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/condition-always-false.cs b/docs/multiple-tests/codacy-rules-csharp/src/condition-always-false.cs new file mode 100644 index 0000000..e018c3f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/condition-always-false.cs @@ -0,0 +1,32 @@ +using System; + +namespace Tests.Bugs +{ + class Conditions + { + const bool debug = false; + + public void Sample(bool b) + { + bool a = false; + if (a) // Noncompliant + { + DoSomething(); + } + if (debug) + { + Console.WriteLine("debug"); + } + if (false) + { + DoSomething(); + } + if (b) + { + DoSomething(); + } + } + + void DoSomething() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/condition-always-true.cs b/docs/multiple-tests/codacy-rules-csharp/src/condition-always-true.cs new file mode 100644 index 0000000..0eccb37 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/condition-always-true.cs @@ -0,0 +1,25 @@ +namespace Tests.Bugs +{ + class Conditions + { + public void Sample(bool b, bool c) + { + var a = true; + if (a) // Noncompliant + { + DoSomething(); + } + var x = a ? 1 : 2; // Noncompliant + if (true) + { + DoSomething(); + } + if (b) + { + DoSomething(); + } + } + + void DoSomething() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/conditional-on-same-line-as-brace.cs b/docs/multiple-tests/codacy-rules-csharp/src/conditional-on-same-line-as-brace.cs new file mode 100644 index 0000000..f156842 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/conditional-on-same-line-as-brace.cs @@ -0,0 +1,27 @@ +namespace Tests.Style +{ + public class Conditions + { + void M(bool condition1, bool condition2) + { + if (condition1) + { + DoSomething(); + } if (condition2) // Noncompliant + { + DoSomething(); + } + + if (condition1) + { + DoSomething(); + } + else if (condition2) + { + DoSomething(); + } + } + + void DoSomething() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/conflicting-transparency-annotations.cs b/docs/multiple-tests/codacy-rules-csharp/src/conflicting-transparency-annotations.cs new file mode 100644 index 0000000..59c559f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/conflicting-transparency-annotations.cs @@ -0,0 +1,13 @@ +using System.Security; + +namespace MyLibrary +{ + [SecuritySafeCritical] + public class Foo + { + [SecurityCritical] // Noncompliant + public void Bar() + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/console-output-logging.cs b/docs/multiple-tests/codacy-rules-csharp/src/console-output-logging.cs new file mode 100644 index 0000000..0be31b8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/console-output-logging.cs @@ -0,0 +1,23 @@ +using System; +using System.Diagnostics; + +namespace Tests.Security +{ + public class MyClass + { + private void DoSomething() + { + Console.WriteLine("My Message"); // Noncompliant + Console.Error.WriteLine("Failure"); // Noncompliant +#if DEBUG + Console.WriteLine("Debug only"); +#endif + } + + [Conditional("DEBUG")] + private void Trace(string message) + { + Console.WriteLine(message); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/control-character-in-string.cs b/docs/multiple-tests/codacy-rules-csharp/src/control-character-in-string.cs new file mode 100644 index 0000000..04f4568 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/control-character-in-string.cs @@ -0,0 +1,12 @@ +namespace Tests.Style +{ + class Strings + { + void M() + { + string tabInside = "A B"; // Noncompliant + string escaped = "A\tB"; + string verbatim = @"A B"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-httponly-flag.cs b/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-httponly-flag.cs new file mode 100644 index 0000000..d464381 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-httponly-flag.cs @@ -0,0 +1,16 @@ +using System.Web; + +namespace Tests.Security +{ + class Cookies + { + void M() + { + HttpCookie myCookie = new HttpCookie("Sensitive cookie"); + myCookie.HttpOnly = false; // Noncompliant + + HttpCookie safe = new HttpCookie("Sensitive cookie"); + safe.HttpOnly = true; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-secure-flag.cs b/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-secure-flag.cs new file mode 100644 index 0000000..44dec48 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/cookie-without-secure-flag.cs @@ -0,0 +1,19 @@ +using System.Web; + +namespace Tests.Security +{ + class Cookies + { + void M() + { + HttpCookie myCookie = new HttpCookie("Sensitive cookie"); + myCookie.Secure = false; // Noncompliant + + HttpCookie other = new HttpCookie("Sensitive cookie"); // Noncompliant + other.Value = "x"; + + HttpCookie safe = new HttpCookie("Sensitive cookie"); + safe.Secure = true; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/count-used-to-check-emptiness.cs b/docs/multiple-tests/codacy-rules-csharp/src/count-used-to-check-emptiness.cs new file mode 100644 index 0000000..5009165 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/count-used-to-check-emptiness.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Emptiness + { + private static bool HasContent(IEnumerable strings) + { + return strings.Count() > 0; // Noncompliant + } + + private static bool IsEmpty(IEnumerable strings) + { + return strings.Count() == 0; // Noncompliant + } + + private static bool HasMany(IEnumerable strings) + { + return strings.Count() > 1 || strings.Any(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/csrf-protection-disabled.cs b/docs/multiple-tests/codacy-rules-csharp/src/csrf-protection-disabled.cs new file mode 100644 index 0000000..1b19080 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/csrf-protection-disabled.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; + +namespace Tests.Security +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddControllersWithViews(options => options.Filters.Add(new IgnoreAntiforgeryTokenAttribute())); // Noncompliant + } + } + + [IgnoreAntiforgeryToken] // Noncompliant + public class HomeController : Controller + { + [HttpPost] + [ValidateAntiForgeryToken] + public IActionResult Save() => Ok(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/culture-insensitive-string-operation.cs b/docs/multiple-tests/codacy-rules-csharp/src/culture-insensitive-string-operation.cs new file mode 100644 index 0000000..1ae3e62 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/culture-insensitive-string-operation.cs @@ -0,0 +1,18 @@ +using System; +using System.Globalization; + +namespace Tests.Bugs +{ + class Strings + { + void M(string someString, string other) + { + var lowered = someString.ToLower(); // Noncompliant + var upper = someString.ToUpperInvariant(); + var cmp = string.Compare(someString, other); // Noncompliant + var starts = someString.StartsWith("abc"); // Noncompliant + var ok = someString.StartsWith("abc", StringComparison.Ordinal); + var ok2 = someString.ToLower(CultureInfo.InvariantCulture); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/custom-cryptographic-algorithm.cs b/docs/multiple-tests/codacy-rules-csharp/src/custom-cryptographic-algorithm.cs new file mode 100644 index 0000000..bb0182e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/custom-cryptographic-algorithm.cs @@ -0,0 +1,18 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + public class CustomHash : HashAlgorithm // Noncompliant + { + private byte[] result; + + public override void Initialize() => result = null; + protected override byte[] HashFinal() => result; + protected override void HashCore(byte[] array, int ibStart, int cbSize) => result = array; + } + + public class Wrapper + { + private readonly SHA256 sha = SHA256.Create(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/dangerous-safehandle-access.cs b/docs/multiple-tests/codacy-rules-csharp/src/dangerous-safehandle-access.cs new file mode 100644 index 0000000..57b9858 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/dangerous-safehandle-access.cs @@ -0,0 +1,14 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Security +{ + class Handles + { + void M(SafeHandle handle) + { + IntPtr dangerousHandle = handle.DangerousGetHandle(); // Noncompliant + bool closed = handle.IsClosed; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/database-connection-without-password.cs b/docs/multiple-tests/codacy-rules-csharp/src/database-connection-without-password.cs new file mode 100644 index 0000000..5531702 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/database-connection-without-password.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; + +namespace Tests.Security +{ + class Context : DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer("Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password="); // Noncompliant + optionsBuilder.UseSqlServer("Server=myServerAddress;Database=myDataBase;Integrated Security=True"); + optionsBuilder.UseSqlServer("Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=" + GetPassword()); + } + + string GetPassword() => System.Environment.GetEnvironmentVariable("DB_PASSWORD"); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/datatable-without-locale.cs b/docs/multiple-tests/codacy-rules-csharp/src/datatable-without-locale.cs new file mode 100644 index 0000000..aad3d00 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/datatable-without-locale.cs @@ -0,0 +1,21 @@ +using System.Data; +using System.Globalization; + +namespace MyLibrary +{ + public class Foo + { + public DataTable CreateTable() + { + var table = new DataTable("Customers"); // Noncompliant + return table; + } + + public DataTable CreateGood() + { + var table = new DataTable("Customers"); + table.Locale = CultureInfo.InvariantCulture; + return table; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/date-parse-without-format-provider.cs b/docs/multiple-tests/codacy-rules-csharp/src/date-parse-without-format-provider.cs new file mode 100644 index 0000000..de7d307 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/date-parse-without-format-provider.cs @@ -0,0 +1,18 @@ +using System; +using System.Globalization; + +namespace Tests.Bugs +{ + class Parsing + { + void M(string dateTimeString) + { + var dateTimeObject = DateTime.Parse(dateTimeString); // Noncompliant + var exact = DateTime.ParseExact(dateTimeString, "yyyy-MM-dd", null); // Noncompliant + var span = TimeSpan.Parse(dateTimeString); // Noncompliant + var ok = DateTime.Parse(dateTimeString, CultureInfo.InvariantCulture); + var ok2 = DateTime.ParseExact(dateTimeString, "yyyy-MM-dd", CultureInfo.InvariantCulture); + var number = int.Parse(dateTimeString); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/datetime-instead-of-datetimeoffset.cs b/docs/multiple-tests/codacy-rules-csharp/src/datetime-instead-of-datetimeoffset.cs new file mode 100644 index 0000000..f4da6e5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/datetime-instead-of-datetimeoffset.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Practices +{ + class Dates + { + void M() + { + DateTime myDate = new DateTime(2008, 6, 19, 7, 0, 0, DateTimeKind.Local); // Noncompliant + var now = DateTime.Now; // Noncompliant + var offset = DateTimeOffset.Now; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/datetime-now-for-timing.cs b/docs/multiple-tests/codacy-rules-csharp/src/datetime-now-for-timing.cs new file mode 100644 index 0000000..6573406 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/datetime-now-for-timing.cs @@ -0,0 +1,21 @@ +using System; +using System.Diagnostics; + +namespace Tests.Performance +{ + class Timing + { + void M() + { + var start = DateTime.Now; + MethodToBeBenchmarked(); + Console.WriteLine($"{(DateTime.Now - start).TotalMilliseconds} ms"); // Noncompliant + + var watch = Stopwatch.StartNew(); + MethodToBeBenchmarked(); + Console.WriteLine(watch.ElapsedMilliseconds); + } + + void MethodToBeBenchmarked() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/datetime-without-kind.cs b/docs/multiple-tests/codacy-rules-csharp/src/datetime-without-kind.cs new file mode 100644 index 0000000..6853b23 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/datetime-without-kind.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Bugs +{ + class Dates + { + void CreateNewTime() + { + var birthDate = new DateTime(1994, 7, 5, 16, 23, 42); // Noncompliant + var day = new DateTime(1994, 7, 5); // Noncompliant + var utc = new DateTime(1994, 7, 5, 16, 23, 42, DateTimeKind.Utc); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/dead-store.cs b/docs/multiple-tests/codacy-rules-csharp/src/dead-store.cs new file mode 100644 index 0000000..11001eb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/dead-store.cs @@ -0,0 +1,18 @@ +namespace Tests.Performance +{ + class Stores + { + int Foo(int y) + { + int x = 100; // Noncompliant + x = 150; + x = x + 1; + int z = 0; + z = 5; + int w; + w = 7; // Noncompliant + w = 8; + return x + y + z + w; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/debug-feature-enabled.cs b/docs/multiple-tests/codacy-rules-csharp/src/debug-feature-enabled.cs new file mode 100644 index 0000000..ef9cac0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/debug-feature-enabled.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Tests.Security +{ + public class Startup + { + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app.UseDeveloperExceptionPage(); // Noncompliant + if (env.IsDevelopment()) + { + app.UseDatabaseErrorPage(); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/default-clause-position.cs b/docs/multiple-tests/codacy-rules-csharp/src/default-clause-position.cs new file mode 100644 index 0000000..514624d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/default-clause-position.cs @@ -0,0 +1,35 @@ +namespace Tests.Style +{ + public class Positions + { + void M(int param) + { + switch (param) + { + case 0: + DoSomething(); + break; + default: // Noncompliant + Error(); + break; + case 1: + DoSomethingElse(); + break; + } + + switch (param) + { + default: + Error(); + break; + case 0: + DoSomething(); + break; + } + } + + void DoSomething() { } + void DoSomethingElse() { } + void Error() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/default-parameter-value-without-optional.cs b/docs/multiple-tests/codacy-rules-csharp/src/default-parameter-value-without-optional.cs new file mode 100644 index 0000000..3a937d9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/default-parameter-value-without-optional.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Practices +{ + class Params + { + public void MyMethod([DefaultParameterValue(5)] int j) //Noncompliant + { + Console.WriteLine(j); + } + + public void Fine([Optional, DefaultParameterValue(5)] int j) + { + Console.WriteLine(j); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/default-value-on-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/default-value-on-parameter.cs new file mode 100644 index 0000000..f7b67c7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/default-value-on-parameter.cs @@ -0,0 +1,22 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace Tests.Bugs +{ + class MyClass + { + [DefaultValue(5)] + public int Size { get; set; } + + public void DoStuff([Optional][DefaultValue(4)] int i, int j = 5) // Noncompliant + { + Console.WriteLine(i); + } + + public void Fine([Optional][DefaultParameterValue(4)] int i) + { + Console.WriteLine(i); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/default-value-passed-explicitly.cs b/docs/multiple-tests/codacy-rules-csharp/src/default-value-passed-explicitly.cs new file mode 100644 index 0000000..0a4a3d1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/default-value-passed-explicitly.cs @@ -0,0 +1,16 @@ +namespace Tests.Style +{ + class Defaults + { + public void M(int x, int y = 5) + { + } + + void Caller() + { + M(1, 5); // Noncompliant + M(1, 6); + M(1); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/deprecated-code.cs b/docs/multiple-tests/codacy-rules-csharp/src/deprecated-code.cs new file mode 100644 index 0000000..2bccac5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/deprecated-code.cs @@ -0,0 +1,17 @@ +using System; + +namespace Tests.Practices +{ + public class Legacy + { + [Obsolete] // Noncompliant + void Method() + { + } + + [Obsolete("Use the new API")] // Noncompliant + void Other() + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/derived-type-name-suffix.cs b/docs/multiple-tests/codacy-rules-csharp/src/derived-type-name-suffix.cs new file mode 100644 index 0000000..856621b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/derived-type-name-suffix.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Naming +{ + class AttributeOne : Attribute // Noncompliant + { + } + + class Timeout : Exception // Noncompliant + { + } + + class ExtendedTimeout : Timeout + { + } + + class MyEventArgs : EventArgs + { + } + + class Changed : EventArgs, IDisposable // Noncompliant + { + public void Dispose() { } + } + + class TimeoutException : Exception + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/deserialization-without-validation.cs b/docs/multiple-tests/codacy-rules-csharp/src/deserialization-without-validation.cs new file mode 100644 index 0000000..3e75f53 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/deserialization-without-validation.cs @@ -0,0 +1,43 @@ +using System; +using System.Runtime.Serialization; + +namespace Tests.Security +{ + [Serializable] + public class InternalUrl // Noncompliant + { + private string url; + + public InternalUrl(string tmpUrl) + { + if (!tmpUrl.StartsWith("http://localhost/")) + { + throw new ArgumentException("Invalid url"); + } + url = tmpUrl; + } + } + + [Serializable] + public class ValidatedUrl : IDeserializationCallback + { + private string url; + + public ValidatedUrl(string tmpUrl) + { + if (!tmpUrl.StartsWith("http://localhost/")) + { + throw new ArgumentException("Invalid url"); + } + url = tmpUrl; + } + + void IDeserializationCallback.OnDeserialization(object sender) + { + if (!url.StartsWith("http://localhost/")) + { + throw new ArgumentException("Invalid url"); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/disposable-not-disposed.cs b/docs/multiple-tests/codacy-rules-csharp/src/disposable-not-disposed.cs new file mode 100644 index 0000000..514dcc6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/disposable-not-disposed.cs @@ -0,0 +1,52 @@ +using System.IO; + +namespace Tests.Bugs +{ + public class ResourceUser + { + public void Leak(string path) + { + var fs = new FileStream(path, FileMode.Open); // Noncompliant + fs.ReadByte(); + } + + public void LeakReader(string path) + { + var reader = new StreamReader(path); // Noncompliant + reader.ReadLine(); + } + + public void Disposed(string path) + { + var fs = new FileStream(path, FileMode.Open); + fs.ReadByte(); + fs.Dispose(); + } + + public void Using(string path) + { + using var fs = new FileStream(path, FileMode.Open); + fs.ReadByte(); + } + + public Stream Returned(string path) + { + var fs = new FileStream(path, FileMode.Open); + return fs; + } + + public void Wrapped(Stream s) + { + var sr = new StreamReader(s); + sr.ReadLine(); + } + + public void Passed(string path) + { + var fs = File.Create(path); + Consume(fs); + } + + void Consume(Stream s) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/disposable-without-finalizer.cs b/docs/multiple-tests/codacy-rules-csharp/src/disposable-without-finalizer.cs new file mode 100644 index 0000000..e787426 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/disposable-without-finalizer.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Bugs +{ + public class Foo : IDisposable // Noncompliant + { + private IntPtr myResource; + + public void Dispose() { } + } + + public class Bar : IDisposable + { + private IntPtr myResource; + + public void Dispose() { } + + ~Bar() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/dispose-does-not-dispose-fields.cs b/docs/multiple-tests/codacy-rules-csharp/src/dispose-does-not-dispose-fields.cs new file mode 100644 index 0000000..e50373b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/dispose-does-not-dispose-fields.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; + +namespace Tests.Bugs +{ + public class ResourceHolder : IDisposable + { + private FileStream fs; + private StreamWriter writer = new StreamWriter("log.txt"); + + public void OpenResource(string path) + { + this.fs = new FileStream(path, FileMode.Open); // Noncompliant + } + + public void Dispose() + { + writer.Dispose(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/dispose-method-without-idisposable.cs b/docs/multiple-tests/codacy-rules-csharp/src/dispose-method-without-idisposable.cs new file mode 100644 index 0000000..3916700 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/dispose-method-without-idisposable.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Practices +{ + public class GarbageDisposal + { + private int Dispose() // Noncompliant + { + return 0; + } + } + + public class Proper : IDisposable + { + public void Dispose() + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/disposed-object-returned.cs b/docs/multiple-tests/codacy-rules-csharp/src/disposed-object-returned.cs new file mode 100644 index 0000000..b19d8eb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/disposed-object-returned.cs @@ -0,0 +1,29 @@ +using System.IO; + +namespace Tests.Bugs +{ + class Disposables + { + public FileStream WriteToFile(string path, string text) + { + using (var fs = File.Create(path)) + { + var bytes = System.Text.Encoding.UTF8.GetBytes(text); + fs.Write(bytes, 0, bytes.Length); + return fs; // Noncompliant + } + } + + public FileStream Other(string path) + { + using var fs = File.Create(path); + return fs; // Noncompliant + } + + public FileStream Fine(string path) + { + var fs = File.Create(path); + return fs; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/doubled-prefix-operator.cs b/docs/multiple-tests/codacy-rules-csharp/src/doubled-prefix-operator.cs new file mode 100644 index 0000000..575f00b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/doubled-prefix-operator.cs @@ -0,0 +1,12 @@ +namespace Tests.Bugs +{ + class Prefix + { + void M(int v1, bool v2) + { + var v3 = !!v2; // Noncompliant + var v4 = ~~v1; // Noncompliant + var v5 = !v2; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/duplicate-branch.cs b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-branch.cs new file mode 100644 index 0000000..818c8d0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-branch.cs @@ -0,0 +1,36 @@ +namespace Tests.Practices +{ + class Branches + { + void M(int a) + { + if (a >= 0 && a < 10) + { + DoFirst(); + DoTheThing(); + } + else if (a >= 10 && a < 20) + { + DoTheOtherThing(); + } + else if (a >= 20 && a < 50) // Noncompliant + { + DoFirst(); + DoTheThing(); + } + + if (a == 1) + { + DoFirst(); + } + else if (a == 2) + { + DoFirst(); + } + } + + void DoFirst() { } + void DoTheThing() { } + void DoTheOtherThing() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/duplicate-cast.cs b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-cast.cs new file mode 100644 index 0000000..dbdacf1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-cast.cs @@ -0,0 +1,22 @@ +namespace Tests.Performance +{ + class Fruit { } + + class Casts + { + void M(object x) + { + if (x is Fruit) + { + var f = (Fruit)x; // Noncompliant + Use(f); + } + if (x is Fruit fruit) + { + Use(fruit); + } + } + + void Use(Fruit f) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/duplicate-condition-in-if-chain.cs b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-condition-in-if-chain.cs new file mode 100644 index 0000000..18aa019 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-condition-in-if-chain.cs @@ -0,0 +1,34 @@ +namespace Tests.Bugs +{ + class Chains + { + void M(int param) + { + if (param == 1) + { + OpenWindow(); + } + else if (param == 2) + { + CloseWindow(); + } + else if (param == 1) // Noncompliant + { + MoveWindowToTheBackground(); + } + + if (param == 1) + { + OpenWindow(); + } + else if (param == 3) + { + CloseWindow(); + } + } + + void OpenWindow() { } + void CloseWindow() { } + void MoveWindowToTheBackground() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/duplicate-log-template-placeholder.cs b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-log-template-placeholder.cs new file mode 100644 index 0000000..0f58501 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/duplicate-log-template-placeholder.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Practices +{ + class User { public int Id { get; set; } } + class Order { public int Id { get; set; } } + + class Shop + { + public void Checkout(ILogger logger, User user, Order order) + { + logger.LogDebug("User {Id} purchased order {Id}", user.Id, order.Id); // Noncompliant + logger.LogDebug("User {UserId} purchased order {OrderId}", user.Id, order.Id); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/else-if-without-else.cs b/docs/multiple-tests/codacy-rules-csharp/src/else-if-without-else.cs new file mode 100644 index 0000000..1a5ae9e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/else-if-without-else.cs @@ -0,0 +1,51 @@ +namespace Tests.Style +{ + public class Chains + { + void M(int x) + { + if (x == 0) + { + DoSomething(); + } + else if (x == 1) // Noncompliant + { + DoSomethingElse(); + } + + if (x == 0) + { + DoSomething(); + } + else if (x == 1) + { + DoSomethingElse(); + } + else if (x == 2) // Noncompliant + { + DoSomethingElse(); + } + + if (x == 0) + { + DoSomething(); + } + else if (x == 1) + { + DoSomethingElse(); + } + else + { + throw new System.InvalidOperationException(); + } + + if (x == 3) + { + DoSomething(); + } + } + + void DoSomething() { } + void DoSomethingElse() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-case-before-default.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-case-before-default.cs new file mode 100644 index 0000000..165e436 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-case-before-default.cs @@ -0,0 +1,26 @@ +namespace Tests.Style +{ + public class Cases + { + void M(char ch) + { + switch (ch) + { + case 'a': + HandleA(); + break; + case 'b': + HandleB(); + break; + case 'c': // Noncompliant + default: + HandleTheRest(); + break; + } + } + + void HandleA() { } + void HandleB() { } + void HandleTheRest() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-class.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-class.cs new file mode 100644 index 0000000..3b2ad3a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-class.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Practices +{ + public class Empty { } // Noncompliant + + public partial class Generated { } + + public class CreateUserCommand { } + + public class MyException : Exception { } + + [Serializable] + public class Marker { } + + public class NotEmpty + { + public int Value { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-collection-accessed.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-collection-accessed.cs new file mode 100644 index 0000000..eae4d9a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-collection-accessed.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Empty + { + public void Method() + { + var values = new List(); + values.Remove("bar"); // Noncompliant + if (values.Contains("foo")) { } // Noncompliant + foreach (var str in values) { } // Noncompliant + } + + public void Filled() + { + var values = new List(); + values.Add("bar"); + values.Remove("bar"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-comment.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-comment.cs new file mode 100644 index 0000000..79f45fb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-comment.cs @@ -0,0 +1,17 @@ +namespace Tests.Style +{ + public class Comments + { + void M() + { + // + int a = 1; // Noncompliant@-1 + /* */ // Noncompliant + // First line of a block + // + // Third line of a block + int b = 2; + /* not empty */ + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-default-clause.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-default-clause.cs new file mode 100644 index 0000000..ca40234 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-default-clause.cs @@ -0,0 +1,31 @@ +using System; + +namespace Tests.Style +{ + enum Fruit { Apple, Orange, Banana } + + public class Defaults + { + void PrintName(Fruit fruit) + { + switch (fruit) + { + case Fruit.Apple: + Console.WriteLine("apple"); + break; + default: + break; // Noncompliant@-1 + } + + switch (fruit) + { + case Fruit.Apple: + Console.WriteLine("apple"); + break; + default: + // nothing to do for other fruits + break; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-finalizer.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-finalizer.cs new file mode 100644 index 0000000..a314009 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-finalizer.cs @@ -0,0 +1,17 @@ +namespace Tests.Performance +{ + public class Foo + { + ~Foo() // Noncompliant + { + } + } + + public class Bar + { + ~Bar() + { + System.Console.WriteLine("finalized"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-generic-catch.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-generic-catch.cs new file mode 100644 index 0000000..1486541 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-generic-catch.cs @@ -0,0 +1,30 @@ +using System; +using System.IO; + +namespace Tests.Security +{ + class Catches + { + string M(string fileName) + { + string text = ""; + try + { + text = File.ReadAllText(fileName); + } + catch (Exception exc) // Noncompliant + { + } + + try + { + text = File.ReadAllText(fileName); + } + catch (Exception exc) + { + // the file is optional + } + return text; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-interface.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-interface.cs new file mode 100644 index 0000000..aa83e97 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-interface.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Practices +{ + public interface IFoo // Noncompliant + { + } + + public interface IAggregate : IComparable, IFormattable { } + + public interface IStringEquatable : IEquatable { } + + [Obsolete] + public interface ISorted { } + + public interface IFull + { + void Do(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-method.cs new file mode 100644 index 0000000..d021ceb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-method.cs @@ -0,0 +1,26 @@ +namespace Tests.Practices +{ + public class Methods + { + public void ShouldNotBeEmpty() { + } // Noncompliant@-1 + + public void NotImplementedYet() + { + } // Noncompliant@-2 + + public void EmptyOnPurpose() + { + // comment explaining why the method is empty + } + + public virtual void Hook() + { + } + + public void Implemented() + { + ShouldNotBeEmpty(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-namespace.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-namespace.cs new file mode 100644 index 0000000..e767045 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-namespace.cs @@ -0,0 +1,9 @@ +namespace MyEmptyNamespace // Noncompliant +{ + +} + +namespace Tests.Style +{ + class NotEmpty { } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-nested-block.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-nested-block.cs new file mode 100644 index 0000000..8b11759 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-nested-block.cs @@ -0,0 +1,30 @@ +namespace Tests.Style +{ + public class Blocks + { + void M(bool c, int n) + { + for (int i = 0; i < 42; i++) { } // Noncompliant + if (c) + { + } // Noncompliant@-2 + else + { + n++; + } + while (n > 0) + { + // waiting on purpose + n--; + } + try + { + n++; + } + catch (System.InvalidOperationException) + { + // ignored on purpose + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/empty-statement.cs b/docs/multiple-tests/codacy-rules-csharp/src/empty-statement.cs new file mode 100644 index 0000000..eb707ad --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/empty-statement.cs @@ -0,0 +1,28 @@ +namespace Tests.Style +{ + public class Empty + { + void DoSomething() + { + ; // Noncompliant + } + + void DoSomethingElse(int x) + { + System.Console.WriteLine("Hello, world!");; // Noncompliant + for (;;) + { + break; + } + for (int i = 0;; i++) + { + break; + } + while (x-- > 0) ; // Noncompliant + do + { + x++; + } while (x < 3); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enum-name-suffix.cs b/docs/multiple-tests/codacy-rules-csharp/src/enum-name-suffix.cs new file mode 100644 index 0000000..b7726fd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enum-name-suffix.cs @@ -0,0 +1,18 @@ +namespace Tests.Naming +{ + enum FooFlags // Noncompliant + { + Foo = 1, + Bar = 2 + } + + enum ColorEnum // Noncompliant + { + Red + } + + enum Color + { + Red + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enum-naming.cs b/docs/multiple-tests/codacy-rules-csharp/src/enum-naming.cs new file mode 100644 index 0000000..6ad25b7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enum-naming.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Naming +{ + public enum foo // Noncompliant + { + FooValue = 0 + } + + public enum Color + { + Red + } + + [Flags] + public enum Option // Noncompliant + { + None = 0, + Option1 = 1, + Option2 = 2 + } + + [Flags] + public enum Options + { + None = 0, + Option1 = 1 + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enum-storage-not-int32.cs b/docs/multiple-tests/codacy-rules-csharp/src/enum-storage-not-int32.cs new file mode 100644 index 0000000..1f4658e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enum-storage-not-int32.cs @@ -0,0 +1,13 @@ +namespace Tests.Performance +{ + public enum Visibility : sbyte // Noncompliant + { + Visible = 0, + Invisible = 1, + } + + public enum Normal + { + A + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enumerable-first-last-on-linkedlist.cs b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-first-last-on-linkedlist.cs new file mode 100644 index 0000000..570dbc3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-first-last-on-linkedlist.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Linked + { + int GetFirst(LinkedList data) => + data.First(); // Noncompliant + + int GetLast(LinkedList data) => + data.Last(); // Noncompliant + + int GetFirstProperty(LinkedList data) => + data.First.Value; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enumerable-method-instead-of-indexing.cs b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-method-instead-of-indexing.cs new file mode 100644 index 0000000..bcf9bc1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-method-instead-of-indexing.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Indexing + { + int GetAt(List data, int index) => data.ElementAt(index); // Noncompliant + int GetFirst(List data) => data.First(); // Noncompliant + int GetLast(int[] data) => data.Last(); // Noncompliant + int GetFirstEnumerable(IEnumerable data) => data.First(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/enumerable-min-max-on-sorted-set.cs b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-min-max-on-sorted-set.cs new file mode 100644 index 0000000..2d8dbb7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/enumerable-min-max-on-sorted-set.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Sets + { + int GetMax(SortedSet data) => + data.Max(); // Noncompliant + + int GetMin(SortedSet data) => + data.Min(); // Noncompliant + + int GetMaxProperty(SortedSet data) => + data.Max; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/equality-operator-on-reference-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/equality-operator-on-reference-type.cs new file mode 100644 index 0000000..ec40e9d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/equality-operator-on-reference-type.cs @@ -0,0 +1,24 @@ +using System; + +namespace Tests.Practices +{ + public class MyType // Noncompliant + { + public static bool operator ==(MyType x, MyType y) => ReferenceEquals(x, y); + public static bool operator !=(MyType x, MyType y) => !(x == y); + } + + public class Money : IEquatable + { + public bool Equals(Money other) => true; + public static bool operator ==(Money x, Money y) => true; + public static bool operator !=(Money x, Money y) => false; + } + + public class Vector + { + public static Vector operator +(Vector a, Vector b) => a; + public static bool operator ==(Vector x, Vector y) => true; + public static bool operator !=(Vector x, Vector y) => false; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/equals-without-gethashcode.cs b/docs/multiple-tests/codacy-rules-csharp/src/equals-without-gethashcode.cs new file mode 100644 index 0000000..f01bc95 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/equals-without-gethashcode.cs @@ -0,0 +1,26 @@ +namespace Tests.Bugs +{ + class MyClass // Noncompliant + { + public override bool Equals(object obj) + { + return base.Equals(obj); + } + } + + class Hashed // Noncompliant + { + public override int GetHashCode() => 42; + } + + class Both + { + public override bool Equals(object obj) => obj is Both; + public override int GetHashCode() => 1; + } + + struct Point // Noncompliant + { + public override bool Equals(object obj) => obj is Point; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/equals-without-iequatable.cs b/docs/multiple-tests/codacy-rules-csharp/src/equals-without-iequatable.cs new file mode 100644 index 0000000..8b9b3aa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/equals-without-iequatable.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Practices +{ + class MyClass // Noncompliant + { + public bool Equals(MyClass other) + { + return other != null; + } + } + + class Proper : IEquatable + { + public bool Equals(Proper other) + { + return other != null; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/event-handler-signature.cs b/docs/multiple-tests/codacy-rules-csharp/src/event-handler-signature.cs new file mode 100644 index 0000000..fd74eed --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/event-handler-signature.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Bugs +{ + public delegate void AlarmEventHandler(object s); + public delegate void GoodEventHandler(object sender, EventArgs e); + + public class Foo + { + public event AlarmEventHandler AlarmEvent; // Noncompliant + public event GoodEventHandler GoodEvent; + public event EventHandler Standard; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/event-never-raised.cs b/docs/multiple-tests/codacy-rules-csharp/src/event-never-raised.cs new file mode 100644 index 0000000..7b0d8c0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/event-never-raised.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Unused +{ + class UninvokedEventSample + { + private event Action Happened; // Noncompliant + public event EventHandler Raised; + + public void RegisterEventHandler(Action handler) + { + Happened += handler; + } + + public void Fire() + { + Raised?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exception-created-not-thrown.cs b/docs/multiple-tests/codacy-rules-csharp/src/exception-created-not-thrown.cs new file mode 100644 index 0000000..92729b3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exception-created-not-thrown.cs @@ -0,0 +1,23 @@ +using System; + +namespace Tests.Bugs +{ + class Exceptions + { + void M(int x) + { + if (x < 0) + { + new ArgumentException("x must be nonnegative"); // Noncompliant + } + if (x > 10) + { + throw new ArgumentException("x must be smaller than 10"); + } + var e = new InvalidOperationException(); + Log(new InvalidOperationException()); + } + + void Log(Exception e) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exception-missing-standard-constructors.cs b/docs/multiple-tests/codacy-rules-csharp/src/exception-missing-standard-constructors.cs new file mode 100644 index 0000000..938a84e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exception-missing-standard-constructors.cs @@ -0,0 +1,28 @@ +using System; + +namespace Tests.Practices +{ + public class MyException : Exception // Noncompliant + { + public MyException() + { + } + } + + public class CompleteException : Exception + { + public CompleteException() + { + } + + public CompleteException(string message) + : base(message) + { + } + + public CompleteException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exception-rethrown-explicitly.cs b/docs/multiple-tests/codacy-rules-csharp/src/exception-rethrown-explicitly.cs new file mode 100644 index 0000000..0504579 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exception-rethrown-explicitly.cs @@ -0,0 +1,34 @@ +using System; + +namespace Tests.Bugs +{ + class Rethrow + { + void M() + { + try + { + Work(); + } + catch (Exception exception) + { + Console.WriteLine(exception.Message); + throw exception; // Noncompliant + } + } + + void N() + { + try + { + Work(); + } + catch (Exception exception) + { + throw new Exception("Additional information", exception); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exception-thrown-from-unexpected-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/exception-thrown-from-unexpected-method.cs new file mode 100644 index 0000000..000fb3a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exception-thrown-from-unexpected-method.cs @@ -0,0 +1,45 @@ +using System; + +namespace Tests.Bugs +{ + class Unexpected : IDisposable + { + public string Name { get; set; } + + static Unexpected() + { + throw new InvalidOperationException(); // Noncompliant + } + + public override string ToString() + { + if (string.IsNullOrEmpty(Name)) + { + throw new ArgumentException(nameof(Name)); // Noncompliant + } + return Name; + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + + public override bool Equals(object obj) + { + return obj is Unexpected; + } + + public void Dispose() + { + throw new InvalidOperationException(); // Noncompliant + } + + private EventHandler handlers; + public event EventHandler Changed + { + add { throw new NotSupportedException(); } + remove { handlers -= value; } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/excessive-request-content-length.cs b/docs/multiple-tests/codacy-rules-csharp/src/excessive-request-content-length.cs new file mode 100644 index 0000000..4085d69 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/excessive-request-content-length.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Security +{ + public class MyController : Controller + { + [HttpPost] + [DisableRequestSizeLimit] // Noncompliant + public IActionResult PostRequest() => Ok(); + + [HttpPost] + [RequestSizeLimit(10485760)] // Noncompliant + public IActionResult PostLarge() => Ok(); + + [HttpPost] + [RequestSizeLimit(8000000)] + public IActionResult PostSmall() => Ok(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exclude-from-coverage-without-justification.cs b/docs/multiple-tests/codacy-rules-csharp/src/exclude-from-coverage-without-justification.cs new file mode 100644 index 0000000..0bb846d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exclude-from-coverage-without-justification.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Tests.Practices +{ + public struct Coordinates + { + public int X { get; } + public int Y { get; } + + [ExcludeFromCodeCoverage] // Noncompliant + public override bool Equals(object obj) => obj is Coordinates; + + [ExcludeFromCodeCoverage(Justification = "Generated equality members")] + public override int GetHashCode() => X ^ Y; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/exit-method-call.cs b/docs/multiple-tests/codacy-rules-csharp/src/exit-method-call.cs new file mode 100644 index 0000000..be6cf68 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/exit-method-call.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Bugs +{ + public class Program + { + public static void Main(string[] args) + { + if (args.Length == 0) + { + Environment.Exit(1); + } + } + + public void Stop() + { + Environment.Exit(0); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/expected-exception-attribute.cs b/docs/multiple-tests/codacy-rules-csharp/src/expected-exception-attribute.cs new file mode 100644 index 0000000..1b438c0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/expected-exception-attribute.cs @@ -0,0 +1,29 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class Tests + { + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] // Noncompliant + public void Method_NullParam() + { + var sut = new MyService(); + sut.Method(null); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void SingleLine() + { + new MyService().Method(null); + } + } + + public class MyService + { + public void Method(string s) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/export-without-implementation.cs b/docs/multiple-tests/codacy-rules-csharp/src/export-without-implementation.cs new file mode 100644 index 0000000..1ae6420 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/export-without-implementation.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.Composition; + +namespace Tests.Bugs +{ + public interface ISomeType { } + + [Export(typeof(ISomeType))] + public class SomeType // Noncompliant + { + } + + [Export(typeof(ISomeType))] + public class Implementer : ISomeType + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/extension-method-in-same-namespace.cs b/docs/multiple-tests/codacy-rules-csharp/src/extension-method-in-same-namespace.cs new file mode 100644 index 0000000..4afb71e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/extension-method-in-same-namespace.cs @@ -0,0 +1,17 @@ +namespace MyLibrary +{ + public class Foo + { + } + + public static class MyExtensions + { + public static void Bar(this Foo a) // Noncompliant + { + } + + public static void Baz(this string s) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/extension-method-on-object.cs b/docs/multiple-tests/codacy-rules-csharp/src/extension-method-on-object.cs new file mode 100644 index 0000000..360f0ed --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/extension-method-on-object.cs @@ -0,0 +1,13 @@ +namespace Tests.Practices +{ + public static class MyExtensions + { + public static void SomeExtension(this object obj) // Noncompliant + { + } + + public static void StringExtension(this string s) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/field-could-be-readonly.cs b/docs/multiple-tests/codacy-rules-csharp/src/field-could-be-readonly.cs new file mode 100644 index 0000000..6f346e3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/field-could-be-readonly.cs @@ -0,0 +1,27 @@ +namespace Tests.Practices +{ + public class Person + { + private int _birthYear; // Noncompliant + private int _age; + private string _name = "x"; // Noncompliant + private readonly int _id; + + Person(int birthYear, int id) + { + _birthYear = birthYear; + _id = id; + } + + public void Birthday() + { + _age++; + } + + private object _lazy; + public object Lazy => _lazy ?? (_lazy = new object()); + private int _neverAssigned; + + public int Compute() => _birthYear + _age + _id + _name.Length + _neverAssigned; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/field-shadows-parent-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/field-shadows-parent-field.cs new file mode 100644 index 0000000..9a0f59a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/field-shadows-parent-field.cs @@ -0,0 +1,14 @@ +namespace Tests.Practices +{ + public class Fruit + { + protected bool ripe; + protected int flesh; + } + + public class Raspberry : Fruit + { + private bool ripe; // Noncompliant + private int color; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/file-too-many-lines.cs b/docs/multiple-tests/codacy-rules-csharp/src/file-too-many-lines.cs new file mode 100644 index 0000000..f1fc7b8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/file-too-many-lines.cs @@ -0,0 +1,2006 @@ +namespace Tests.Size // Noncompliant +{ + public class Big + { + private const int Field0 = 0; + + private const int Field1 = 1; + + private const int Field2 = 2; + + private const int Field3 = 3; + + private const int Field4 = 4; + + private const int Field5 = 5; + + private const int Field6 = 6; + + private const int Field7 = 7; + + private const int Field8 = 8; + + private const int Field9 = 9; + + private const int Field10 = 10; + + private const int Field11 = 11; + + private const int Field12 = 12; + + private const int Field13 = 13; + + private const int Field14 = 14; + + private const int Field15 = 15; + + private const int Field16 = 16; + + private const int Field17 = 17; + + private const int Field18 = 18; + + private const int Field19 = 19; + + private const int Field20 = 20; + + private const int Field21 = 21; + + private const int Field22 = 22; + + private const int Field23 = 23; + + private const int Field24 = 24; + + private const int Field25 = 25; + + private const int Field26 = 26; + + private const int Field27 = 27; + + private const int Field28 = 28; + + private const int Field29 = 29; + + private const int Field30 = 30; + + private const int Field31 = 31; + + private const int Field32 = 32; + + private const int Field33 = 33; + + private const int Field34 = 34; + + private const int Field35 = 35; + + private const int Field36 = 36; + + private const int Field37 = 37; + + private const int Field38 = 38; + + private const int Field39 = 39; + + private const int Field40 = 40; + + private const int Field41 = 41; + + private const int Field42 = 42; + + private const int Field43 = 43; + + private const int Field44 = 44; + + private const int Field45 = 45; + + private const int Field46 = 46; + + private const int Field47 = 47; + + private const int Field48 = 48; + + private const int Field49 = 49; + + private const int Field50 = 50; + + private const int Field51 = 51; + + private const int Field52 = 52; + + private const int Field53 = 53; + + private const int Field54 = 54; + + private const int Field55 = 55; + + private const int Field56 = 56; + + private const int Field57 = 57; + + private const int Field58 = 58; + + private const int Field59 = 59; + + private const int Field60 = 60; + + private const int Field61 = 61; + + private const int Field62 = 62; + + private const int Field63 = 63; + + private const int Field64 = 64; + + private const int Field65 = 65; + + private const int Field66 = 66; + + private const int Field67 = 67; + + private const int Field68 = 68; + + private const int Field69 = 69; + + private const int Field70 = 70; + + private const int Field71 = 71; + + private const int Field72 = 72; + + private const int Field73 = 73; + + private const int Field74 = 74; + + private const int Field75 = 75; + + private const int Field76 = 76; + + private const int Field77 = 77; + + private const int Field78 = 78; + + private const int Field79 = 79; + + private const int Field80 = 80; + + private const int Field81 = 81; + + private const int Field82 = 82; + + private const int Field83 = 83; + + private const int Field84 = 84; + + private const int Field85 = 85; + + private const int Field86 = 86; + + private const int Field87 = 87; + + private const int Field88 = 88; + + private const int Field89 = 89; + + private const int Field90 = 90; + + private const int Field91 = 91; + + private const int Field92 = 92; + + private const int Field93 = 93; + + private const int Field94 = 94; + + private const int Field95 = 95; + + private const int Field96 = 96; + + private const int Field97 = 97; + + private const int Field98 = 98; + + private const int Field99 = 99; + + private const int Field100 = 100; + + private const int Field101 = 101; + + private const int Field102 = 102; + + private const int Field103 = 103; + + private const int Field104 = 104; + + private const int Field105 = 105; + + private const int Field106 = 106; + + private const int Field107 = 107; + + private const int Field108 = 108; + + private const int Field109 = 109; + + private const int Field110 = 110; + + private const int Field111 = 111; + + private const int Field112 = 112; + + private const int Field113 = 113; + + private const int Field114 = 114; + + private const int Field115 = 115; + + private const int Field116 = 116; + + private const int Field117 = 117; + + private const int Field118 = 118; + + private const int Field119 = 119; + + private const int Field120 = 120; + + private const int Field121 = 121; + + private const int Field122 = 122; + + private const int Field123 = 123; + + private const int Field124 = 124; + + private const int Field125 = 125; + + private const int Field126 = 126; + + private const int Field127 = 127; + + private const int Field128 = 128; + + private const int Field129 = 129; + + private const int Field130 = 130; + + private const int Field131 = 131; + + private const int Field132 = 132; + + private const int Field133 = 133; + + private const int Field134 = 134; + + private const int Field135 = 135; + + private const int Field136 = 136; + + private const int Field137 = 137; + + private const int Field138 = 138; + + private const int Field139 = 139; + + private const int Field140 = 140; + + private const int Field141 = 141; + + private const int Field142 = 142; + + private const int Field143 = 143; + + private const int Field144 = 144; + + private const int Field145 = 145; + + private const int Field146 = 146; + + private const int Field147 = 147; + + private const int Field148 = 148; + + private const int Field149 = 149; + + private const int Field150 = 150; + + private const int Field151 = 151; + + private const int Field152 = 152; + + private const int Field153 = 153; + + private const int Field154 = 154; + + private const int Field155 = 155; + + private const int Field156 = 156; + + private const int Field157 = 157; + + private const int Field158 = 158; + + private const int Field159 = 159; + + private const int Field160 = 160; + + private const int Field161 = 161; + + private const int Field162 = 162; + + private const int Field163 = 163; + + private const int Field164 = 164; + + private const int Field165 = 165; + + private const int Field166 = 166; + + private const int Field167 = 167; + + private const int Field168 = 168; + + private const int Field169 = 169; + + private const int Field170 = 170; + + private const int Field171 = 171; + + private const int Field172 = 172; + + private const int Field173 = 173; + + private const int Field174 = 174; + + private const int Field175 = 175; + + private const int Field176 = 176; + + private const int Field177 = 177; + + private const int Field178 = 178; + + private const int Field179 = 179; + + private const int Field180 = 180; + + private const int Field181 = 181; + + private const int Field182 = 182; + + private const int Field183 = 183; + + private const int Field184 = 184; + + private const int Field185 = 185; + + private const int Field186 = 186; + + private const int Field187 = 187; + + private const int Field188 = 188; + + private const int Field189 = 189; + + private const int Field190 = 190; + + private const int Field191 = 191; + + private const int Field192 = 192; + + private const int Field193 = 193; + + private const int Field194 = 194; + + private const int Field195 = 195; + + private const int Field196 = 196; + + private const int Field197 = 197; + + private const int Field198 = 198; + + private const int Field199 = 199; + + private const int Field200 = 200; + + private const int Field201 = 201; + + private const int Field202 = 202; + + private const int Field203 = 203; + + private const int Field204 = 204; + + private const int Field205 = 205; + + private const int Field206 = 206; + + private const int Field207 = 207; + + private const int Field208 = 208; + + private const int Field209 = 209; + + private const int Field210 = 210; + + private const int Field211 = 211; + + private const int Field212 = 212; + + private const int Field213 = 213; + + private const int Field214 = 214; + + private const int Field215 = 215; + + private const int Field216 = 216; + + private const int Field217 = 217; + + private const int Field218 = 218; + + private const int Field219 = 219; + + private const int Field220 = 220; + + private const int Field221 = 221; + + private const int Field222 = 222; + + private const int Field223 = 223; + + private const int Field224 = 224; + + private const int Field225 = 225; + + private const int Field226 = 226; + + private const int Field227 = 227; + + private const int Field228 = 228; + + private const int Field229 = 229; + + private const int Field230 = 230; + + private const int Field231 = 231; + + private const int Field232 = 232; + + private const int Field233 = 233; + + private const int Field234 = 234; + + private const int Field235 = 235; + + private const int Field236 = 236; + + private const int Field237 = 237; + + private const int Field238 = 238; + + private const int Field239 = 239; + + private const int Field240 = 240; + + private const int Field241 = 241; + + private const int Field242 = 242; + + private const int Field243 = 243; + + private const int Field244 = 244; + + private const int Field245 = 245; + + private const int Field246 = 246; + + private const int Field247 = 247; + + private const int Field248 = 248; + + private const int Field249 = 249; + + private const int Field250 = 250; + + private const int Field251 = 251; + + private const int Field252 = 252; + + private const int Field253 = 253; + + private const int Field254 = 254; + + private const int Field255 = 255; + + private const int Field256 = 256; + + private const int Field257 = 257; + + private const int Field258 = 258; + + private const int Field259 = 259; + + private const int Field260 = 260; + + private const int Field261 = 261; + + private const int Field262 = 262; + + private const int Field263 = 263; + + private const int Field264 = 264; + + private const int Field265 = 265; + + private const int Field266 = 266; + + private const int Field267 = 267; + + private const int Field268 = 268; + + private const int Field269 = 269; + + private const int Field270 = 270; + + private const int Field271 = 271; + + private const int Field272 = 272; + + private const int Field273 = 273; + + private const int Field274 = 274; + + private const int Field275 = 275; + + private const int Field276 = 276; + + private const int Field277 = 277; + + private const int Field278 = 278; + + private const int Field279 = 279; + + private const int Field280 = 280; + + private const int Field281 = 281; + + private const int Field282 = 282; + + private const int Field283 = 283; + + private const int Field284 = 284; + + private const int Field285 = 285; + + private const int Field286 = 286; + + private const int Field287 = 287; + + private const int Field288 = 288; + + private const int Field289 = 289; + + private const int Field290 = 290; + + private const int Field291 = 291; + + private const int Field292 = 292; + + private const int Field293 = 293; + + private const int Field294 = 294; + + private const int Field295 = 295; + + private const int Field296 = 296; + + private const int Field297 = 297; + + private const int Field298 = 298; + + private const int Field299 = 299; + + private const int Field300 = 300; + + private const int Field301 = 301; + + private const int Field302 = 302; + + private const int Field303 = 303; + + private const int Field304 = 304; + + private const int Field305 = 305; + + private const int Field306 = 306; + + private const int Field307 = 307; + + private const int Field308 = 308; + + private const int Field309 = 309; + + private const int Field310 = 310; + + private const int Field311 = 311; + + private const int Field312 = 312; + + private const int Field313 = 313; + + private const int Field314 = 314; + + private const int Field315 = 315; + + private const int Field316 = 316; + + private const int Field317 = 317; + + private const int Field318 = 318; + + private const int Field319 = 319; + + private const int Field320 = 320; + + private const int Field321 = 321; + + private const int Field322 = 322; + + private const int Field323 = 323; + + private const int Field324 = 324; + + private const int Field325 = 325; + + private const int Field326 = 326; + + private const int Field327 = 327; + + private const int Field328 = 328; + + private const int Field329 = 329; + + private const int Field330 = 330; + + private const int Field331 = 331; + + private const int Field332 = 332; + + private const int Field333 = 333; + + private const int Field334 = 334; + + private const int Field335 = 335; + + private const int Field336 = 336; + + private const int Field337 = 337; + + private const int Field338 = 338; + + private const int Field339 = 339; + + private const int Field340 = 340; + + private const int Field341 = 341; + + private const int Field342 = 342; + + private const int Field343 = 343; + + private const int Field344 = 344; + + private const int Field345 = 345; + + private const int Field346 = 346; + + private const int Field347 = 347; + + private const int Field348 = 348; + + private const int Field349 = 349; + + private const int Field350 = 350; + + private const int Field351 = 351; + + private const int Field352 = 352; + + private const int Field353 = 353; + + private const int Field354 = 354; + + private const int Field355 = 355; + + private const int Field356 = 356; + + private const int Field357 = 357; + + private const int Field358 = 358; + + private const int Field359 = 359; + + private const int Field360 = 360; + + private const int Field361 = 361; + + private const int Field362 = 362; + + private const int Field363 = 363; + + private const int Field364 = 364; + + private const int Field365 = 365; + + private const int Field366 = 366; + + private const int Field367 = 367; + + private const int Field368 = 368; + + private const int Field369 = 369; + + private const int Field370 = 370; + + private const int Field371 = 371; + + private const int Field372 = 372; + + private const int Field373 = 373; + + private const int Field374 = 374; + + private const int Field375 = 375; + + private const int Field376 = 376; + + private const int Field377 = 377; + + private const int Field378 = 378; + + private const int Field379 = 379; + + private const int Field380 = 380; + + private const int Field381 = 381; + + private const int Field382 = 382; + + private const int Field383 = 383; + + private const int Field384 = 384; + + private const int Field385 = 385; + + private const int Field386 = 386; + + private const int Field387 = 387; + + private const int Field388 = 388; + + private const int Field389 = 389; + + private const int Field390 = 390; + + private const int Field391 = 391; + + private const int Field392 = 392; + + private const int Field393 = 393; + + private const int Field394 = 394; + + private const int Field395 = 395; + + private const int Field396 = 396; + + private const int Field397 = 397; + + private const int Field398 = 398; + + private const int Field399 = 399; + + private const int Field400 = 400; + + private const int Field401 = 401; + + private const int Field402 = 402; + + private const int Field403 = 403; + + private const int Field404 = 404; + + private const int Field405 = 405; + + private const int Field406 = 406; + + private const int Field407 = 407; + + private const int Field408 = 408; + + private const int Field409 = 409; + + private const int Field410 = 410; + + private const int Field411 = 411; + + private const int Field412 = 412; + + private const int Field413 = 413; + + private const int Field414 = 414; + + private const int Field415 = 415; + + private const int Field416 = 416; + + private const int Field417 = 417; + + private const int Field418 = 418; + + private const int Field419 = 419; + + private const int Field420 = 420; + + private const int Field421 = 421; + + private const int Field422 = 422; + + private const int Field423 = 423; + + private const int Field424 = 424; + + private const int Field425 = 425; + + private const int Field426 = 426; + + private const int Field427 = 427; + + private const int Field428 = 428; + + private const int Field429 = 429; + + private const int Field430 = 430; + + private const int Field431 = 431; + + private const int Field432 = 432; + + private const int Field433 = 433; + + private const int Field434 = 434; + + private const int Field435 = 435; + + private const int Field436 = 436; + + private const int Field437 = 437; + + private const int Field438 = 438; + + private const int Field439 = 439; + + private const int Field440 = 440; + + private const int Field441 = 441; + + private const int Field442 = 442; + + private const int Field443 = 443; + + private const int Field444 = 444; + + private const int Field445 = 445; + + private const int Field446 = 446; + + private const int Field447 = 447; + + private const int Field448 = 448; + + private const int Field449 = 449; + + private const int Field450 = 450; + + private const int Field451 = 451; + + private const int Field452 = 452; + + private const int Field453 = 453; + + private const int Field454 = 454; + + private const int Field455 = 455; + + private const int Field456 = 456; + + private const int Field457 = 457; + + private const int Field458 = 458; + + private const int Field459 = 459; + + private const int Field460 = 460; + + private const int Field461 = 461; + + private const int Field462 = 462; + + private const int Field463 = 463; + + private const int Field464 = 464; + + private const int Field465 = 465; + + private const int Field466 = 466; + + private const int Field467 = 467; + + private const int Field468 = 468; + + private const int Field469 = 469; + + private const int Field470 = 470; + + private const int Field471 = 471; + + private const int Field472 = 472; + + private const int Field473 = 473; + + private const int Field474 = 474; + + private const int Field475 = 475; + + private const int Field476 = 476; + + private const int Field477 = 477; + + private const int Field478 = 478; + + private const int Field479 = 479; + + private const int Field480 = 480; + + private const int Field481 = 481; + + private const int Field482 = 482; + + private const int Field483 = 483; + + private const int Field484 = 484; + + private const int Field485 = 485; + + private const int Field486 = 486; + + private const int Field487 = 487; + + private const int Field488 = 488; + + private const int Field489 = 489; + + private const int Field490 = 490; + + private const int Field491 = 491; + + private const int Field492 = 492; + + private const int Field493 = 493; + + private const int Field494 = 494; + + private const int Field495 = 495; + + private const int Field496 = 496; + + private const int Field497 = 497; + + private const int Field498 = 498; + + private const int Field499 = 499; + + private const int Field500 = 500; + + private const int Field501 = 501; + + private const int Field502 = 502; + + private const int Field503 = 503; + + private const int Field504 = 504; + + private const int Field505 = 505; + + private const int Field506 = 506; + + private const int Field507 = 507; + + private const int Field508 = 508; + + private const int Field509 = 509; + + private const int Field510 = 510; + + private const int Field511 = 511; + + private const int Field512 = 512; + + private const int Field513 = 513; + + private const int Field514 = 514; + + private const int Field515 = 515; + + private const int Field516 = 516; + + private const int Field517 = 517; + + private const int Field518 = 518; + + private const int Field519 = 519; + + private const int Field520 = 520; + + private const int Field521 = 521; + + private const int Field522 = 522; + + private const int Field523 = 523; + + private const int Field524 = 524; + + private const int Field525 = 525; + + private const int Field526 = 526; + + private const int Field527 = 527; + + private const int Field528 = 528; + + private const int Field529 = 529; + + private const int Field530 = 530; + + private const int Field531 = 531; + + private const int Field532 = 532; + + private const int Field533 = 533; + + private const int Field534 = 534; + + private const int Field535 = 535; + + private const int Field536 = 536; + + private const int Field537 = 537; + + private const int Field538 = 538; + + private const int Field539 = 539; + + private const int Field540 = 540; + + private const int Field541 = 541; + + private const int Field542 = 542; + + private const int Field543 = 543; + + private const int Field544 = 544; + + private const int Field545 = 545; + + private const int Field546 = 546; + + private const int Field547 = 547; + + private const int Field548 = 548; + + private const int Field549 = 549; + + private const int Field550 = 550; + + private const int Field551 = 551; + + private const int Field552 = 552; + + private const int Field553 = 553; + + private const int Field554 = 554; + + private const int Field555 = 555; + + private const int Field556 = 556; + + private const int Field557 = 557; + + private const int Field558 = 558; + + private const int Field559 = 559; + + private const int Field560 = 560; + + private const int Field561 = 561; + + private const int Field562 = 562; + + private const int Field563 = 563; + + private const int Field564 = 564; + + private const int Field565 = 565; + + private const int Field566 = 566; + + private const int Field567 = 567; + + private const int Field568 = 568; + + private const int Field569 = 569; + + private const int Field570 = 570; + + private const int Field571 = 571; + + private const int Field572 = 572; + + private const int Field573 = 573; + + private const int Field574 = 574; + + private const int Field575 = 575; + + private const int Field576 = 576; + + private const int Field577 = 577; + + private const int Field578 = 578; + + private const int Field579 = 579; + + private const int Field580 = 580; + + private const int Field581 = 581; + + private const int Field582 = 582; + + private const int Field583 = 583; + + private const int Field584 = 584; + + private const int Field585 = 585; + + private const int Field586 = 586; + + private const int Field587 = 587; + + private const int Field588 = 588; + + private const int Field589 = 589; + + private const int Field590 = 590; + + private const int Field591 = 591; + + private const int Field592 = 592; + + private const int Field593 = 593; + + private const int Field594 = 594; + + private const int Field595 = 595; + + private const int Field596 = 596; + + private const int Field597 = 597; + + private const int Field598 = 598; + + private const int Field599 = 599; + + private const int Field600 = 600; + + private const int Field601 = 601; + + private const int Field602 = 602; + + private const int Field603 = 603; + + private const int Field604 = 604; + + private const int Field605 = 605; + + private const int Field606 = 606; + + private const int Field607 = 607; + + private const int Field608 = 608; + + private const int Field609 = 609; + + private const int Field610 = 610; + + private const int Field611 = 611; + + private const int Field612 = 612; + + private const int Field613 = 613; + + private const int Field614 = 614; + + private const int Field615 = 615; + + private const int Field616 = 616; + + private const int Field617 = 617; + + private const int Field618 = 618; + + private const int Field619 = 619; + + private const int Field620 = 620; + + private const int Field621 = 621; + + private const int Field622 = 622; + + private const int Field623 = 623; + + private const int Field624 = 624; + + private const int Field625 = 625; + + private const int Field626 = 626; + + private const int Field627 = 627; + + private const int Field628 = 628; + + private const int Field629 = 629; + + private const int Field630 = 630; + + private const int Field631 = 631; + + private const int Field632 = 632; + + private const int Field633 = 633; + + private const int Field634 = 634; + + private const int Field635 = 635; + + private const int Field636 = 636; + + private const int Field637 = 637; + + private const int Field638 = 638; + + private const int Field639 = 639; + + private const int Field640 = 640; + + private const int Field641 = 641; + + private const int Field642 = 642; + + private const int Field643 = 643; + + private const int Field644 = 644; + + private const int Field645 = 645; + + private const int Field646 = 646; + + private const int Field647 = 647; + + private const int Field648 = 648; + + private const int Field649 = 649; + + private const int Field650 = 650; + + private const int Field651 = 651; + + private const int Field652 = 652; + + private const int Field653 = 653; + + private const int Field654 = 654; + + private const int Field655 = 655; + + private const int Field656 = 656; + + private const int Field657 = 657; + + private const int Field658 = 658; + + private const int Field659 = 659; + + private const int Field660 = 660; + + private const int Field661 = 661; + + private const int Field662 = 662; + + private const int Field663 = 663; + + private const int Field664 = 664; + + private const int Field665 = 665; + + private const int Field666 = 666; + + private const int Field667 = 667; + + private const int Field668 = 668; + + private const int Field669 = 669; + + private const int Field670 = 670; + + private const int Field671 = 671; + + private const int Field672 = 672; + + private const int Field673 = 673; + + private const int Field674 = 674; + + private const int Field675 = 675; + + private const int Field676 = 676; + + private const int Field677 = 677; + + private const int Field678 = 678; + + private const int Field679 = 679; + + private const int Field680 = 680; + + private const int Field681 = 681; + + private const int Field682 = 682; + + private const int Field683 = 683; + + private const int Field684 = 684; + + private const int Field685 = 685; + + private const int Field686 = 686; + + private const int Field687 = 687; + + private const int Field688 = 688; + + private const int Field689 = 689; + + private const int Field690 = 690; + + private const int Field691 = 691; + + private const int Field692 = 692; + + private const int Field693 = 693; + + private const int Field694 = 694; + + private const int Field695 = 695; + + private const int Field696 = 696; + + private const int Field697 = 697; + + private const int Field698 = 698; + + private const int Field699 = 699; + + private const int Field700 = 700; + + private const int Field701 = 701; + + private const int Field702 = 702; + + private const int Field703 = 703; + + private const int Field704 = 704; + + private const int Field705 = 705; + + private const int Field706 = 706; + + private const int Field707 = 707; + + private const int Field708 = 708; + + private const int Field709 = 709; + + private const int Field710 = 710; + + private const int Field711 = 711; + + private const int Field712 = 712; + + private const int Field713 = 713; + + private const int Field714 = 714; + + private const int Field715 = 715; + + private const int Field716 = 716; + + private const int Field717 = 717; + + private const int Field718 = 718; + + private const int Field719 = 719; + + private const int Field720 = 720; + + private const int Field721 = 721; + + private const int Field722 = 722; + + private const int Field723 = 723; + + private const int Field724 = 724; + + private const int Field725 = 725; + + private const int Field726 = 726; + + private const int Field727 = 727; + + private const int Field728 = 728; + + private const int Field729 = 729; + + private const int Field730 = 730; + + private const int Field731 = 731; + + private const int Field732 = 732; + + private const int Field733 = 733; + + private const int Field734 = 734; + + private const int Field735 = 735; + + private const int Field736 = 736; + + private const int Field737 = 737; + + private const int Field738 = 738; + + private const int Field739 = 739; + + private const int Field740 = 740; + + private const int Field741 = 741; + + private const int Field742 = 742; + + private const int Field743 = 743; + + private const int Field744 = 744; + + private const int Field745 = 745; + + private const int Field746 = 746; + + private const int Field747 = 747; + + private const int Field748 = 748; + + private const int Field749 = 749; + + private const int Field750 = 750; + + private const int Field751 = 751; + + private const int Field752 = 752; + + private const int Field753 = 753; + + private const int Field754 = 754; + + private const int Field755 = 755; + + private const int Field756 = 756; + + private const int Field757 = 757; + + private const int Field758 = 758; + + private const int Field759 = 759; + + private const int Field760 = 760; + + private const int Field761 = 761; + + private const int Field762 = 762; + + private const int Field763 = 763; + + private const int Field764 = 764; + + private const int Field765 = 765; + + private const int Field766 = 766; + + private const int Field767 = 767; + + private const int Field768 = 768; + + private const int Field769 = 769; + + private const int Field770 = 770; + + private const int Field771 = 771; + + private const int Field772 = 772; + + private const int Field773 = 773; + + private const int Field774 = 774; + + private const int Field775 = 775; + + private const int Field776 = 776; + + private const int Field777 = 777; + + private const int Field778 = 778; + + private const int Field779 = 779; + + private const int Field780 = 780; + + private const int Field781 = 781; + + private const int Field782 = 782; + + private const int Field783 = 783; + + private const int Field784 = 784; + + private const int Field785 = 785; + + private const int Field786 = 786; + + private const int Field787 = 787; + + private const int Field788 = 788; + + private const int Field789 = 789; + + private const int Field790 = 790; + + private const int Field791 = 791; + + private const int Field792 = 792; + + private const int Field793 = 793; + + private const int Field794 = 794; + + private const int Field795 = 795; + + private const int Field796 = 796; + + private const int Field797 = 797; + + private const int Field798 = 798; + + private const int Field799 = 799; + + private const int Field800 = 800; + + private const int Field801 = 801; + + private const int Field802 = 802; + + private const int Field803 = 803; + + private const int Field804 = 804; + + private const int Field805 = 805; + + private const int Field806 = 806; + + private const int Field807 = 807; + + private const int Field808 = 808; + + private const int Field809 = 809; + + private const int Field810 = 810; + + private const int Field811 = 811; + + private const int Field812 = 812; + + private const int Field813 = 813; + + private const int Field814 = 814; + + private const int Field815 = 815; + + private const int Field816 = 816; + + private const int Field817 = 817; + + private const int Field818 = 818; + + private const int Field819 = 819; + + private const int Field820 = 820; + + private const int Field821 = 821; + + private const int Field822 = 822; + + private const int Field823 = 823; + + private const int Field824 = 824; + + private const int Field825 = 825; + + private const int Field826 = 826; + + private const int Field827 = 827; + + private const int Field828 = 828; + + private const int Field829 = 829; + + private const int Field830 = 830; + + private const int Field831 = 831; + + private const int Field832 = 832; + + private const int Field833 = 833; + + private const int Field834 = 834; + + private const int Field835 = 835; + + private const int Field836 = 836; + + private const int Field837 = 837; + + private const int Field838 = 838; + + private const int Field839 = 839; + + private const int Field840 = 840; + + private const int Field841 = 841; + + private const int Field842 = 842; + + private const int Field843 = 843; + + private const int Field844 = 844; + + private const int Field845 = 845; + + private const int Field846 = 846; + + private const int Field847 = 847; + + private const int Field848 = 848; + + private const int Field849 = 849; + + private const int Field850 = 850; + + private const int Field851 = 851; + + private const int Field852 = 852; + + private const int Field853 = 853; + + private const int Field854 = 854; + + private const int Field855 = 855; + + private const int Field856 = 856; + + private const int Field857 = 857; + + private const int Field858 = 858; + + private const int Field859 = 859; + + private const int Field860 = 860; + + private const int Field861 = 861; + + private const int Field862 = 862; + + private const int Field863 = 863; + + private const int Field864 = 864; + + private const int Field865 = 865; + + private const int Field866 = 866; + + private const int Field867 = 867; + + private const int Field868 = 868; + + private const int Field869 = 869; + + private const int Field870 = 870; + + private const int Field871 = 871; + + private const int Field872 = 872; + + private const int Field873 = 873; + + private const int Field874 = 874; + + private const int Field875 = 875; + + private const int Field876 = 876; + + private const int Field877 = 877; + + private const int Field878 = 878; + + private const int Field879 = 879; + + private const int Field880 = 880; + + private const int Field881 = 881; + + private const int Field882 = 882; + + private const int Field883 = 883; + + private const int Field884 = 884; + + private const int Field885 = 885; + + private const int Field886 = 886; + + private const int Field887 = 887; + + private const int Field888 = 888; + + private const int Field889 = 889; + + private const int Field890 = 890; + + private const int Field891 = 891; + + private const int Field892 = 892; + + private const int Field893 = 893; + + private const int Field894 = 894; + + private const int Field895 = 895; + + private const int Field896 = 896; + + private const int Field897 = 897; + + private const int Field898 = 898; + + private const int Field899 = 899; + + private const int Field900 = 900; + + private const int Field901 = 901; + + private const int Field902 = 902; + + private const int Field903 = 903; + + private const int Field904 = 904; + + private const int Field905 = 905; + + private const int Field906 = 906; + + private const int Field907 = 907; + + private const int Field908 = 908; + + private const int Field909 = 909; + + private const int Field910 = 910; + + private const int Field911 = 911; + + private const int Field912 = 912; + + private const int Field913 = 913; + + private const int Field914 = 914; + + private const int Field915 = 915; + + private const int Field916 = 916; + + private const int Field917 = 917; + + private const int Field918 = 918; + + private const int Field919 = 919; + + private const int Field920 = 920; + + private const int Field921 = 921; + + private const int Field922 = 922; + + private const int Field923 = 923; + + private const int Field924 = 924; + + private const int Field925 = 925; + + private const int Field926 = 926; + + private const int Field927 = 927; + + private const int Field928 = 928; + + private const int Field929 = 929; + + private const int Field930 = 930; + + private const int Field931 = 931; + + private const int Field932 = 932; + + private const int Field933 = 933; + + private const int Field934 = 934; + + private const int Field935 = 935; + + private const int Field936 = 936; + + private const int Field937 = 937; + + private const int Field938 = 938; + + private const int Field939 = 939; + + private const int Field940 = 940; + + private const int Field941 = 941; + + private const int Field942 = 942; + + private const int Field943 = 943; + + private const int Field944 = 944; + + private const int Field945 = 945; + + private const int Field946 = 946; + + private const int Field947 = 947; + + private const int Field948 = 948; + + private const int Field949 = 949; + + private const int Field950 = 950; + + private const int Field951 = 951; + + private const int Field952 = 952; + + private const int Field953 = 953; + + private const int Field954 = 954; + + private const int Field955 = 955; + + private const int Field956 = 956; + + private const int Field957 = 957; + + private const int Field958 = 958; + + private const int Field959 = 959; + + private const int Field960 = 960; + + private const int Field961 = 961; + + private const int Field962 = 962; + + private const int Field963 = 963; + + private const int Field964 = 964; + + private const int Field965 = 965; + + private const int Field966 = 966; + + private const int Field967 = 967; + + private const int Field968 = 968; + + private const int Field969 = 969; + + private const int Field970 = 970; + + private const int Field971 = 971; + + private const int Field972 = 972; + + private const int Field973 = 973; + + private const int Field974 = 974; + + private const int Field975 = 975; + + private const int Field976 = 976; + + private const int Field977 = 977; + + private const int Field978 = 978; + + private const int Field979 = 979; + + private const int Field980 = 980; + + private const int Field981 = 981; + + private const int Field982 = 982; + + private const int Field983 = 983; + + private const int Field984 = 984; + + private const int Field985 = 985; + + private const int Field986 = 986; + + private const int Field987 = 987; + + private const int Field988 = 988; + + private const int Field989 = 989; + + private const int Field990 = 990; + + private const int Field991 = 991; + + private const int Field992 = 992; + + private const int Field993 = 993; + + private const int Field994 = 994; + + private const int Field995 = 995; + + private const int Field996 = 996; + + private const int Field997 = 997; + + private const int Field998 = 998; + + private const int Field999 = 999; + + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/fixme-tag.cs b/docs/multiple-tests/codacy-rules-csharp/src/fixme-tag.cs new file mode 100644 index 0000000..ddc0e96 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/fixme-tag.cs @@ -0,0 +1,13 @@ +namespace Tests.Practices +{ + public class Fixmes + { + private int Divide(int numerator, int denominator) + { + return numerator / denominator; // FIXME denominator value might be 0 // Noncompliant + } + + /* fixme: handle overflow */ // Noncompliant + private int Prefix() { return 0; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-invalid-value.cs b/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-invalid-value.cs new file mode 100644 index 0000000..1c6a3da --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-invalid-value.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Bugs +{ + [Flags] + public enum Color + { + None = 0, + Red = 1, + Orange = 3, // Noncompliant + Yellow = 4, + Mixed = Red | Yellow + } + + public enum NotFlags + { + A = 3, + B = 5 + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-members-not-initialized.cs b/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-members-not-initialized.cs new file mode 100644 index 0000000..1617bcd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/flags-enum-members-not-initialized.cs @@ -0,0 +1,38 @@ +using System; + +namespace Tests.Bugs +{ + [Flags] + enum FruitType // Noncompliant + { + None, + Banana, + Orange, + Strawberry + } + + [Flags] + enum Small + { + None, + A, + B + } + + [Flags] + enum Explicit + { + None = 0, + A = 1, + B = 2, + C = 4 + } + + enum NotFlags + { + A, + B, + C, + D + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/flags-zero-member-not-none.cs b/docs/multiple-tests/codacy-rules-csharp/src/flags-zero-member-not-none.cs new file mode 100644 index 0000000..317966e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/flags-zero-member-not-none.cs @@ -0,0 +1,26 @@ +using System; + +namespace Tests.Practices +{ + [Flags] + enum FruitType + { + Void = 0, // Noncompliant + Banana = 1, + Orange = 2, + Strawberry = 4 + } + + [Flags] + enum Colors + { + None = 0, + Red = 1 + } + + enum NotFlags + { + Zero = 0, + One = 1 + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/floating-point-equality.cs b/docs/multiple-tests/codacy-rules-csharp/src/floating-point-equality.cs new file mode 100644 index 0000000..d293e00 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/floating-point-equality.cs @@ -0,0 +1,15 @@ +namespace Tests.Bugs +{ + class Floats + { + void M(double d, int i) + { + float myNumber = 3.146f; + if (myNumber == 3.146f) { } // Noncompliant + if (d != 0.1) { } // Noncompliant + if (i == 3) { } + if (d < 0.1) { } + if (d != d) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/for-loop-never-runs.cs b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-never-runs.cs new file mode 100644 index 0000000..458f3de --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-never-runs.cs @@ -0,0 +1,24 @@ +namespace Tests.Bugs +{ + class Loops + { + void M() + { + for (int i = 0; i < 0; i++) // Noncompliant + { + } + for (int i = 10; i <= 5; i++) // Noncompliant + { + } + for (int i = 0; i > 5; i--) // Noncompliant + { + } + for (int i = 0; i < 5; i++) + { + } + for (int i = 5; i >= 0; i--) + { + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/for-loop-only-condition.cs b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-only-condition.cs new file mode 100644 index 0000000..858e2bc --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-only-condition.cs @@ -0,0 +1,23 @@ +namespace Tests.Style +{ + public class Loops + { + void M(bool condition) + { + for (;condition;) // Noncompliant + { + condition = Next(); + } + for (int i = 0; condition; i++) + { + condition = Next(); + } + while (condition) + { + condition = Next(); + } + } + + bool Next() { return false; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/for-loop-wrong-direction.cs b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-wrong-direction.cs new file mode 100644 index 0000000..c893a1a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/for-loop-wrong-direction.cs @@ -0,0 +1,21 @@ +namespace Tests.Bugs +{ + class Loops + { + void M(int maximum) + { + for (int i = 0; i < maximum; i--) // Noncompliant + { + } + for (int i = maximum; i >= maximum; i++) // Noncompliant + { + } + for (int i = 0; i < maximum; i++) + { + } + for (int i = maximum; i >= 0; i--) + { + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/for-update-not-loop-counter.cs b/docs/multiple-tests/codacy-rules-csharp/src/for-update-not-loop-counter.cs new file mode 100644 index 0000000..d9b6173 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/for-update-not-loop-counter.cs @@ -0,0 +1,18 @@ +namespace Tests.Practices +{ + class Loops + { + void M() + { + int sum = 0; + for (int i = 0; i < 10; sum++) // Noncompliant + { + i++; + } + for (int j = 0; j < 10; j++) + { + sum += j; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/format-string-unused-arguments.cs b/docs/multiple-tests/codacy-rules-csharp/src/format-string-unused-arguments.cs new file mode 100644 index 0000000..35d616a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/format-string-unused-arguments.cs @@ -0,0 +1,14 @@ +namespace Tests.Bugs +{ + class Formats + { + void M(object arg0, object arg1, object arg2) + { + var s = string.Format("{0}", arg0, arg1); // Noncompliant + s = string.Format("{0} {2}", arg0, arg1, arg2); // Noncompliant + s = string.Format("no placeholders", arg0); // Noncompliant + s = string.Format("{1} {0}", arg0, arg1); + s = string.Format("{0}", arg0); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/formattablestring-instead-of-string-create.cs b/docs/multiple-tests/codacy-rules-csharp/src/formattablestring-instead-of-string-create.cs new file mode 100644 index 0000000..56b56df --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/formattablestring-instead-of-string-create.cs @@ -0,0 +1,17 @@ +using System; +using System.Globalization; + +namespace Tests.Performance +{ + class Strings + { + string Interpolate(string value) => + FormattableString.Invariant($"Value: {value}"); // Noncompliant + + string Interpolate2(string value) => + FormattableString.CurrentCulture($"Value: {value}"); // Noncompliant + + string Good(string value) => + string.Create(CultureInfo.InvariantCulture, $"Value: {value}"); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/gc-collect.cs b/docs/multiple-tests/codacy-rules-csharp/src/gc-collect.cs new file mode 100644 index 0000000..5361344 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/gc-collect.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Performance +{ + class Program + { + static void Main(string[] args) + { + GC.Collect(); // Noncompliant + GC.Collect(2, GCCollectionMode.Optimized); // Noncompliant + var before = GC.GetTotalMemory(false); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/general-exception-thrown.cs b/docs/multiple-tests/codacy-rules-csharp/src/general-exception-thrown.cs new file mode 100644 index 0000000..aefe3b4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/general-exception-thrown.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Exceptions +{ + public class Thrower + { + public void DoSomething(object obj, string s) + { + if (obj == null) + { + throw new NullReferenceException("obj"); // Noncompliant + } + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + if (s.Length == 0) + { + throw new Exception("empty"); // Noncompliant + } + if (s.Length == 1) + { + throw new System.ApplicationException(); // Noncompliant + } + var x = obj ?? throw new SystemException(); // Noncompliant + throw new InvalidOperationException("ok"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/generic-logger-type-mismatch.cs b/docs/multiple-tests/codacy-rules-csharp/src/generic-logger-type-mismatch.cs new file mode 100644 index 0000000..dff9ba7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/generic-logger-type-mismatch.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Practices +{ + class AnotherType { } + + class EnclosingType + { + public EnclosingType(ILogger logger) // Noncompliant + { + } + } + + class Proper + { + public Proper(ILogger logger) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/get-executing-assembly.cs b/docs/multiple-tests/codacy-rules-csharp/src/get-executing-assembly.cs new file mode 100644 index 0000000..1233fe3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/get-executing-assembly.cs @@ -0,0 +1,15 @@ +using System; +using System.Reflection; + +namespace Tests.Performance +{ + public class Example + { + public static void Main() + { + Assembly assem = Assembly.GetExecutingAssembly(); // Noncompliant + Assembly better = typeof(Example).Assembly; + Console.WriteLine(assem.FullName + better.FullName); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/gethashcode-uses-mutable-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/gethashcode-uses-mutable-field.cs new file mode 100644 index 0000000..ea54167 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/gethashcode-uses-mutable-field.cs @@ -0,0 +1,20 @@ +namespace Tests.Bugs +{ + public class Person + { + public int age; + public string name; + private readonly int id; + + public override int GetHashCode() + { + int hash = 12; + hash += this.age.GetHashCode(); // Noncompliant + hash += name.GetHashCode(); // Noncompliant + hash += id.GetHashCode(); + return hash; + } + + public override bool Equals(object obj) => obj is Person p && p.id == id; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/getter-method-could-be-property.cs b/docs/multiple-tests/codacy-rules-csharp/src/getter-method-could-be-property.cs new file mode 100644 index 0000000..76a35f7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/getter-method-could-be-property.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Tests.Practices +{ + public class Foo + { + private string name; + + public string GetName() // Noncompliant + { + return name; + } + + public string[] GetNames() => new[] { name }; + + public Task GetNameAsync() => Task.FromResult(name); + + public IEnumerator GetEnumerator() => null; + + public string GetFormatted(string format) => name; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/gettype-on-type-instance.cs b/docs/multiple-tests/codacy-rules-csharp/src/gettype-on-type-instance.cs new file mode 100644 index 0000000..b72df94 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/gettype-on-type-instance.cs @@ -0,0 +1,18 @@ +using System; + +namespace Tests.Bugs +{ + class Types + { + void ExamineSystemType(string str) + { + Type stringType = str.GetType(); + Type runtimeType = stringType.GetType(); // Noncompliant + var t2 = typeof(string).GetType(); // Noncompliant + var t3 = typeof(Type).GetType(); + if (stringType.IsInstanceOfType(typeof(string))) // Noncompliant + { + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/goto-statement.cs b/docs/multiple-tests/codacy-rules-csharp/src/goto-statement.cs new file mode 100644 index 0000000..239af5c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/goto-statement.cs @@ -0,0 +1,25 @@ +namespace Tests.Style +{ + public class Jumps + { + void M(int i) + { + loop: + i++; + if (i < 10) + { + goto loop; // Noncompliant + } + switch (i) + { + case 1: + goto case 2; // Noncompliant + case 2: + break; + default: + break; + } + // this comment mentions goto but is fine + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-credentials.cs b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-credentials.cs new file mode 100644 index 0000000..b1074a5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-credentials.cs @@ -0,0 +1,23 @@ +namespace Tests.Security +{ + class Credentials + { + private string dbPassword = "Admin123"; // Noncompliant + + void M(Config config) + { + string password = "Admin123"; // Noncompliant + string usernamePassword = "user=admin&password=Admin123"; // Noncompliant + string url = "scheme://user:Admin123@domain.com"; // Noncompliant + config.Password = "secret"; // Noncompliant + string passwordLabel = ""; + string user = "admin"; + string fromConfig = config.Password; + } + } + + class Config + { + public string Password { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-date-format.cs b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-date-format.cs new file mode 100644 index 0000000..a77f1ee --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-date-format.cs @@ -0,0 +1,16 @@ +using System; +using System.Globalization; + +namespace Tests.Practices +{ + class Formats + { + void PrintTime(DateTime date) + { + Console.WriteLine(DateTime.UtcNow.ToString("dd/MM/yyyy HH:mm:ss")); // Noncompliant + Console.WriteLine(date.ToString("yyyy-MM-dd")); // Noncompliant + Console.WriteLine(DateTime.UtcNow.ToString("d")); + Console.WriteLine(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-ip-address.cs b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-ip-address.cs new file mode 100644 index 0000000..2ee8b27 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-ip-address.cs @@ -0,0 +1,18 @@ +using System.Net; + +namespace Tests.Security +{ + class Addresses + { + void M() + { + var ip = "192.168.12.42"; // Noncompliant + var address = IPAddress.Parse(ip); + var withPort = "10.0.0.5:8080"; // Noncompliant + var loopback = "127.0.0.1"; + var doc = "192.0.2.10"; + var oid = "2.5.4.3"; + var version = "1.2"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-jwt-secret.cs b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-jwt-secret.cs new file mode 100644 index 0000000..d949daa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-jwt-secret.cs @@ -0,0 +1,22 @@ +using System.Text; +using Microsoft.IdentityModel.Tokens; + +namespace Tests.Security +{ + public class LoginExampleController + { + private const string key = "SecretSecretSecretSecretSecretSecret"; + + public SymmetricSecurityKey Login() + { + var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); // Noncompliant + var inline = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("AnotherSecretAnotherSecret")); // Noncompliant + return securityKey; + } + + public SymmetricSecurityKey FromConfig(string configuredKey) + { + return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuredKey)); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-uri.cs b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-uri.cs new file mode 100644 index 0000000..5ae04d5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/hardcoded-uri.cs @@ -0,0 +1,17 @@ +using System.IO; + +namespace Tests.Practices +{ + public class Foo + { + public string ListUsers() + { + string userListPath = "/home/mylogin/Dev/users.txt"; // Noncompliant + string url = "https://api.example.com/v1/users"; // Noncompliant + string windows = @"C:\Users\me\file.txt"; // Noncompliant + string ns = "http://www.w3.org/2001/XMLSchema"; + string relative = "users.txt"; + return File.ReadAllText(userListPath); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/httpclient-created-per-call.cs b/docs/multiple-tests/codacy-rules-csharp/src/httpclient-created-per-call.cs new file mode 100644 index 0000000..d7f33a3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/httpclient-created-per-call.cs @@ -0,0 +1,20 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + [ApiController] + [Route("controller")] + public class FooController : ControllerBase + { + private static readonly HttpClient Shared = new HttpClient(); + + [HttpGet] + public async Task Foo() + { + using var client = new HttpClient(); // Noncompliant + return await client.GetStringAsync("https://example.com"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/icomparable-without-equality-operators.cs b/docs/multiple-tests/codacy-rules-csharp/src/icomparable-without-equality-operators.cs new file mode 100644 index 0000000..04dbd59 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/icomparable-without-equality-operators.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Bugs +{ + public class Foo : IComparable // Noncompliant + { + public int CompareTo(object obj) { return 0; } + } + + public class Bar : IComparable + { + public int CompareTo(Bar other) { return 0; } + public override bool Equals(object obj) => obj is Bar b && CompareTo(b) == 0; + public override int GetHashCode() => 0; + public static bool operator ==(Bar l, Bar r) => l.Equals(r); + public static bool operator !=(Bar l, Bar r) => !l.Equals(r); + public static bool operator <(Bar l, Bar r) => l.CompareTo(r) < 0; + public static bool operator >(Bar l, Bar r) => l.CompareTo(r) > 0; + public static bool operator <=(Bar l, Bar r) => l.CompareTo(r) <= 0; + public static bool operator >=(Bar l, Bar r) => l.CompareTo(r) >= 0; + } + + public class Baz : Base, IComparable // Noncompliant + { + public int CompareTo(Baz other) { return 0; } + public override bool Equals(object obj) => false; + public override int GetHashCode() => 0; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/identical-branches.cs b/docs/multiple-tests/codacy-rules-csharp/src/identical-branches.cs new file mode 100644 index 0000000..6b016e1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/identical-branches.cs @@ -0,0 +1,30 @@ +namespace Tests.Practices +{ + class Branches + { + void M(int a, int b) + { + if (b == 0) // Noncompliant + { + DoTheThing(); + } + else + { + DoTheThing(); + } + + int c = a > 12 ? 4 : 4; // Noncompliant + + if (b == 0) + { + DoTheThing(); + } + else if (b == 1) + { + DoTheThing(); + } + } + + void DoTheThing() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/identical-method-implementations.cs b/docs/multiple-tests/codacy-rules-csharp/src/identical-method-implementations.cs new file mode 100644 index 0000000..23af2bf --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/identical-method-implementations.cs @@ -0,0 +1,25 @@ +namespace Tests.Practices +{ + class Codes + { + private const string CODE = "secret"; + private int callCount = 0; + + public string GetCode() + { + callCount++; + return CODE; + } + + public string GetName() // Noncompliant + { + callCount++; + return CODE; + } + + public string GetOther() + { + return CODE; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/identical-operands.cs b/docs/multiple-tests/codacy-rules-csharp/src/identical-operands.cs new file mode 100644 index 0000000..f58d401 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/identical-operands.cs @@ -0,0 +1,17 @@ +namespace Tests.Bugs +{ + class Operands + { + void M(int a, int b, bool c) + { + if (a == a) { } // Noncompliant + if (a != a) { } // Noncompliant + if (a == b && a == b) { } // Noncompliant + var d = a - a; // Noncompliant + var e = a + a; + var f = a * a; + var g = 1 << 1; + if (a == b) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/iequatable-class-not-sealed.cs b/docs/multiple-tests/codacy-rules-csharp/src/iequatable-class-not-sealed.cs new file mode 100644 index 0000000..78ee1df --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/iequatable-class-not-sealed.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Bugs +{ + public class Base : IEquatable // Noncompliant + { + public bool Equals(Base other) => other != null; + } + + public sealed class Sealed : IEquatable + { + public bool Equals(Sealed other) => other != null; + } + + public class Virtual : IEquatable + { + public virtual bool Equals(Virtual other) => other != null; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/ignored-return-value.cs b/docs/multiple-tests/codacy-rules-csharp/src/ignored-return-value.cs new file mode 100644 index 0000000..a7e39fb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/ignored-return-value.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Bugs +{ + class Returns + { + void M(List data, string text, DateTime date) + { + data.Where(x => x > 5).Select(x => x * x); // Noncompliant + "this string".Equals("other string"); // Noncompliant + text.Trim(); // Noncompliant + date.AddYears(1); // Noncompliant + data.Add(1); + var result = data.Where(x => x > 5).ToList(); + text = text.Trim(); + int.TryParse(text, out var n); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/ignored-test-without-reason.cs b/docs/multiple-tests/codacy-rules-csharp/src/ignored-test-without-reason.cs new file mode 100644 index 0000000..4c4febb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/ignored-test-without-reason.cs @@ -0,0 +1,30 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class Tests + { + [TestMethod] // Noncompliant@+1 + [Ignore] + public void Test_DoTheThing() + { + Assert.IsTrue(true); + } + + [TestMethod] + [Ignore] // Flaky on CI, see ticket 123 + public void Test_Explained() + { + Assert.IsTrue(true); + } + + [TestMethod] + [Ignore] + [WorkItem(1234)] + public void Test_Tracked() + { + Assert.IsTrue(true); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/ill-formed-format-string.cs b/docs/multiple-tests/codacy-rules-csharp/src/ill-formed-format-string.cs new file mode 100644 index 0000000..21e8586 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/ill-formed-format-string.cs @@ -0,0 +1,21 @@ +using System; +using System.Text; + +namespace Tests.Bugs +{ + class Formats + { + void M(object arg0, object arg1, StringBuilder sb) + { + var s = string.Format("{0}}", arg0); // Noncompliant + s = string.Format("{0} {1}", arg0); // Noncompliant + s = string.Format("{0} {1}", arg0, arg1); + s = string.Format("{{0}} {0}", arg0); + s = string.Format("{0,-10:N2}", arg0); + sb.AppendFormat("{1}", arg0); // Noncompliant + s = string.Format("{0}"); // Noncompliant + Console.WriteLine("{0}"); + Console.WriteLine("{2}", arg0, arg1); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/incomplete-assertion.cs b/docs/multiple-tests/codacy-rules-csharp/src/incomplete-assertion.cs new file mode 100644 index 0000000..88ba957 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/incomplete-assertion.cs @@ -0,0 +1,17 @@ +using FluentAssertions; +using NFluent; + +namespace Tests.Bugs +{ + class Assertions + { + void M() + { + string actual = "Using Fluent Assertions"; + actual.Should(); // Noncompliant + Check.That(actual); // Noncompliant + actual.Should().Be("Using Fluent Assertions"); + Check.That(actual).IsEqualTo("x"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/inconsistent-operator-overloading.cs b/docs/multiple-tests/codacy-rules-csharp/src/inconsistent-operator-overloading.cs new file mode 100644 index 0000000..4e368e8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/inconsistent-operator-overloading.cs @@ -0,0 +1,26 @@ +namespace Tests.Practices +{ + public class Foo // Noncompliant + { + private int left; + + public Foo(int l) + { + this.left = l; + } + + public static Foo operator +(Foo a, Foo b) + { + return new Foo(a.left + b.left); + } + } + + public class Bar + { + public static Bar operator +(Bar a, Bar b) => a; + public static bool operator ==(Bar a, Bar b) => true; + public static bool operator !=(Bar a, Bar b) => false; + public override bool Equals(object obj) => true; + public override int GetHashCode() => 0; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/incorrect-idisposable-implementation.cs b/docs/multiple-tests/codacy-rules-csharp/src/incorrect-idisposable-implementation.cs new file mode 100644 index 0000000..edaa284 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/incorrect-idisposable-implementation.cs @@ -0,0 +1,31 @@ +using System; + +namespace Tests.Bugs +{ + public class Foo1 : IDisposable // Noncompliant + { + public void Dispose() + { + } + } + + public sealed class Foo2 : IDisposable + { + public void Dispose() + { + } + } + + public class Foo3 : IDisposable + { + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/increment-in-expression.cs b/docs/multiple-tests/codacy-rules-csharp/src/increment-in-expression.cs new file mode 100644 index 0000000..ecc29ec --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/increment-in-expression.cs @@ -0,0 +1,16 @@ +namespace Tests.Practices +{ + class Increments + { + void M(int u8b, int u8c, int bar) + { + int u8a = ++u8b + u8c--; // Noncompliant + int foo = bar++ / 4; // Noncompliant + Use(bar++); // Noncompliant + bar++; + u8a = u8b + u8c; + } + + void Use(int x) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/indexof-positive-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/indexof-positive-check.cs new file mode 100644 index 0000000..2d43dd7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/indexof-positive-check.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class IndexOfs + { + void M(List strings, string color) + { + if (strings.IndexOf(color) > 0) { } // Noncompliant + if (color.IndexOf("b") > 0) { } // Noncompliant + if (strings.IndexOf(color) >= 0) { } + if (strings.IndexOf(color) > -1) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/infinite-loop-or-recursion.cs b/docs/multiple-tests/codacy-rules-csharp/src/infinite-loop-or-recursion.cs new file mode 100644 index 0000000..aa094fe --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/infinite-loop-or-recursion.cs @@ -0,0 +1,49 @@ +namespace Tests.Bugs +{ + class Infinite + { + public int Sum() + { + var i = 0; + var result = 0; + while (true) // Noncompliant + { + result += i; + i++; + } + } + + public int Bounded() + { + var i = 0; + while (true) + { + if (i > 10) + { + break; + } + i++; + } + for (;;) + { + if (i++ > 20) + { + return i; + } + } + } + + public int Recurse() // Noncompliant + { + return Recurse(); + } + + public int Value => Value; // Noncompliant + + public int Factorial(int n) + { + if (n <= 1) return 1; + return n * Factorial(n - 1); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/insecure-cipher-mode-or-padding.cs b/docs/multiple-tests/codacy-rules-csharp/src/insecure-cipher-mode-or-padding.cs new file mode 100644 index 0000000..72a5793 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/insecure-cipher-mode-or-padding.cs @@ -0,0 +1,17 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Modes + { + public void Encrypt(byte[] dataToEncrypt) + { + var aes = Aes.Create(); + aes.Mode = CipherMode.ECB; // Noncompliant + var rsaCsp = new RSACryptoServiceProvider(2048); + byte[] encryptedData = rsaCsp.Encrypt(dataToEncrypt, false); // Noncompliant + byte[] good = rsaCsp.Encrypt(dataToEncrypt, true); + aes.Mode = CipherMode.CBC; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/insecure-temporary-file.cs b/docs/multiple-tests/codacy-rules-csharp/src/insecure-temporary-file.cs new file mode 100644 index 0000000..6b0ce77 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/insecure-temporary-file.cs @@ -0,0 +1,13 @@ +using System.IO; + +namespace Tests.Security +{ + class Temp + { + public void Example() + { + var tempPath = Path.GetTempFileName(); // Noncompliant + var random = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/integer-division-to-floating-point.cs b/docs/multiple-tests/codacy-rules-csharp/src/integer-division-to-floating-point.cs new file mode 100644 index 0000000..893a277 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/integer-division-to-floating-point.cs @@ -0,0 +1,14 @@ +namespace Tests.Bugs +{ + class Divisions + { + void M(int a, int b, double x) + { + decimal dec = 3 / 2; // Noncompliant + double d = a / b; // Noncompliant + double ok = 3.0 / 2; + double ok2 = x / b; + int i = a / b; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-dynamic-shift-operand.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-dynamic-shift-operand.cs new file mode 100644 index 0000000..c92f242 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-dynamic-shift-operand.cs @@ -0,0 +1,12 @@ +namespace Tests.Bugs +{ + class Shifts + { + void M(dynamic d) + { + var x = d >> 5.4; // Noncompliant + var y = d << null; // Noncompliant + var z = d << 4; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-event-arguments.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-event-arguments.cs new file mode 100644 index 0000000..069fd35 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-event-arguments.cs @@ -0,0 +1,22 @@ +using System; + +namespace Tests.Bugs +{ + class Foo + { + public event EventHandler ThresholdReached; + public static event EventHandler StaticEvent; + + protected virtual void OnThresholdReached(EventArgs e) + { + ThresholdReached?.Invoke(null, e); // Noncompliant + ThresholdReached?.Invoke(this, null); // Noncompliant + ThresholdReached?.Invoke(this, EventArgs.Empty); + } + + static void OnStatic() + { + StaticEvent?.Invoke(null, EventArgs.Empty); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-log-message-template.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-log-message-template.cs new file mode 100644 index 0000000..e133581 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-log-message-template.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Bugs +{ + class Logging + { + private readonly ILogger logger; + + void M(int cnt, string user) + { + logger.LogDebug("Retry attempt {Cnt,r}", cnt); // Noncompliant + logger.LogError("Login failed for {User-Name}", user); // Noncompliant + logger.LogError("Login failed for {UserName}", user); + logger.LogDebug("Retry attempt {Cnt,5:N0} {{escaped}}", cnt); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-regular-expression.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-regular-expression.cs new file mode 100644 index 0000000..b310552 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-regular-expression.cs @@ -0,0 +1,16 @@ +using System.Text.RegularExpressions; + +namespace Tests.Bugs +{ + class Regexes + { + void M(string input) + { + var regex = new Regex("[A"); // Noncompliant + var match = Regex.Match(input, "(abc"); // Noncompliant + var stars = Regex.IsMatch(input, "*abc"); // Noncompliant + var ok = new Regex("[A-Z]+(abc)?"); + var ok2 = Regex.IsMatch(input, @"\(literal\)"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-shift-count.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-shift-count.cs new file mode 100644 index 0000000..de81564 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-shift-count.cs @@ -0,0 +1,15 @@ +namespace Tests.Bugs +{ + class Shifts + { + void M(int i, long lg, byte[] bytes) + { + int intShift = i << 33; // Noncompliant + long longShift2 = lg << 65; // Noncompliant + int zero = i >> 0; // Noncompliant + int ok = i << 4; + int literal = 1 << 0; + long longOk = lg << 40; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/invalid-test-method-signature.cs b/docs/multiple-tests/codacy-rules-csharp/src/invalid-test-method-signature.cs new file mode 100644 index 0000000..9175df5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/invalid-test-method-signature.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Bugs +{ + [TestClass] + public class Signatures + { + [TestMethod] + void TestNullArg() // Noncompliant + { + Assert.IsTrue(true); + } + + [TestMethod] + public async void MyIgnoredTestMethod() // Noncompliant + { + await Task.Delay(1); + Assert.IsTrue(true); + } + + [TestMethod] + public void Fine() + { + Assert.IsTrue(true); + } + + [TestMethod] + public async Task FineAsync() + { + await Task.Delay(1); + Assert.IsTrue(true); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/inverted-boolean-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/inverted-boolean-check.cs new file mode 100644 index 0000000..9f85390 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/inverted-boolean-check.cs @@ -0,0 +1,15 @@ +namespace Tests.Style +{ + public class Inversions + { + void M(int a, int i) + { + if (!(a == 2)) { } // Noncompliant + bool b = !(i < 10); // Noncompliant + bool c = a != 2; + bool d = !Check(a); + } + + bool Check(int a) { return a > 0; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/irregular-number-grouping.cs b/docs/multiple-tests/codacy-rules-csharp/src/irregular-number-grouping.cs new file mode 100644 index 0000000..24b1abc --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/irregular-number-grouping.cs @@ -0,0 +1,12 @@ +namespace Tests.Style +{ + public class Groups + { + int thousand = 100_0; // Noncompliant + int tenThousand = 100_00; // Noncompliant + int million = 1_000_000; + int hundred = 1_00; + long hex = 0x7fff_ffff; + int bin = 0b0110_1001_01; // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/iserializable-incorrect-implementation.cs b/docs/multiple-tests/codacy-rules-csharp/src/iserializable-incorrect-implementation.cs new file mode 100644 index 0000000..625c388 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/iserializable-incorrect-implementation.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.Serialization; + +namespace Tests.Bugs +{ + public class Foo : ISerializable // Noncompliant + { + public void GetObjectData(SerializationInfo info, StreamingContext context) { } + } + + [Serializable] + public class Bar : ISerializable + { + public Bar() { } + protected Bar(SerializationInfo info, StreamingContext context) { } + public void GetObjectData(SerializationInfo info, StreamingContext context) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/issue-suppression.cs b/docs/multiple-tests/codacy-rules-csharp/src/issue-suppression.cs new file mode 100644 index 0000000..a7b5ee5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/issue-suppression.cs @@ -0,0 +1,18 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Tests.Practices +{ + public class Suppressions + { + [SuppressMessage("Usage", "CA1801")] // Noncompliant + void M() + { +#pragma warning disable CS0168 // Noncompliant + int unused; +#pragma warning restore CS0168 + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060")] // Noncompliant + void N(int x) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/iterator-argument-validation.cs b/docs/multiple-tests/codacy-rules-csharp/src/iterator-argument-validation.cs new file mode 100644 index 0000000..825a8e2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/iterator-argument-validation.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace Tests.Bugs +{ + static class Iterators + { + public static IEnumerable TakeWhile(this IEnumerable source, Func predicate) + { + if (source == null) { throw new ArgumentNullException(nameof(source)); } // Noncompliant + foreach (var element in source) + { + if (!predicate(element)) break; + yield return element; + } + } + + public static List NotIterator(List source) + { + if (source == null) { throw new ArgumentNullException(nameof(source)); } + return source; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/jsinvokable-method-not-public.cs b/docs/multiple-tests/codacy-rules-csharp/src/jsinvokable-method-not-public.cs new file mode 100644 index 0000000..2897bda --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/jsinvokable-method-not-public.cs @@ -0,0 +1,16 @@ +using Microsoft.JSInterop; + +namespace Tests.Bugs +{ + public class Interop + { + [JSInvokable] + private static void MyStaticMethod() { } // Noncompliant + + [JSInvokable] + internal void MyMethod() { } // Noncompliant + + [JSInvokable] + public void Fine() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/jwt-signature-not-verified.cs b/docs/multiple-tests/codacy-rules-csharp/src/jwt-signature-not-verified.cs new file mode 100644 index 0000000..b9f4e33 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/jwt-signature-not-verified.cs @@ -0,0 +1,21 @@ +using JWT; +using JWT.Builder; + +namespace Tests.Security +{ + class Tokens + { + public static void Decode(IJwtDecoder decoder, string token, string secret) + { + decoder.Decode(token, secret, verify: false); // Noncompliant + decoder.Decode(token, secret, verify: true); + var json = new JwtBuilder() + .WithSecret(secret) + .Decode(token); // Noncompliant + var verified = new JwtBuilder() + .WithSecret(secret) + .MustVerifySignature() + .Decode(token); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/large-number-without-underscores.cs b/docs/multiple-tests/codacy-rules-csharp/src/large-number-without-underscores.cs new file mode 100644 index 0000000..266734b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/large-number-without-underscores.cs @@ -0,0 +1,14 @@ +namespace Tests.Style +{ + public class Numbers + { + int i = 10000000; // Noncompliant + int i2 = 10_000_000; + int small = 99999; + int j = 0b01101001010011011110010101011110; // Noncompliant + int j2 = 0b01101001_01001101_11100101_01011110; + long l = 0x7fffffffffffffffL; // Noncompliant + long l2 = 0x7fff_ffff_ffff_ffffL; + int k = 0xFF; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/line-too-long.cs b/docs/multiple-tests/codacy-rules-csharp/src/line-too-long.cs new file mode 100644 index 0000000..572fa27 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/line-too-long.cs @@ -0,0 +1,8 @@ +namespace Tests.Layout +{ + public class Lines + { + private string ok = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private string tooLong = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/list-in-public-api.cs b/docs/multiple-tests/codacy-rules-csharp/src/list-in-public-api.cs new file mode 100644 index 0000000..6a8ec92 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/list-in-public-api.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace Foo +{ + public class Bar + { + public List Method1(T arg) // Noncompliant + { + return null; + } + + public void Method2(List items) // Noncompliant + { + } + + private List internalList = new List(); + + public IList Fine() => internalList; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/local-could-be-const.cs b/docs/multiple-tests/codacy-rules-csharp/src/local-could-be-const.cs new file mode 100644 index 0000000..eeca094 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/local-could-be-const.cs @@ -0,0 +1,23 @@ +namespace Tests.Practices +{ + class Consts + { + public bool Seek(int[] input) + { + var target = 32; // Noncompliant + foreach (int i in input) + { + if (i == target) + { + return true; + } + } + var counter = 0; + foreach (int i in input) + { + counter++; + } + return counter > 0; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/local-shadows-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/local-shadows-field.cs new file mode 100644 index 0000000..40f5b2b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/local-shadows-field.cs @@ -0,0 +1,22 @@ +namespace Tests.Style +{ + public class Foo + { + public int myField; + private string other = "x"; + public int MyProperty { get; set; } + + public void DoSomething() + { + int myField = 0; // Noncompliant + int MyProperty = 1; // Noncompliant + string other; // Noncompliant + int unrelated = 2; + } + + public static void Create() + { + int myField = 3; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/local-time-recorded.cs b/docs/multiple-tests/codacy-rules-csharp/src/local-time-recorded.cs new file mode 100644 index 0000000..3b4293e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/local-time-recorded.cs @@ -0,0 +1,15 @@ +using System; +using System.IO; + +namespace Tests.Practices +{ + class Logs + { + void LogDateTime() + { + using var streamWriter = new StreamWriter("logs.txt", true); + streamWriter.WriteLine($"DateTime:{DateTime.Now:o}"); // Noncompliant + streamWriter.WriteLine($"DateTime:{DateTime.UtcNow:o}"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lock-not-released-on-all-paths.cs b/docs/multiple-tests/codacy-rules-csharp/src/lock-not-released-on-all-paths.cs new file mode 100644 index 0000000..84eee05 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lock-not-released-on-all-paths.cs @@ -0,0 +1,48 @@ +using System.Threading; + +namespace Tests.Bugs +{ + class MyClass + { + private readonly object obj = new object(); + private readonly ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim(); + + public void DoSomethingWithMonitor(bool condition) + { + Monitor.Enter(obj); // Noncompliant + if (condition) + { + Monitor.Exit(obj); + } + } + + public void DoSomethingWithReaderWriteLockSlim(bool condition) + { + lockObj.EnterReadLock(); // Noncompliant + if (condition) + { + lockObj.ExitReadLock(); + } + } + + public void Correct() + { + Monitor.Enter(obj); + try + { + DoWork(); + } + finally + { + Monitor.Exit(obj); + } + } + + public void NeverReleased() + { + Monitor.Enter(obj); + } + + void DoWork() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lock-on-local-variable.cs b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-local-variable.cs new file mode 100644 index 0000000..0d8f2c6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-local-variable.cs @@ -0,0 +1,22 @@ +namespace Tests.Bugs +{ + class Locks + { + private readonly object sync = new object(); + + private void DoSomething() + { + object local = new object(); + lock (local) // Noncompliant + { + Work(); + } + lock (sync) + { + Work(); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lock-on-non-readonly-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-non-readonly-field.cs new file mode 100644 index 0000000..3ae8915 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-non-readonly-field.cs @@ -0,0 +1,31 @@ +namespace Tests.Bugs +{ + class Color + { + public Color(string name) { } + } + + class Locks + { + private Color color = new Color("red"); + private readonly object sync = new object(); + + private void DoSomething() + { + lock (color) // Noncompliant + { + Paint(); + } + lock (new object()) // Noncompliant + { + Paint(); + } + lock (sync) + { + Paint(); + } + } + + void Paint() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lock-on-shared-resource.cs b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-shared-resource.cs new file mode 100644 index 0000000..bb59291 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-shared-resource.cs @@ -0,0 +1,29 @@ +namespace Tests.Bugs +{ + class Locks + { + private readonly object sync = new object(); + + void MyLockingMethod() + { + lock (this) // Noncompliant + { + Work(); + } + lock (typeof(Locks)) // Noncompliant + { + Work(); + } + lock ("shared") // Noncompliant + { + Work(); + } + lock (sync) + { + Work(); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lock-on-weak-identity-object.cs b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-weak-identity-object.cs new file mode 100644 index 0000000..4973bfa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lock-on-weak-identity-object.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading; + +namespace Tests.Bugs +{ + public class Sample + { + private readonly StackOverflowException myLock = new StackOverflowException(); + private readonly Thread thread = new Thread(() => { }); + private readonly object sync = new object(); + + public void Go() + { + lock (myLock) // Noncompliant + { + Work(); + } + lock (thread) // Noncompliant + { + Work(); + } + lock (sync) + { + Work(); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/log-and-rethrow.cs b/docs/multiple-tests/codacy-rules-csharp/src/log-and-rethrow.cs new file mode 100644 index 0000000..ec8b9c1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/log-and-rethrow.cs @@ -0,0 +1,45 @@ +using System; +using Microsoft.Extensions.Logging; + +namespace Tests.Practices +{ + class Service + { + private readonly ILogger logger; + + void M() + { + try + { + Work(); + } + catch (Exception ex) // Noncompliant + { + logger.LogError(ex.Message); + throw; + } + + try + { + Work(); + } + catch (Exception ex) + { + logger.LogError("Failed"); + throw; + } + + try + { + Work(); + } + catch (Exception ex) + { + logger.LogError(ex, "Failed"); + throw new InvalidOperationException("Work failed", ex); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/log-template-argument-order.cs b/docs/multiple-tests/codacy-rules-csharp/src/log-template-argument-order.cs new file mode 100644 index 0000000..a2a2ac1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/log-template-argument-order.cs @@ -0,0 +1,17 @@ +using System.IO; +using Microsoft.Extensions.Logging; + +namespace Tests.Bugs +{ + class Logging + { + private readonly ILogger logger; + + void M(string path, string fileName, FileInfo file) + { + logger.LogError("File {FileName} not found in folder {Path}", path, fileName); // Noncompliant + logger.LogError("File {FileName} not found in folder {Path}", fileName, path); + logger.LogError("File {Name} not found in folder {Folder}", file.DirectoryName, file.Name); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/log-template-placeholder-not-pascal-case.cs b/docs/multiple-tests/codacy-rules-csharp/src/log-template-placeholder-not-pascal-case.cs new file mode 100644 index 0000000..3859cb8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/log-template-placeholder-not-pascal-case.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Style +{ + class Logins + { + void M(ILogger logger, string firstName) + { + logger.LogDebug("User {firstName} logged in", firstName); // Noncompliant + logger.LogDebug("User {FirstName} logged in", firstName); + logger.LogDebug("Escaped {{braces}} {0}", firstName); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/logger-category-mismatch.cs b/docs/multiple-tests/codacy-rules-csharp/src/logger-category-mismatch.cs new file mode 100644 index 0000000..e3b6dfd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/logger-category-mismatch.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Practices +{ + class AnotherType { } + + class EnclosingType + { + private readonly ILogger logger; + + public EnclosingType(ILoggerFactory loggerFactory) + { + logger = loggerFactory.CreateLogger(); // Noncompliant + logger = loggerFactory.CreateLogger(); + logger = loggerFactory.CreateLogger("My cross-type logging category"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/logger-configuration.cs b/docs/multiple-tests/codacy-rules-csharp/src/logger-configuration.cs new file mode 100644 index 0000000..3b341b3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/logger-configuration.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Tests.Security +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddLogging(logging => // Noncompliant + { + logging.SetMinimumLevel(LogLevel.Debug); + }); + } + + public void Configure(ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/logger-field-not-private-static-readonly.cs b/docs/multiple-tests/codacy-rules-csharp/src/logger-field-not-private-static-readonly.cs new file mode 100644 index 0000000..6afd36d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/logger-field-not-private-static-readonly.cs @@ -0,0 +1,10 @@ +using log4net; + +namespace Tests.Practices +{ + public class Service + { + public ILog logger = LogManager.GetLogger(typeof(Service)); // Noncompliant + private static readonly ILog Log = LogManager.GetLogger(typeof(Service)); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/logger-naming.cs b/docs/multiple-tests/codacy-rules-csharp/src/logger-naming.cs new file mode 100644 index 0000000..3bac70a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/logger-naming.cs @@ -0,0 +1,12 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Naming +{ + public class Service + { + private readonly ILogger myLogger; // Noncompliant + private readonly ILogger _logger; + public ILogger MyLogger { get; set; } // Noncompliant + private static readonly ILog Log = null; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/logging-arguments-in-message-arguments.cs b/docs/multiple-tests/codacy-rules-csharp/src/logging-arguments-in-message-arguments.cs new file mode 100644 index 0000000..56499ea --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/logging-arguments-in-message-arguments.cs @@ -0,0 +1,25 @@ +using System; +using Microsoft.Extensions.Logging; + +namespace Tests.Bugs +{ + class Logging + { + private readonly ILogger logger; + + void M() + { + try + { + Work(); + } + catch (Exception ex) + { + logger.LogDebug("An exception occured {Exception}.", ex); // Noncompliant + logger.LogError(ex, "An exception occured."); + } + } + + void Work() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/loop-could-use-linq.cs b/docs/multiple-tests/codacy-rules-csharp/src/loop-could-use-linq.cs new file mode 100644 index 0000000..27cb8c2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/loop-could-use-linq.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Tests.Practices +{ + class Loops + { + List M(List collection) + { + var result = new List(); + foreach (var element in collection) // Noncompliant + { + if (element.Length > 3) + { + result.Add(element); + } + } + foreach (var element in collection) + { + result.Add(element); + if (element.Length > 3) + { + result.Add(element); + } + } + return result; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/loop-counter-modified-in-body.cs b/docs/multiple-tests/codacy-rules-csharp/src/loop-counter-modified-in-body.cs new file mode 100644 index 0000000..7723b1c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/loop-counter-modified-in-body.cs @@ -0,0 +1,23 @@ +using System; + +namespace Tests.Bugs +{ + class Loops + { + void M(bool condition) + { + for (int i = 1; i <= 5; i++) + { + Console.WriteLine(i); + if (condition) + { + i = 20; // Noncompliant + } + } + for (int j = 0; j < 5; j++) + { + Console.WriteLine(j); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/loop-with-single-iteration.cs b/docs/multiple-tests/codacy-rules-csharp/src/loop-with-single-iteration.cs new file mode 100644 index 0000000..2a514bd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/loop-with-single-iteration.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace Tests.Practices +{ + class Loops + { + public object Method(IEnumerable items) + { + for (int i = 0; i < 10; i++) // Noncompliant + { + Console.WriteLine(i); + break; + } + + foreach (var item in items) // Noncompliant + { + return item; + } + + foreach (var item in items) + { + if (item == null) + { + continue; + } + return item; + } + + while (items != null) + { + if (Check()) + { + break; + } + } + return null; + } + + bool Check() { return true; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/loose-file-permissions.cs b/docs/multiple-tests/codacy-rules-csharp/src/loose-file-permissions.cs new file mode 100644 index 0000000..396375d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/loose-file-permissions.cs @@ -0,0 +1,15 @@ +using System.IO; +using System.Security.AccessControl; + +namespace Tests.Security +{ + class Permissions + { + void M(FileSecurity fileSecurity) + { + var unsafeAccessRule = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow); // Noncompliant + fileSecurity.AddAccessRule(unsafeAccessRule); + var safeRule = new FileSystemAccessRule("Administrators", FileSystemRights.FullControl, AccessControlType.Allow); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lowercase-literal-suffix.cs b/docs/multiple-tests/codacy-rules-csharp/src/lowercase-literal-suffix.cs new file mode 100644 index 0000000..0601e1f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lowercase-literal-suffix.cs @@ -0,0 +1,13 @@ +namespace Tests.Style +{ + public class Literals + { + const long b = 0l; // Noncompliant + const long c = 0L; + const uint d = 1u; + const ulong e = 1UL; + const ulong f = 1ul; // Noncompliant + const int hex = 0xff; + const decimal m = 1.5M; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/lowercase-string-normalization.cs b/docs/multiple-tests/codacy-rules-csharp/src/lowercase-string-normalization.cs new file mode 100644 index 0000000..5ef1bed --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/lowercase-string-normalization.cs @@ -0,0 +1,12 @@ +namespace Tests.Practices +{ + class Normalization + { + bool M(string a) + { + var areEqual = "INTEGER".ToLower() == "integer"; // Noncompliant + var other = a.ToLowerInvariant() == "x"; // Noncompliant + return a.ToUpperInvariant() == "INTEGER"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/magic-number.cs b/docs/multiple-tests/codacy-rules-csharp/src/magic-number.cs new file mode 100644 index 0000000..89455db --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/magic-number.cs @@ -0,0 +1,30 @@ +using System; + +namespace Tests.Style +{ + public class Numbers + { + private const int Max = 4; + private int field = 42; + + [Obsolete("x", false)] + public void DoSomething(int retries = 3) + { + for (int i = 0; i < 4; i++) // Noncompliant + { + Console.Write(i * 1000); // Noncompliant + } + var size = 16; + var ts = new TimeSpan(0, 5, 0); + Use(count: 7); + if (field > Max || retries == 0 || size == 1) + { + return; + } + } + + void Use(int count) { } + + public override int GetHashCode() => 31 * field; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/manual-timezone-conversion.cs b/docs/multiple-tests/codacy-rules-csharp/src/manual-timezone-conversion.cs new file mode 100644 index 0000000..2dcb2c4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/manual-timezone-conversion.cs @@ -0,0 +1,15 @@ +using System; +using TimeZoneConverter; + +namespace Tests.Practices +{ + class Zones + { + void M() + { + var ianaTimeZone = "Asia/Tokyo"; + var windowsTimeZone = TZConvert.IanaToWindows(ianaTimeZone); // Noncompliant + TimeZoneInfo tokyo = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZone); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/member-more-visible-than-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/member-more-visible-than-type.cs new file mode 100644 index 0000000..e7005c8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/member-more-visible-than-type.cs @@ -0,0 +1,22 @@ +namespace Tests.Practices +{ + internal class MyClass + { + public static decimal PI = 3.14m; // Noncompliant + + public int GetOne() // Noncompliant + { + return 1; + } + + internal int GetTwo() + { + return 2; + } + } + + internal class Implementer : System.IDisposable + { + public void Dispose() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/mergeable-if-statements.cs b/docs/multiple-tests/codacy-rules-csharp/src/mergeable-if-statements.cs new file mode 100644 index 0000000..2612347 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/mergeable-if-statements.cs @@ -0,0 +1,43 @@ +namespace Tests.Style +{ + public class Ifs + { + void M(object file, bool a, bool b) + { + if (file != null) // Noncompliant + { + if (a || b) + { + Do(); + } + } + + if (file != null && (a || b)) + { + Do(); + } + + if (a) + { + if (b) { Do(); } + } + else + { + Do(); + } + + if (a) + { + if (b) { Do(); } else { Do(); } + } + + if (a) + { + Do(); + if (b) { Do(); } + } + } + + void Do() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/mergeable-try-statements.cs b/docs/multiple-tests/codacy-rules-csharp/src/mergeable-try-statements.cs new file mode 100644 index 0000000..0242866 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/mergeable-try-statements.cs @@ -0,0 +1,35 @@ +using System; + +namespace Tests.Style +{ + class Tries + { + void M(int a, int b) + { + try + { + DoTheFirstThing(a, b); + } + catch (InvalidOperationException ex) + { + HandleException(ex); + } + + DoSomeOtherStuff(); + + try + { + DoTheSecondThing(); // Noncompliant@+2 + } + catch (InvalidOperationException ex) + { + HandleException(ex); + } + } + + void DoTheFirstThing(int a, int b) { } + void DoTheSecondThing() { } + void DoSomeOtherStuff() { } + void HandleException(Exception ex) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/method-overloads-not-grouped.cs b/docs/multiple-tests/codacy-rules-csharp/src/method-overloads-not-grouped.cs new file mode 100644 index 0000000..75d6b04 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/method-overloads-not-grouped.cs @@ -0,0 +1,20 @@ +namespace Tests.Style +{ + class MyClass + { + public int DoTheThing() + { + return 1; + } + + public string DoTheOtherThing() + { + return "x"; + } + + public int DoTheThing(int x) // Noncompliant + { + return x; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/method-property-pascal-case.cs b/docs/multiple-tests/codacy-rules-csharp/src/method-property-pascal-case.cs new file mode 100644 index 0000000..c54371e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/method-property-pascal-case.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Naming +{ + public class Sample : BaseSample + { + public int doSomething() { return 1; } // Noncompliant + public int DoSomething() { return 1; } + void My_method_() { } // Noncompliant + void _Leading() { } // Noncompliant + void My_method() { } + void MyXMethod() { } + void XM() { } // Noncompliant + void GetHTMLPage() { } // Noncompliant + void GetHtmlPage() { } + int compute() => 42; // Noncompliant + int Compute() => 42; + public int myProperty { get; set; } // Noncompliant + public int MyProperty { get; set; } + public override string toString() { return ""; } + [DllImport("user32.dll")] + static extern int messageBox(IntPtr h, string m, string c, int t); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/method-returns-constant.cs b/docs/multiple-tests/codacy-rules-csharp/src/method-returns-constant.cs new file mode 100644 index 0000000..9397b3e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/method-returns-constant.cs @@ -0,0 +1,19 @@ +namespace Tests.Performance +{ + class Constants + { + int GetBestNumber() // Noncompliant + { + return 12; + } + + string Name() => "name"; // Noncompliant + + public override string ToString() => "constant"; + + int Compute(int x) + { + return x * 2; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/misleading-conditional-indentation.cs b/docs/multiple-tests/codacy-rules-csharp/src/misleading-conditional-indentation.cs new file mode 100644 index 0000000..453045b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/misleading-conditional-indentation.cs @@ -0,0 +1,24 @@ +namespace Tests.Bugs +{ + public class Indentation + { + void M(bool condition) + { + if (condition) // Noncompliant + DoTheThing(); + DoTheOtherThing(); + + if (condition) + DoTheThing(); + DoTheOtherThing(); + + if (condition) + { + DoTheThing(); + } + } + + void DoTheThing() { } + void DoTheOtherThing() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-assembly-version.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-assembly-version.cs new file mode 100644 index 0000000..96a9a92 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-assembly-version.cs @@ -0,0 +1,11 @@ +using System.Reflection; + +[assembly: AssemblyTitle("MyAssembly")] // Noncompliant +[assembly: AssemblyDescription("Description")] + +namespace MyLibrary +{ + public class Placeholder + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-configure-await.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-configure-await.cs new file mode 100644 index 0000000..a24c45c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-configure-await.cs @@ -0,0 +1,16 @@ +using System.Net.Http; +using System.Threading.Tasks; + +namespace Tests.Performance +{ + class Client + { + async Task Get(HttpClient httpClient, string url) + { + var response = await httpClient.GetAsync(url); // Noncompliant + var body = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + await Task.Yield(); + return body; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-curly-braces.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-curly-braces.cs new file mode 100644 index 0000000..eba32b7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-curly-braces.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace Tests.Style +{ + public class Braces + { + void M(bool condition, List items, int n) + { + if (condition) // Noncompliant + ExecuteSomething(); + if (condition) { ExecuteSomething(); } + if (condition) + { + ExecuteSomething(); + } + else if (n > 2) + { + ExecuteSomething(); + } + else + ExecuteSomething(); // Noncompliant + while (n-- > 0) // Noncompliant + ExecuteSomething(); + while (n++ < 3) + { + ExecuteSomething(); + } + foreach (var item in items) // Noncompliant + ExecuteSomething(); + foreach (var item in items) + { + ExecuteSomething(); + } + for (int i = 0; i < n; i++) ExecuteSomething(); // Noncompliant + for (int i = 0; i < n; i++) + { + ExecuteSomething(); + } + do // Noncompliant + ExecuteSomething(); + while (condition); + do + { + ExecuteSomething(); + } while (condition); + } + + void ExecuteSomething() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-final-newline.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-final-newline.cs new file mode 100644 index 0000000..afa32e3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-final-newline.cs @@ -0,0 +1,6 @@ +namespace Tests.Layout +{ + public class NoNewLine + { + } +} // Noncompliant \ No newline at end of file diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-format-provider.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-format-provider.cs new file mode 100644 index 0000000..7decbc0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-format-provider.cs @@ -0,0 +1,17 @@ +using System; +using System.Globalization; + +namespace MyLibrary +{ + public class Foo + { + public void Example(string input, decimal amount) + { + int number = int.Parse(input); // Noncompliant + int other = int.Parse(input, CultureInfo.InvariantCulture); + string text = amount.ToString("N2"); // Noncompliant + string good = amount.ToString("N2", CultureInfo.InvariantCulture); + Console.WriteLine(number + other + text + good); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-stathread-on-windows-forms-main.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-stathread-on-windows-forms-main.cs new file mode 100644 index 0000000..8f505c3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-stathread-on-windows-forms-main.cs @@ -0,0 +1,22 @@ +using System; +using System.Windows.Forms; + +namespace Tests.Bugs +{ + public class MyForm : Form + { + static void Main() // Noncompliant + { + Application.Run(new MyForm()); + } + } + + public class OtherForm : Form + { + [STAThread] + static void Main() + { + Application.Run(new OtherForm()); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/missing-string-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/missing-string-comparison.cs new file mode 100644 index 0000000..7a7db51 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/missing-string-comparison.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tests.Practices +{ + class Comparisons + { + int M(string name1, string name2) + { + var a = string.Compare(name1, name2); // Noncompliant + var b = string.Compare(name1, name2, StringComparison.Ordinal); + var c = name1.StartsWith("x"); // Noncompliant + return a + b + (c ? 1 : 0); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/model-state-not-validated.cs b/docs/multiple-tests/codacy-rules-csharp/src/model-state-not-validated.cs new file mode 100644 index 0000000..04788bc --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/model-state-not-validated.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + public class Movie { public string Title { get; set; } } + + public class MoviesController : Controller + { + [HttpPost] + public async Task Create(Movie movie) // Noncompliant + { + await Task.Yield(); + return RedirectToAction("Index"); + } + + [HttpPost] + public async Task CreateChecked(Movie movie) + { + if (!ModelState.IsValid) + { + return View(movie); + } + await Task.Yield(); + return RedirectToAction("Index"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/modulus-equality-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/modulus-equality-check.cs new file mode 100644 index 0000000..1788fe1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/modulus-equality-check.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Modulus + { + public bool IsOdd(int x) + { + return x % 2 == 1; // Noncompliant + } + + public bool IsEven(int x) + { + return x % 2 == 0; + } + + public bool Check(List list, uint u) + { + return list.Count % 2 == 1 || u % 2 == 1; + } + + public bool Third(int x) + { + return x % 3 != 2; // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array-parameter.cs new file mode 100644 index 0000000..14a8b0e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array-parameter.cs @@ -0,0 +1,21 @@ +namespace Tests.Comprehensibility +{ + public class Program + { + public void WriteMatrix(int[][] matrix) // Noncompliant + { + } + + public void WriteGrid(int[,] grid) // Noncompliant + { + } + + private void UpdateMatrix(int[][] matrix) + { + } + + public void WriteRow(int[] row) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array.cs b/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array.cs new file mode 100644 index 0000000..ba7e07d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multidimensional-array.cs @@ -0,0 +1,16 @@ +namespace Tests.Performance +{ + class Arrays + { + void M() + { + int[,] myArray = // Noncompliant + { + {1, 2, 3, 4}, + {5, 6, 7, 0} + }; + int[][] jagged = new int[2][]; + System.Console.WriteLine(myArray[1, 1] + jagged.Length); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multiline-block-without-braces.cs b/docs/multiple-tests/codacy-rules-csharp/src/multiline-block-without-braces.cs new file mode 100644 index 0000000..39cbfc0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multiline-block-without-braces.cs @@ -0,0 +1,27 @@ +namespace Tests.Bugs +{ + public class Blocks + { + void M(bool condition) + { + if (condition) + FirstActionInBlock(); + SecondAction(); // Noncompliant + + if (condition) FirstActionInBlock(); SecondAction(); // Noncompliant + + if (condition) + FirstActionInBlock(); + SecondAction(); + + if (condition) + { + FirstActionInBlock(); + SecondAction(); + } + } + + void FirstActionInBlock() { } + void SecondAction() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multiple-declarations-per-line.cs b/docs/multiple-tests/codacy-rules-csharp/src/multiple-declarations-per-line.cs new file mode 100644 index 0000000..b660232 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multiple-declarations-per-line.cs @@ -0,0 +1,14 @@ +namespace Tests.Style +{ + public class Declarations + { + private int a, b; // Noncompliant + private int c; + + public void Method() + { + int d, e; // Noncompliant + int f = 1; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multiple-orderby-calls.cs b/docs/multiple-tests/codacy-rules-csharp/src/multiple-orderby-calls.cs new file mode 100644 index 0000000..21b43c7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multiple-orderby-calls.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Person + { + public int Age { get; set; } + public string Name { get; set; } + } + + class Sorting + { + void M(List personList) + { + var x = personList + .OrderBy(person => person.Age) + .OrderBy(person => person.Name) // Noncompliant@-2 + .ToList(); + var y = personList.OrderBy(p => p.Age).ThenBy(p => p.Name).ToList(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/multiple-statements-per-line.cs b/docs/multiple-tests/codacy-rules-csharp/src/multiple-statements-per-line.cs new file mode 100644 index 0000000..6ba713b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/multiple-statements-per-line.cs @@ -0,0 +1,30 @@ +using System; + +namespace Tests.Style +{ + public class Statements + { + public int Prop { get; set; } + public int Other { get; private set; } + + void M(bool someCondition, int a) + { + if (someCondition) DoSomething(); // Noncompliant + a = 1; a = 2; // Noncompliant + Func item1 = o => { return true; }; + Func item2 = o => { var r = false; return r; }; // Noncompliant + var s = "a; b"; + for (int i = 0; i < 3; i++) + { + DoSomething(); + } + if (someCondition) + { + DoSomething(); + } + else DoSomething(); // Noncompliant + } + + void DoSomething() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nan-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/nan-comparison.cs new file mode 100644 index 0000000..314d584 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nan-comparison.cs @@ -0,0 +1,17 @@ +using System; + +namespace Tests.Bugs +{ + class NaNs + { + void M(double a, float f) + { + if (a == double.NaN) // Noncompliant + { + Console.WriteLine("a is not a number"); + } + if (f != float.NaN) { } // Noncompliant + if (double.IsNaN(a)) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/native-method-not-wrapped.cs b/docs/multiple-tests/codacy-rules-csharp/src/native-method-not-wrapped.cs new file mode 100644 index 0000000..1ed8f7d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/native-method-not-wrapped.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; + +namespace MyLibrary +{ + class Foo + { + [DllImport("mynativelib")] + extern public static void Bar(string s, int x); // Noncompliant + + [DllImport("mynativelib")] + extern private static void Baz(string s, int x); + + public void SafeBaz(string s) + { + if (s != null) + { + Baz(s, 1); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nested-code-block.cs b/docs/multiple-tests/codacy-rules-csharp/src/nested-code-block.cs new file mode 100644 index 0000000..4897280 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nested-code-block.cs @@ -0,0 +1,30 @@ +namespace Tests.Practices +{ + public class Blocks + { + public void Evaluate(int x) + { + var a = x; + { // Noncompliant + int b = a + 1; + Use(b); + } + switch (x) + { + case 1: + { + Use(x); + break; + } + default: + break; + } + var list = new System.Collections.Generic.Dictionary + { + { 1, 2 }, + }; + } + + void Use(int v) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nested-generic-type-in-signature.cs b/docs/multiple-tests/codacy-rules-csharp/src/nested-generic-type-in-signature.cs new file mode 100644 index 0000000..19e4f62 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nested-generic-type-in-signature.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Tests.Complexity +{ + public class Generics + { + public void DoSomething(ICollection> outerCollect) // Noncompliant + { + } + + public void Simple(ICollection values) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nested-member-shadows-outer-member.cs b/docs/multiple-tests/codacy-rules-csharp/src/nested-member-shadows-outer-member.cs new file mode 100644 index 0000000..ed1b32d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nested-member-shadows-outer-member.cs @@ -0,0 +1,13 @@ +namespace Tests.Practices +{ + class Outer + { + public static int A; + + public class Inner + { + public int A; // Noncompliant + public int B; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nested-switch.cs b/docs/multiple-tests/codacy-rules-csharp/src/nested-switch.cs new file mode 100644 index 0000000..aa7575d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nested-switch.cs @@ -0,0 +1,24 @@ +namespace Tests.Style +{ + class Switches + { + void M(int a, int b) + { + switch (a) + { + case 1: + switch (b) // Noncompliant + { + case 2: + Do(); + break; + } + break; + default: + break; + } + } + + void Do() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nested-ternary.cs b/docs/multiple-tests/codacy-rules-csharp/src/nested-ternary.cs new file mode 100644 index 0000000..b751ee1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nested-ternary.cs @@ -0,0 +1,21 @@ +namespace Tests.Comprehensibility +{ + class Job + { + public bool IsRunning { get; set; } + public bool HasErrors { get; set; } + } + + class Status + { + public string GetReadableStatus(Job j) + { + return j.IsRunning ? "Running" : j.HasErrors ? "Failed" : "Succeeded"; // Noncompliant + } + + public string Simple(Job j) + { + return j.IsRunning ? "Running" : "Idle"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-constant-log-template.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-constant-log-template.cs new file mode 100644 index 0000000..a7f746d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-constant-log-template.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.Logging; + +namespace Tests.Performance +{ + class Logging + { + private readonly ILogger logger; + + void M(int parameter) + { + logger.LogDebug($"The value of the parameter is: {parameter}."); // Noncompliant + logger.LogInformation("Value: " + parameter); // Noncompliant + logger.LogDebug("The value of the parameter is: {Parameter}.", parameter); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-constant-visible-static-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-constant-visible-static-field.cs new file mode 100644 index 0000000..a791ff6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-constant-visible-static-field.cs @@ -0,0 +1,19 @@ +namespace Tests.Practices +{ + public class Math + { + public static double Pi = 3.14; // Noncompliant + public const double E = 2.71; + public static readonly double Tau = 6.28; + private static int counter; + } + + public class Shape + { + public static Shape Empty = new EmptyShape(); // Noncompliant + + private class EmptyShape : Shape + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-existent-operator.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-existent-operator.cs new file mode 100644 index 0000000..f00f13e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-existent-operator.cs @@ -0,0 +1,18 @@ +namespace Tests.Bugs +{ + class Operators + { + void M() + { + int target = -5; + int num = 3; + target =- num; // Noncompliant + target =+ num; // Noncompliant + target = -num; + target -= num; + target =-1; + bool b = true; + bool c = !b; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-generic-collection.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-generic-collection.cs new file mode 100644 index 0000000..7e49bad --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-generic-collection.cs @@ -0,0 +1,22 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Tests.Practices +{ + public class MyData { } + + public class MyList : CollectionBase // Noncompliant + { + public void Add(MyData data) { InnerList.Add(data); } + } + + public class TypedList : CollectionBase, ICollection + { + public bool IsReadOnly => false; + public void Add(MyData item) { } + public bool Contains(MyData item) => false; + public void CopyTo(MyData[] array, int arrayIndex) { } + public bool Remove(MyData item) => false; + public new IEnumerator GetEnumerator() => null; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-generic-event-handler.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-generic-event-handler.cs new file mode 100644 index 0000000..e51f2b3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-generic-event-handler.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Practices +{ + public class MyEventArgs : EventArgs { } + + public delegate void MyEventHandler(object sender, MyEventArgs e); // Noncompliant + + public class EventProducer + { + public event MyEventHandler OnSomething; + public event EventHandler OnOther; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-integral-indexer.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-integral-indexer.cs new file mode 100644 index 0000000..c27be0c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-integral-indexer.cs @@ -0,0 +1,17 @@ +namespace Tests.Practices +{ + public class MyCustomClass { } + + public class Indexers + { + public int this[MyCustomClass index] // Noncompliant + { + get { return 0; } + } + + public int this[string key] + { + get { return 0; } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-private-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-private-field.cs new file mode 100644 index 0000000..93488d6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-private-field.cs @@ -0,0 +1,16 @@ +namespace Tests.Practices +{ + public class Foo + { + public int MagicNumber = 42; // Noncompliant + public readonly int Answer = 42; // Noncompliant + public static int Shared = 1; + public const int Constant = 1; + private int hidden; + } + + public struct Point + { + public int X; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-public-exception-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-public-exception-type.cs new file mode 100644 index 0000000..e17056e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-public-exception-type.cs @@ -0,0 +1,16 @@ +using System; + +namespace Tests.Practices +{ + internal class MyException : Exception // Noncompliant + { + } + + public class PublicException : Exception + { + } + + class ImplicitInternalException : InvalidOperationException // Noncompliant + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/non-short-circuit-logic.cs b/docs/multiple-tests/codacy-rules-csharp/src/non-short-circuit-logic.cs new file mode 100644 index 0000000..908efb1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/non-short-circuit-logic.cs @@ -0,0 +1,17 @@ +namespace Tests.Bugs +{ + class Logic + { + void M(string s, int flags) + { + if (GetTrue() | GetFalse()) { } // Noncompliant + bool b = s != null & s.Length > 0; // Noncompliant + var masked = flags & 4; + if ((flags & 4) != 0) { } + if (GetTrue() || GetFalse()) { } + } + + bool GetTrue() { return true; } + bool GetFalse() { return false; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nonsensical-size-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/nonsensical-size-comparison.cs new file mode 100644 index 0000000..7fdcb35 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nonsensical-size-comparison.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Sizes + { + void M(List collection, int[] array) + { + if (collection.Count >= 0) { } // Noncompliant + if (array.Length >= 0) { } // Noncompliant + if (array.Length < 0) { } // Noncompliant + if (collection.Count > 0) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/not-implemented-exception.cs b/docs/multiple-tests/codacy-rules-csharp/src/not-implemented-exception.cs new file mode 100644 index 0000000..6d3265d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/not-implemented-exception.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Bugs +{ + class Todo + { + void DoTheThing() + { + throw new NotImplementedException(); // Noncompliant + } + + int Other() => throw new NotImplementedException(); // Noncompliant + + void Fine() + { + throw new NotSupportedException(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/null-pointer-dereference.cs b/docs/multiple-tests/codacy-rules-csharp/src/null-pointer-dereference.cs new file mode 100644 index 0000000..16d82b2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/null-pointer-dereference.cs @@ -0,0 +1,47 @@ +using System; + +namespace Tests.Bugs +{ + class Nulls + { + public void Method() + { + object myObject = null; + Console.WriteLine(myObject.ToString()); // Noncompliant + } + + public void Checked(object input) + { + if (input is null) + { + Console.WriteLine("null input"); + } + Console.WriteLine(input.ToString()); // Noncompliant + } + + public void Guarded(object input) + { + if (input == null) + { + return; + } + Console.WriteLine(input.ToString()); + } + + public void Reassigned() + { + object o = null; + o = new object(); + Console.WriteLine(o.ToString()); + } + + public void Conditional() + { + string s = null; + if (s != null) + { + Console.WriteLine(s.Length); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/null-returned-for-collection.cs b/docs/multiple-tests/codacy-rules-csharp/src/null-returned-for-collection.cs new file mode 100644 index 0000000..39d0636 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/null-returned-for-collection.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace Tests.Practices +{ + public class Result { } + + public class Results + { + public Result[] GetResults() + { + return null; // Noncompliant + } + + public IEnumerable GetResults(bool condition) + { + if (condition) + { + return null; // Noncompliant + } + return new List(); + } + + public string GetName() + { + return null; + } + + public Result GetOne() + { + return null; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/null-returned-from-task-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/null-returned-from-task-method.cs new file mode 100644 index 0000000..178d3fa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/null-returned-from-task-method.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + class Tasks + { + public Task DoFooAsync() + { + return null; // Noncompliant + } + + public Task GetFooAsync() + { + return null; // Noncompliant + } + + public async Task GetBarAsync() + { + await Task.Delay(1); + return null; + } + + public Task Fine() + { + return Task.CompletedTask; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nullable-gettype-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/nullable-gettype-comparison.cs new file mode 100644 index 0000000..804726f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nullable-gettype-comparison.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tests.Bugs +{ + class Nullables + { + void DoChecks(Nullable value) where T : struct + { + bool areEqual = value.GetType() == typeof(Nullable); // Noncompliant + bool other = value.GetType() != typeof(int?); // Noncompliant + bool fine = value.GetType() == typeof(int); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/nullable-value-without-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/nullable-value-without-check.cs new file mode 100644 index 0000000..aa9726f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/nullable-value-without-check.cs @@ -0,0 +1,28 @@ +using System; + +namespace Tests.Bugs +{ + class Nullables + { + void Sample(bool condition) + { + int? nullableValue = condition ? 42 : null; + Console.WriteLine(nullableValue.Value); // Noncompliant + } + + void Checked(bool condition) + { + int? nullableValue = condition ? 42 : null; + if (nullableValue.HasValue) + { + Console.WriteLine(nullableValue.Value); + } + } + + void Direct() + { + int? empty = null; + Console.WriteLine(empty.Value); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/object-created-and-dropped.cs b/docs/multiple-tests/codacy-rules-csharp/src/object-created-and-dropped.cs new file mode 100644 index 0000000..c72fbd3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/object-created-and-dropped.cs @@ -0,0 +1,22 @@ +namespace Tests.Bugs +{ + class MyObject + { + public bool IsCorrupted { get; set; } + } + + class Creator + { + public void Method(MyObject myObject) + { + if (myObject is null) + { + new MyObject(); // Noncompliant + } + var other = new MyObject(); + Use(new MyObject()); + } + + void Use(MyObject o) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/object-disposed-twice.cs b/docs/multiple-tests/codacy-rules-csharp/src/object-disposed-twice.cs new file mode 100644 index 0000000..b677f14 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/object-disposed-twice.cs @@ -0,0 +1,29 @@ +using System.IO; + +namespace Tests.Bugs +{ + class Disposable : System.IDisposable + { + public void Dispose() { } + } + + class Twice + { + void M() + { + var foo = new Disposable(); + foo.Dispose(); + foo.Dispose(); // Noncompliant + + using (var bar = new Disposable()) + { + bar.Dispose(); // Noncompliant + } + + var baz = new Disposable(); + baz.Dispose(); + baz = new Disposable(); + baz.Dispose(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/obsolete-without-explanation.cs b/docs/multiple-tests/codacy-rules-csharp/src/obsolete-without-explanation.cs new file mode 100644 index 0000000..504218f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/obsolete-without-explanation.cs @@ -0,0 +1,16 @@ +using System; + +namespace Tests.Practices +{ + public class Car + { + [Obsolete] // Noncompliant + public void CrankEngine(int turnsOfCrank) { } + + [Obsolete("Use Start() instead")] + public void Crank() { } + + [Serializable, Obsolete()] // Noncompliant + public class Old { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/one-way-operation-returns-value.cs b/docs/multiple-tests/codacy-rules-csharp/src/one-way-operation-returns-value.cs new file mode 100644 index 0000000..851cb8b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/one-way-operation-returns-value.cs @@ -0,0 +1,14 @@ +using System.ServiceModel; + +namespace Tests.Practices +{ + [ServiceContract] + interface IMyService + { + [OperationContract(IsOneWay = true)] + int SomethingHappened(int parameter); // Noncompliant + + [OperationContract(IsOneWay = true)] + void Notify(int parameter); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/operator-without-named-alternative.cs b/docs/multiple-tests/codacy-rules-csharp/src/operator-without-named-alternative.cs new file mode 100644 index 0000000..2872d4a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/operator-without-named-alternative.cs @@ -0,0 +1,10 @@ +namespace Tests.Practices +{ + public class Calculator + { + public static Calculator operator +(Calculator a, Calculator b) // Noncompliant + { + return a; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/optional-field-without-deserialization-handler.cs b/docs/multiple-tests/codacy-rules-csharp/src/optional-field-without-deserialization-handler.cs new file mode 100644 index 0000000..8b49b0d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/optional-field-without-deserialization-handler.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; + +namespace Tests.Bugs +{ + [Serializable] + public class Foo // Noncompliant + { + [OptionalField(VersionAdded = 2)] + int optionalField = 5; + } + + [Serializable] + public class Bar + { + [OptionalField(VersionAdded = 2)] + int optionalField = 5; + + [OnDeserializing] + private void OnDeserializing(StreamingContext context) + { + optionalField = 5; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/optional-on-ref-or-out-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/optional-on-ref-or-out-parameter.cs new file mode 100644 index 0000000..a4fc620 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/optional-on-ref-or-out-parameter.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Bugs +{ + class MyClass + { + public void DoStuff([Optional] ref int i) // Noncompliant + { + Console.WriteLine(i); + } + + public void Fine([Optional] int i) + { + Console.WriteLine(i); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/optional-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/optional-parameter.cs new file mode 100644 index 0000000..bf569aa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/optional-parameter.cs @@ -0,0 +1,17 @@ +namespace Tests.Practices +{ + public class Notifier + { + public void Notify(string company, string office = "QJZ") // Noncompliant + { + } + + private void Internal(string company, string office = "QJZ") + { + } + + public void Overload(string company) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/orderby-before-where.cs b/docs/multiple-tests/codacy-rules-csharp/src/orderby-before-where.cs new file mode 100644 index 0000000..c942223 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/orderby-before-where.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Queries + { + public IEnumerable GetSortedFilteredList(IEnumerable data) => + data.OrderBy(x => x).Where(x => x % 2 == 0); // Noncompliant + + public IEnumerable Good(IEnumerable data) => + data.Where(x => x % 2 == 0).OrderBy(x => x); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/os-command-from-path.cs b/docs/multiple-tests/codacy-rules-csharp/src/os-command-from-path.cs new file mode 100644 index 0000000..3446196 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/os-command-from-path.cs @@ -0,0 +1,16 @@ +using System.Diagnostics; + +namespace Tests.Security +{ + class Commands + { + void M() + { + Process p = new Process(); + p.StartInfo.FileName = "binary"; // Noncompliant + Process.Start("git", "status"); // Noncompliant + Process.Start("/usr/bin/git", "status"); + var info = new ProcessStartInfo(@"C:\Tools\tool.exe"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/out-or-ref-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/out-or-ref-parameter.cs new file mode 100644 index 0000000..5b39250 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/out-or-ref-parameter.cs @@ -0,0 +1,24 @@ +namespace Tests.Practices +{ + public class MyClass { } + + public class Replies + { + public void GetReply( // Noncompliant + ref MyClass input, + out string reply) + { + reply = "x"; + } + + public bool TryParse(string s, out int value) + { + value = 0; + return true; + } + + private void Internal(ref int x) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/outdated-base-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/outdated-base-type.cs new file mode 100644 index 0000000..0912c7a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/outdated-base-type.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections; + +namespace MyLibrary +{ + public class MyCollection : CollectionBase // Noncompliant + { + } + + public class MyError : ApplicationException // Noncompliant + { + } + + internal class InternalCollection : CollectionBase + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/overlapping-overload-defaults.cs b/docs/multiple-tests/codacy-rules-csharp/src/overlapping-overload-defaults.cs new file mode 100644 index 0000000..bcb9289 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/overlapping-overload-defaults.cs @@ -0,0 +1,10 @@ +namespace Tests.Practices +{ + public static class MyClass + { + public static void Print(int number) { } + public static void Print(int number, string delimiter = "\n") { } // Noncompliant + public static void Other(string s) { } + public static void Other(int number, string delimiter = "\n") { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/overridable-call-in-constructor.cs b/docs/multiple-tests/codacy-rules-csharp/src/overridable-call-in-constructor.cs new file mode 100644 index 0000000..085b082 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/overridable-call-in-constructor.cs @@ -0,0 +1,34 @@ +namespace Tests.Bugs +{ + public class Parent + { + public Parent() + { + DoSomething(); // Noncompliant + Helper(); + } + + public virtual void DoSomething() { } + private void Helper() { } + } + + public abstract class Shape + { + protected Shape(int size) : base() + { + this.Draw(); // Noncompliant + } + + protected abstract void Draw(); + } + + public sealed class Closed + { + public Closed() + { + Helper(); + } + + private void Helper() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/override-only-calls-base.cs b/docs/multiple-tests/codacy-rules-csharp/src/override-only-calls-base.cs new file mode 100644 index 0000000..974fd52 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/override-only-calls-base.cs @@ -0,0 +1,27 @@ +namespace Tests.Style +{ + public class Base + { + public virtual void Method() { } + public virtual int Compute(int x) { return x; } + public virtual string Describe() { return "base"; } + } + + public class Derived : Base + { + public override void Method() // Noncompliant + { + base.Method(); + } + + public override int Compute(int x) // Noncompliant + { + return base.Compute(x); + } + + public override string Describe() + { + return base.Describe() + "!"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-as-string.cs b/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-as-string.cs new file mode 100644 index 0000000..cecb1fd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-as-string.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Practices +{ + class Exceptions + { + void DoSomething(int someParameter, string anotherParam) + { + if (someParameter < 0) + { + throw new ArgumentException("Bad argument", "someParameter"); // Noncompliant + } + if (anotherParam == null) + { + throw new ArgumentNullException(nameof(anotherParam)); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-differs-from-declaration.cs b/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-differs-from-declaration.cs new file mode 100644 index 0000000..896e531 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/parameter-name-differs-from-declaration.cs @@ -0,0 +1,26 @@ +namespace Tests.Practices +{ + interface IBankAccount + { + void AddMoney(int money); + } + + class BankAccount : IBankAccount + { + public void AddMoney(int amount) // Noncompliant + { + } + } + + interface IOther + { + void Withdraw(int money); + } + + class Other : IOther + { + public void Withdraw(int money) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/parameter-named-like-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/parameter-named-like-method.cs new file mode 100644 index 0000000..14e7761 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/parameter-named-like-method.cs @@ -0,0 +1,18 @@ +namespace Tests.Naming +{ + public class Auth + { + public void Login(string login) // Noncompliant + { + } + + public void Logout(string user, int LOGOUT) // Noncompliant + { + Login(user); + } + + public void Connect(string host) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/parameter-overwritten-before-read.cs b/docs/multiple-tests/codacy-rules-csharp/src/parameter-overwritten-before-read.cs new file mode 100644 index 0000000..efc1b31 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/parameter-overwritten-before-read.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Params + { + public void DoTheThing(string str, int i, List strings) + { + str = i.ToString(i); // Noncompliant + Console.WriteLine(str); + } + + public void Read(string str) + { + str = str.Trim(); + Console.WriteLine(str); + } + + public void Out(out int value) + { + value = 1; + } + + public void Catch() + { + try + { + Console.WriteLine(); + } + catch (Exception e) + { + e = new Exception("x"); // Noncompliant + throw e; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/parameterless-guid-creation.cs b/docs/multiple-tests/codacy-rules-csharp/src/parameterless-guid-creation.cs new file mode 100644 index 0000000..43d0146 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/parameterless-guid-creation.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tests.Practices +{ + class Guids + { + void M() + { + var g1 = new Guid(); // Noncompliant + Guid g2 = new(); // Noncompliant + var g3 = Guid.NewGuid(); + var g4 = Guid.Empty; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/params-added-on-override.cs b/docs/multiple-tests/codacy-rules-csharp/src/params-added-on-override.cs new file mode 100644 index 0000000..f782da9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/params-added-on-override.cs @@ -0,0 +1,20 @@ +namespace Tests.Bugs +{ + class Base + { + public virtual void Method(int[] numbers) + { + } + } + + class Derived : Base + { + public override void Method(params int[] numbers) // Noncompliant + { + } + + public void Other(params int[] numbers) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/part-creation-policy-without-export.cs b/docs/multiple-tests/codacy-rules-csharp/src/part-creation-policy-without-export.cs new file mode 100644 index 0000000..4e6e920 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/part-creation-policy-without-export.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.Composition; + +namespace Tests.Bugs +{ + public interface IFooBar { } + + [PartCreationPolicy(CreationPolicy.Any)] + public class FooBar : IFooBar // Noncompliant + { + } + + [Export(typeof(IFooBar))] + [PartCreationPolicy(CreationPolicy.Any)] + public class Exported : IFooBar + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/permissive-cors-policy.cs b/docs/multiple-tests/codacy-rules-csharp/src/permissive-cors-policy.cs new file mode 100644 index 0000000..8ac3bd0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/permissive-cors-policy.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; + +namespace Tests.Security +{ + public class ValuesController : Controller + { + [HttpGet] + public string Get() + { + Response.Headers.Add("Access-Control-Allow-Origin", "*"); // Noncompliant + Response.Headers.Add("Access-Control-Allow-Origin", "https://trusted.example.com"); + return "value"; + } + } + + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddCors(options => + { + options.AddDefaultPolicy(builder => + { + builder.AllowAnyOrigin(); // Noncompliant + }); + }); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/predictable-initialization-vector.cs b/docs/multiple-tests/codacy-rules-csharp/src/predictable-initialization-vector.cs new file mode 100644 index 0000000..fb0279b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/predictable-initialization-vector.cs @@ -0,0 +1,19 @@ +using System.IO; +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Encryption + { + public void Encrypt(byte[] key, byte[] dataToEncrypt, MemoryStream target) + { + var aes = Aes.Create(); + byte[] iv = new byte[16]; + var encryptor = aes.CreateEncryptor(key, iv); // Noncompliant + + var safe = Aes.Create(); + safe.GenerateIV(); + var good = safe.CreateEncryptor(key, safe.IV); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/predictable-password-salt.cs b/docs/multiple-tests/codacy-rules-csharp/src/predictable-password-salt.cs new file mode 100644 index 0000000..93d7ab4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/predictable-password-salt.cs @@ -0,0 +1,20 @@ +using System.Security.Cryptography; +using System.Text; + +namespace Tests.Security +{ + class Salts + { + public static void Hash(string password) + { + var salt = Encoding.UTF8.GetBytes("salty"); + var hashed = new Rfc2898DeriveBytes(password, salt, 600000, HashAlgorithmName.SHA256); // Noncompliant + } + + public static void Good(string password) + { + var salt = RandomNumberGenerator.GetBytes(32); + var hashed = new Rfc2898DeriveBytes(password, salt, 600000, HashAlgorithmName.SHA256); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/predictable-secure-random-seed.cs b/docs/multiple-tests/codacy-rules-csharp/src/predictable-secure-random-seed.cs new file mode 100644 index 0000000..560c95e --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/predictable-secure-random-seed.cs @@ -0,0 +1,16 @@ +using Org.BouncyCastle.Security; + +namespace Tests.Security +{ + class Seeds + { + void M() + { + byte[] random = new byte[8]; + SecureRandom sr = SecureRandom.GetInstance("SHA256PRNG", false); // Noncompliant + sr.SetSeed(42); // Noncompliant + sr.NextBytes(random); + SecureRandom good = SecureRandom.GetInstance("SHA256PRNG"); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/private-class-not-sealed.cs b/docs/multiple-tests/codacy-rules-csharp/src/private-class-not-sealed.cs new file mode 100644 index 0000000..570aa01 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/private-class-not-sealed.cs @@ -0,0 +1,21 @@ +namespace Tests.Performance +{ + public class Outer + { + private class MyClass // Noncompliant + { + } + + private class BaseClass + { + } + + private sealed class Derived : BaseClass + { + } + + private sealed class AlreadySealed + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/property-getter-throws.cs b/docs/multiple-tests/codacy-rules-csharp/src/property-getter-throws.cs new file mode 100644 index 0000000..08e3358 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/property-getter-throws.cs @@ -0,0 +1,36 @@ +using System; + +namespace Tests.Practices +{ + class Props + { + private int? value; + + public int Foo + { + get + { + throw new Exception(); // Noncompliant + } + } + + public int Value + { + get + { + if (value == null) + { + throw new InvalidOperationException("Not initialized"); + } + return value.Value; + } + } + + public int Bar => throw new ArgumentException("bar"); // Noncompliant + + public int this[int index] + { + get { throw new ArgumentOutOfRangeException(nameof(index)); } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/property-name-matches-get-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/property-name-matches-get-method.cs new file mode 100644 index 0000000..524f072 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/property-name-matches-get-method.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Style +{ + public class Foo + { + public DateTime Date + { + get { return DateTime.Today; } + } + + public string GetDate() // Noncompliant + { + return this.Date.ToString(); + } + + public string GetOther() => "x"; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/property-returns-collection-copy.cs b/docs/multiple-tests/codacy-rules-csharp/src/property-returns-collection-copy.cs new file mode 100644 index 0000000..152a7af --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/property-returns-collection-copy.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Copies + { + private List foo = new List { "a", "b", "c" }; + private string[] bar = new string[] { "a", "b", "c" }; + + public IEnumerable Foo => foo.ToList(); // Noncompliant + + public string[] Bar // Noncompliant + { + get { return bar.ToArray(); } + } + + public IEnumerable Fine => foo.AsReadOnly(); + + public string[] GetBar() => bar.ToArray(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/protected-member-in-sealed-class.cs b/docs/multiple-tests/codacy-rules-csharp/src/protected-member-in-sealed-class.cs new file mode 100644 index 0000000..e991a2f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/protected-member-in-sealed-class.cs @@ -0,0 +1,18 @@ +namespace Tests.Practices +{ + public class Base + { + protected virtual void Hook() { } + } + + public sealed class MySealedClass : Base + { + protected string name = "Fred"; // Noncompliant + protected void SetName(string name) // Noncompliant + { + this.name = name; + } + + protected override void Hook() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/public-constant.cs b/docs/multiple-tests/codacy-rules-csharp/src/public-constant.cs new file mode 100644 index 0000000..0df2d45 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/public-constant.cs @@ -0,0 +1,18 @@ +namespace Tests.Practices +{ + public class Foo + { + public const double Version = 1.0; // Noncompliant + private const double Internal = 2.0; + public static double Version2 => 1.0; + } +} + +namespace Tests.Practices2 +{ + public class Bar + { + public static readonly double NotConstant = 1.0; + public readonly int Field = 3; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/public-constructor-in-abstract-class.cs b/docs/multiple-tests/codacy-rules-csharp/src/public-constructor-in-abstract-class.cs new file mode 100644 index 0000000..970c76d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/public-constructor-in-abstract-class.cs @@ -0,0 +1,20 @@ +namespace Tests.Practices +{ + abstract class Base + { + public Base() // Noncompliant + { + } + + public void Work() + { + } + } + + abstract class Fine + { + protected Fine() + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/public-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/public-field.cs new file mode 100644 index 0000000..19b59a8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/public-field.cs @@ -0,0 +1,22 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Practices +{ + public class Foo + { + public int InstanceData = 32; // Noncompliant + public int AnotherInstanceData; // Noncompliant + public readonly int ReadOnlyData = 1; + public const int Constant = 2; + public static readonly int Shared = 3; + public event EventHandler Changed; + private int hidden; + } + + [StructLayout(LayoutKind.Sequential)] + public class Native + { + public int Value; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/public-static-mutable-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/public-static-mutable-field.cs new file mode 100644 index 0000000..3d33fb4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/public-static-mutable-field.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Tests.Practices +{ + public class A + { + public static string[] strings1 = { "first", "second" }; // Noncompliant + public static readonly List strings3 = new List(); // Noncompliant + public static readonly ReadOnlyCollection fine = new ReadOnlyCollection(new List()); + private static string[] hidden = { "a" }; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/publicly-writable-directory.cs b/docs/multiple-tests/codacy-rules-csharp/src/publicly-writable-directory.cs new file mode 100644 index 0000000..edc3703 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/publicly-writable-directory.cs @@ -0,0 +1,16 @@ +using System; +using System.IO; + +namespace Tests.Security +{ + class Directories + { + void M() + { + using var writer = new StreamWriter("/tmp/f"); // Noncompliant + var tmp = Environment.GetEnvironmentVariable("TMP"); // Noncompliant + var home = Environment.GetEnvironmentVariable("HOME"); + var app = "/var/lib/app/data"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/pure-method-returns-void.cs b/docs/multiple-tests/codacy-rules-csharp/src/pure-method-returns-void.cs new file mode 100644 index 0000000..631b72d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/pure-method-returns-void.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.Contracts; + +namespace Tests.Bugs +{ + class Person + { + private int age; + + [Pure] // Noncompliant@+1 + void ConfigureAge(int age) => + this.age = age; + + [Pure] + int GetAge() => age; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/raw-request-data-in-controller.cs b/docs/multiple-tests/codacy-rules-csharp/src/raw-request-data-in-controller.cs new file mode 100644 index 0000000..05fb6bf --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/raw-request-data-in-controller.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Tests.Web +{ + public class PeopleController : Controller + { + public IActionResult Post() + { + var name = Request.Form["name"]; // Noncompliant + var birthdate = Request.Query["birthdate"]; // Noncompliant + return Ok(name + birthdate); + } + + public IActionResult Bound(string name) + { + return Ok(name); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/readonly-mutable-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/readonly-mutable-field.cs new file mode 100644 index 0000000..0dd7c5a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/readonly-mutable-field.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Tests.Practices +{ + public class MyClass + { + public readonly string[] strings1; // Noncompliant + public readonly List strings2 = new List(); // Noncompliant + private readonly string[] hidden; + public readonly string name; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/recursive-type-inheritance.cs b/docs/multiple-tests/codacy-rules-csharp/src/recursive-type-inheritance.cs new file mode 100644 index 0000000..274cc3a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/recursive-type-inheritance.cs @@ -0,0 +1,14 @@ +namespace Tests.Bugs +{ + class C2 : C2 // Noncompliant + { + } + + class C3 : C3> // Noncompliant + { + } + + class Fine : System.Collections.Generic.List + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-anonymous-property-name.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-anonymous-property-name.cs new file mode 100644 index 0000000..b98990d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-anonymous-property-name.cs @@ -0,0 +1,18 @@ +namespace Tests.Style +{ + public class Anonymous + { + public int Y { get; set; } + + void M(Anonymous other) + { + var X = 5; + var anon = new + { + X = X, // Noncompliant + Y = other.Y, // Noncompliant + Z = "my string" + }; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-boolean-literal.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-boolean-literal.cs new file mode 100644 index 0000000..c0001a7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-boolean-literal.cs @@ -0,0 +1,28 @@ +namespace Tests.Style +{ + public class Booleans + { + void M(bool flag, bool? maybe, int x) + { + if (BooleanMethod() == true) { } // Noncompliant + if (BooleanMethod() == false) { } // Noncompliant + if (BooleanMethod() || false) { } // Noncompliant + DoSomething(!false); // Noncompliant + DoSomething(BooleanMethod() == true); // Noncompliant + flag = BooleanMethod() ? true : false; // Noncompliant + flag = BooleanMethod() ? true : flag; // Noncompliant + flag = BooleanMethod() ? flag : false; // Noncompliant + for (var i = 0; true; i++) // Noncompliant + { + break; + } + if (maybe == true) { } + if (BooleanMethod()) { } + flag = !BooleanMethod(); + flag = x > 3 ? flag : BooleanMethod(); + } + + bool BooleanMethod() { return true; } + void DoSomething(bool b) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-cast.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-cast.cs new file mode 100644 index 0000000..b1050cb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-cast.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Style +{ + class Casts + { + public int Example(int i) + { + return (int)i; // Noncompliant + } + + public IEnumerable ExampleCollection(IEnumerable coll) + { + return coll.Cast(); // Noncompliant + } + + public int Narrow(long l) + { + return (int)l; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-constructor-or-destructor.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-constructor-or-destructor.cs new file mode 100644 index 0000000..779b767 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-constructor-or-destructor.cs @@ -0,0 +1,24 @@ +namespace Tests.Style +{ + class X + { + public X() { } // Noncompliant + static X() { } // Noncompliant + ~X() { } // Noncompliant + public int Value { get; set; } + } + + class Y : X + { + public Y(int parameter) : base() // Noncompliant + { + Value = parameter; + } + } + + class Z + { + public Z() { } + public Z(int value) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-default-initialization.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-default-initialization.cs new file mode 100644 index 0000000..88b6824 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-default-initialization.cs @@ -0,0 +1,22 @@ +using System; + +namespace Tests.Style +{ + class X + { + public int field = 0; // Noncompliant + public object o = null; // Noncompliant + public bool flag = false; // Noncompliant + public double d = 0.0; // Noncompliant + public int field2 = 1; + public const int Zero = 0; + public object MyProperty { get; set; } = null; // Noncompliant + public int? nullable = 0; + + void M() + { + int local = 0; + object other = null; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-double-parentheses.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-double-parentheses.cs new file mode 100644 index 0000000..9314a3b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-double-parentheses.cs @@ -0,0 +1,28 @@ +using System.IO; + +namespace Tests.Style +{ + class Parentheses + { + void M(int y, bool a, int z, TextReader reader) + { + int x = ((y / 2 + 1)); // Noncompliant + if (a && ((z + y > 0))) // Noncompliant + { + x++; + } + if ((a && z > 0) || y > 1) + { + x++; + } + string line; + while ((line = reader.ReadLine()) != null) + { + x++; + } + Use((int)x); + } + + void Use(int v) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-inheritance.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-inheritance.cs new file mode 100644 index 0000000..c037d6f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-inheritance.cs @@ -0,0 +1,16 @@ +namespace Tests.Style +{ + public class MyClass : object // Noncompliant + { + } + + enum MyEnum : int // Noncompliant + { + A + } + + enum Small : byte + { + B + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-jump.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-jump.cs new file mode 100644 index 0000000..5555ef3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-jump.cs @@ -0,0 +1,46 @@ +namespace Tests.Style +{ + public class Jumps + { + void Foo(bool condition1, bool condition2) + { + goto A; // Noncompliant + A: + while (condition1) + { + DoTheThing(); + continue; // Noncompliant + } + if (condition2) + { + return; + } + DoTheThing(); + return; // Noncompliant + } + + void Bar(bool condition) + { + while (condition) + { + if (condition) + { + continue; + } + DoTheThing(); + } + if (condition) + { + return; + } + DoTheThing(); + } + + int Baz() + { + return 1; + } + + void DoTheThing() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-member-initializer.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-member-initializer.cs new file mode 100644 index 0000000..77b900c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-member-initializer.cs @@ -0,0 +1,24 @@ +namespace Tests.Style +{ + class Person + { + int age = 42; // Noncompliant + + public Person(int age) + { + this.age = age; + } + } + + class TwoConstructors + { + int count = 1; + + public TwoConstructors() { } + + public TwoConstructors(int count) + { + this.count = count; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-modifier.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-modifier.cs new file mode 100644 index 0000000..6bcd9d5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-modifier.cs @@ -0,0 +1,27 @@ +namespace Tests.Style +{ + public class MyClass + { + public virtual void Method() + { + } + } + + public sealed class MyOtherClass : MyClass + { + public sealed override void Method() // Noncompliant + { + int x = 1; + checked // Noncompliant + { + Use(x); + } + unchecked + { + x = x + 1; + } + } + + void Use(int x) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-null-check-with-is.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-null-check-with-is.cs new file mode 100644 index 0000000..9a27728 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-null-check-with-is.cs @@ -0,0 +1,14 @@ +namespace Tests.Style +{ + class MyClass { } + + class Checks + { + void M(object x) + { + if (x != null && x is MyClass) { } // Noncompliant + if (x == null || !(x is MyClass)) { } // Noncompliant + if (x is MyClass) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-parentheses-creation.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-parentheses-creation.cs new file mode 100644 index 0000000..cd4379c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-parentheses-creation.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace Tests.Style +{ + [Serializable()] // Noncompliant + public class MyClass + { + public int MyProperty { get; set; } + + public static MyClass CreateNew(int propertyValue) + { + var list = new List() { 1, 2 }; // Noncompliant + var other = new List(10); + return new MyClass() // Noncompliant + { + MyProperty = propertyValue + }; + } + + [Obsolete("Use the other one")] + public static MyClass Create() => new MyClass { MyProperty = 1 }; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-tochararray.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-tochararray.cs new file mode 100644 index 0000000..38b42ec --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-tochararray.cs @@ -0,0 +1,19 @@ +namespace Tests.Performance +{ + class Chars + { + void M() + { + string str = "some string"; + foreach (var c in str.ToCharArray()) // Noncompliant + { + System.Console.Write(c); + } + var first = str.ToCharArray()[0]; // Noncompliant + foreach (var c in str) + { + System.Console.Write(c); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/redundant-tostring.cs b/docs/multiple-tests/codacy-rules-csharp/src/redundant-tostring.cs new file mode 100644 index 0000000..5651756 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/redundant-tostring.cs @@ -0,0 +1,14 @@ +namespace Tests.Style +{ + class Strings + { + void M(int count) + { + var s = "foo"; + var t = "fee fie foe " + s.ToString(); // Noncompliant + var someObject = new object(); + var u = "" + someObject.ToString(); // Noncompliant + var v = "Count: " + count.ToString(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/ref-object-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/ref-object-parameter.cs new file mode 100644 index 0000000..01cd0b4 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/ref-object-parameter.cs @@ -0,0 +1,13 @@ +namespace Tests.Practices +{ + class Refs + { + public void Bar(ref object o1, ref int i) // Noncompliant + { + } + + public void Baz(ref T value) + { + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/reference-equals-value-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/reference-equals-value-type.cs new file mode 100644 index 0000000..e3ac91c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/reference-equals-value-type.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tests.Bugs +{ + static class Refs + { + public static void Method(int a, int b, object c, object d) + { + if (Object.ReferenceEquals(a, b)) // Noncompliant + { + Console.WriteLine("never"); + } + if (ReferenceEquals(c, d)) + { + Console.WriteLine("same"); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/reflection-accessibility-bypass.cs b/docs/multiple-tests/codacy-rules-csharp/src/reflection-accessibility-bypass.cs new file mode 100644 index 0000000..3dd6022 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/reflection-accessibility-bypass.cs @@ -0,0 +1,16 @@ +using System; +using System.Reflection; + +namespace Tests.Practices +{ + class Reflection + { + void M() + { + Type dynClass = Type.GetType("MyInternalClass"); + BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Static; // Noncompliant + MethodInfo dynMethod = dynClass.GetMethod("mymethod", bindingAttr); + var pub = dynClass.GetMethod("Public", BindingFlags.Public | BindingFlags.Instance); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/regex-without-timeout.cs b/docs/multiple-tests/codacy-rules-csharp/src/regex-without-timeout.cs new file mode 100644 index 0000000..6d229fa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/regex-without-timeout.cs @@ -0,0 +1,16 @@ +using System; +using System.Text.RegularExpressions; + +namespace Tests.Security +{ + class Regexes + { + public void RegexPattern(string input) + { + var emailPattern = new Regex(".+@.+", RegexOptions.None); // Noncompliant + var isNumber = Regex.IsMatch(input, "[0-9]+"); // Noncompliant + var withTimeout = new Regex(".+@.+", RegexOptions.None, TimeSpan.FromMilliseconds(100)); + var nonBacktracking = new Regex(".+@.+", RegexOptions.NonBacktracking); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/request-validation-disabled.cs b/docs/multiple-tests/codacy-rules-csharp/src/request-validation-disabled.cs new file mode 100644 index 0000000..add137c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/request-validation-disabled.cs @@ -0,0 +1,19 @@ +using System.Web.Mvc; + +namespace Tests.Security +{ + public class HomeController : Controller + { + [ValidateInput(false)] // Noncompliant + public ActionResult Welcome(string name) + { + return View(); + } + + [ValidateInput(true)] + public ActionResult Safe(string name) + { + return View(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/reserved-enum-member.cs b/docs/multiple-tests/codacy-rules-csharp/src/reserved-enum-member.cs new file mode 100644 index 0000000..4100272 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/reserved-enum-member.cs @@ -0,0 +1,11 @@ +namespace Tests.Practices +{ + public enum Color + { + None, + Red, + Orange, + Yellow, + ReservedColor // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/same-condition-tested-twice.cs b/docs/multiple-tests/codacy-rules-csharp/src/same-condition-tested-twice.cs new file mode 100644 index 0000000..cb23287 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/same-condition-tested-twice.cs @@ -0,0 +1,28 @@ +namespace Tests.Bugs +{ + class Conditions + { + void M(int a, int b, int c) + { + if (a == b) + { + DoTheThing(b); + } + if (a == b) // Noncompliant + { + DoTheThing(c); + } + + if (a == c) + { + a = b; + } + if (a == c) + { + DoTheThing(a); + } + } + + void DoTheThing(int x) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/self-assignment.cs b/docs/multiple-tests/codacy-rules-csharp/src/self-assignment.cs new file mode 100644 index 0000000..38c8747 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/self-assignment.cs @@ -0,0 +1,17 @@ +namespace Tests.Bugs +{ + public class Choice + { + private bool selected; + + public void MakeChoice(bool selected) + { + selected = selected; // Noncompliant + } + + public void Fixed(bool selected) + { + this.selected = selected; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/serialization-handler-signature.cs b/docs/multiple-tests/codacy-rules-csharp/src/serialization-handler-signature.cs new file mode 100644 index 0000000..ec7f4c7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/serialization-handler-signature.cs @@ -0,0 +1,21 @@ +using System; +using System.Runtime.Serialization; + +namespace Tests.Bugs +{ + [Serializable] + public class Foo + { + [OnSerializing] + public void OnSerializing(StreamingContext context) { } // Noncompliant + + [OnSerialized] + int OnSerialized(StreamingContext context) { return 1; } // Noncompliant + + [OnDeserializing] + private void OnDeserializing(StreamingContext context) { } + + [OnDeserialized] + private void OnDeserialized() { } // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/server-certificate-validation-disabled.cs b/docs/multiple-tests/codacy-rules-csharp/src/server-certificate-validation-disabled.cs new file mode 100644 index 0000000..c1172a9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/server-certificate-validation-disabled.cs @@ -0,0 +1,16 @@ +using System.Net; +using System.Net.Http; + +namespace Tests.Security +{ + class Certificates + { + public static void Connect() + { + ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => true; // Noncompliant + var handler = new HttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; // Noncompliant + var safe = new HttpClientHandler(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/service-contract-without-operations.cs b/docs/multiple-tests/codacy-rules-csharp/src/service-contract-without-operations.cs new file mode 100644 index 0000000..a28dfc2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/service-contract-without-operations.cs @@ -0,0 +1,17 @@ +using System.ServiceModel; + +namespace Tests.Bugs +{ + [ServiceContract] + interface IMyService // Noncompliant + { + int MyServiceMethod(); + } + + [ServiceContract] + interface IGoodService + { + [OperationContract] + int MyServiceMethod(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/setter-ignores-value.cs b/docs/multiple-tests/codacy-rules-csharp/src/setter-ignores-value.cs new file mode 100644 index 0000000..bdc34bd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/setter-ignores-value.cs @@ -0,0 +1,27 @@ +using System; + +namespace Tests.Bugs +{ + class Props + { + private int count; + public int Count + { + get { return count; } + set { count = 42; } // Noncompliant + } + + private int other; + public int Other + { + get { return other; } + set { other = value; } + } + + public int ReadOnly + { + get { return 1; } + set { throw new NotSupportedException(); } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/shared-part-instantiated.cs b/docs/multiple-tests/codacy-rules-csharp/src/shared-part-instantiated.cs new file mode 100644 index 0000000..ef11d1b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/shared-part-instantiated.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.Composition; + +namespace Tests.Bugs +{ + [Export(typeof(IFooBar))] + [PartCreationPolicy(CreationPolicy.Shared)] + public class FooBar : IFooBar + { + } + + public interface IFooBar { } + + public class Program + { + public static void Main() + { + var fooBar = new FooBar(); // Noncompliant + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/side-effect-in-debug-assert.cs b/docs/multiple-tests/codacy-rules-csharp/src/side-effect-in-debug-assert.cs new file mode 100644 index 0000000..9d84178 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/side-effect-in-debug-assert.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Diagnostics; + +namespace Tests.Bugs +{ + class Asserts + { + void M(List list, int i) + { + Debug.Assert(list.Remove("dog")); // Noncompliant + Debug.Assert(i++ > 0); // Noncompliant + Debug.Assert(list.Contains("dog")); + bool removed = list.Remove("cat"); + Debug.Assert(removed); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/simplify-conditional.cs b/docs/multiple-tests/codacy-rules-csharp/src/simplify-conditional.cs new file mode 100644 index 0000000..e8d6969 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/simplify-conditional.cs @@ -0,0 +1,49 @@ +namespace Tests.Style +{ + public class Conditions + { + void M(object a, object b, bool condition) + { + object x; + if (a != null) // Noncompliant + { + x = a; + } + else + { + x = b; + } + + x = a != null ? a : b; // Noncompliant + x = (a == null) ? new object() : a; // Noncompliant + + if (condition) // Noncompliant + { + x = a; + } + else + { + x = b; + } + + if (a == null) // Noncompliant + a = new object(); + + a = a ?? new object(); // Noncompliant + + if (a == null) + { + a = new object(); + } + else + { + Use(a); + } + + x = a ?? b; + x = condition ? a : b; + } + + void Use(object o) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/simplify-linq-expression.cs b/docs/multiple-tests/codacy-rules-csharp/src/simplify-linq-expression.cs new file mode 100644 index 0000000..240c42c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/simplify-linq-expression.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Style +{ + class Car { } + + class Linq + { + void M(List seq, List numbers) + { + var result1 = seq.Select(x => x as Car).Any(x => x != null); // Noncompliant + var result4 = seq.Where(x => x is Car).Select(x => (Car)x); // Noncompliant + var any = numbers.Where(n => n > 3).Any(); // Noncompliant + var fine = numbers.Any(n => n > 3); + var cars = seq.OfType(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/simplify-type-check.cs b/docs/multiple-tests/codacy-rules-csharp/src/simplify-type-check.cs new file mode 100644 index 0000000..54ecefb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/simplify-type-check.cs @@ -0,0 +1,14 @@ +namespace Tests.Style +{ + class Apple { } + + class TypeChecks + { + void M(object f) + { + if (f as Apple != null) { } // Noncompliant + if (typeof(Apple).IsInstanceOfType(f)) { } // Noncompliant + if (f is Apple) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/sql-keyword-without-whitespace.cs b/docs/multiple-tests/codacy-rules-csharp/src/sql-keyword-without-whitespace.cs new file mode 100644 index 0000000..0a77e0f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/sql-keyword-without-whitespace.cs @@ -0,0 +1,16 @@ +namespace Tests.Bugs +{ + class Sql + { + void M() + { + string select = "SELECT p.FirstName, p.LastName, p.PhoneNumber" + + "FROM Person as p" + // Noncompliant + "WHERE p.Id = @Id"; // Noncompliant + string ok = "SELECT p.FirstName " + + "FROM Person as p " + + "WHERE p.Id = @Id"; + string text = "Hello" + "World"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/stateful-azure-function.cs b/docs/multiple-tests/codacy-rules-csharp/src/stateful-azure-function.cs new file mode 100644 index 0000000..5c3c3ee --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/stateful-azure-function.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Extensions.Logging; + +namespace Tests.Azure +{ + public static class HttpExample + { + private static readonly int port = 2000; + private static int numOfRequests = 1; + + [FunctionName("HttpExample")] + public static async Task Run(HttpRequest request, ILogger log) + { + numOfRequests += 1; // Noncompliant + log.LogInformation($"Number of POST requests is {numOfRequests}."); + string responseMessage = $"HttpRequest was made on port {port}."; + await Task.Yield(); + return new OkObjectResult(responseMessage); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-constructor-only-initializes-fields.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-constructor-only-initializes-fields.cs new file mode 100644 index 0000000..9326349 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-constructor-only-initializes-fields.cs @@ -0,0 +1,27 @@ +namespace Tests.Performance +{ + public class Foo + { + static int i; + static string s; + + static Foo() // Noncompliant + { + i = 3; + s = "x"; + } + } + + public class Bar + { + static int i; + + static Bar() + { + if (System.Environment.ProcessorCount > 2) + { + i = 1; + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-field-assigned-in-constructor.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-field-assigned-in-constructor.cs new file mode 100644 index 0000000..f26ea58 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-field-assigned-in-constructor.cs @@ -0,0 +1,23 @@ +using System; + +namespace Tests.Bugs +{ + public class Person + { + private static DateTime dateOfBirth; + private static int expectedFingers; + private int age; + + public Person(DateTime birthday) + { + dateOfBirth = birthday; // Noncompliant + expectedFingers = 10; // Noncompliant + age = 1; + } + + static Person() + { + expectedFingers = 10; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-field-in-generic-type.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-field-in-generic-type.cs new file mode 100644 index 0000000..2197524 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-field-in-generic-type.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + public class LengthLimitedSingletonCollection where T : new() + { + protected const int MaxAllowedLength = 5; + protected static Dictionary instances = new Dictionary(); // Noncompliant + private static Dictionary cache = new Dictionary(); + private static int counter; // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-field-initialization-order.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-field-initialization-order.cs new file mode 100644 index 0000000..fb90ea2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-field-initialization-order.cs @@ -0,0 +1,14 @@ +namespace Tests.Bugs +{ + class MyClass + { + public static int X = Y; // Noncompliant + public static int Y = 42; + + public static int A = 1; + public static int B = A + 1; + + public static int C = D; + public const int D = 3; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-field-written-from-instance.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-field-written-from-instance.cs new file mode 100644 index 0000000..ad35263 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-field-written-from-instance.cs @@ -0,0 +1,19 @@ +namespace Tests.Bugs +{ + class MyClass + { + private static int count = 0; + private static string name; + + public void DoSomething() + { + count++; // Noncompliant + name = "x"; // Noncompliant + } + + public static void Reset() + { + count = 0; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/static-readonly-could-be-const.cs b/docs/multiple-tests/codacy-rules-csharp/src/static-readonly-could-be-const.cs new file mode 100644 index 0000000..fa85529 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/static-readonly-could-be-const.cs @@ -0,0 +1,10 @@ +namespace Tests.Performance +{ + public class Foo + { + static readonly int x = 1; // Noncompliant + static readonly string name = "x"; // Noncompliant + static readonly int y = x + 4; + static readonly object sync = new object(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/stream-read-result-ignored.cs b/docs/multiple-tests/codacy-rules-csharp/src/stream-read-result-ignored.cs new file mode 100644 index 0000000..7ecbcad --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/stream-read-result-ignored.cs @@ -0,0 +1,24 @@ +using System.IO; +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + class Reads + { + public byte[] ReadFile(string fileName) + { + using var stream = File.Open(fileName, FileMode.Open); + var result = new byte[stream.Length]; + stream.Read(result, 0, (int)stream.Length); // Noncompliant + return result; + } + + public async Task ReadAsync(Stream stream) + { + var buffer = new byte[16]; + await stream.ReadAsync(buffer, 0, 16); // Noncompliant + int read = stream.Read(buffer, 0, 16); + return buffer; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/string-concatenation-in-loop.cs b/docs/multiple-tests/codacy-rules-csharp/src/string-concatenation-in-loop.cs new file mode 100644 index 0000000..8565b70 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/string-concatenation-in-loop.cs @@ -0,0 +1,24 @@ +namespace Tests.Performance +{ + class Concat + { + string Join(string[] arrayOfStrings) + { + string str = ""; + for (int i = 0; i < arrayOfStrings.Length; ++i) + { + str = str + arrayOfStrings[i]; // Noncompliant + } + foreach (var s in arrayOfStrings) + { + str += s; // Noncompliant + } + int total = 0; + foreach (var s in arrayOfStrings) + { + total += s.Length; + } + return str + total; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/string-literal-for-localizable-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/string-literal-for-localizable-parameter.cs new file mode 100644 index 0000000..3aec76d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/string-literal-for-localizable-parameter.cs @@ -0,0 +1,22 @@ +using System.Windows.Forms; + +namespace MyLibrary +{ + public class Foo + { + public void SetHour(int hour, Label label) + { + if (hour < 0 || hour > 23) + { + MessageBox.Show("The valid range is 0 - 23."); // Noncompliant + } + label.Text = "Hour selected"; // Noncompliant + MessageBox.Show(Resources.Message); + } + } + + public static class Resources + { + public static string Message => "x"; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/string-overload-for-single-char.cs b/docs/multiple-tests/codacy-rules-csharp/src/string-overload-for-single-char.cs new file mode 100644 index 0000000..050eb90 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/string-overload-for-single-char.cs @@ -0,0 +1,17 @@ +namespace Tests.Performance +{ + class Chars + { + bool StartsWithSlash(string s) => + s.StartsWith("/"); // Noncompliant + + bool EndsWithSlash(string s) => + s.EndsWith("/"); // Noncompliant + + bool StartsWithChar(string s) => + s.StartsWith('/'); + + bool StartsWithPrefix(string s) => + s.StartsWith("//"); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/string-uri-overload-not-delegating.cs b/docs/multiple-tests/codacy-rules-csharp/src/string-uri-overload-not-delegating.cs new file mode 100644 index 0000000..4b45491 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/string-uri-overload-not-delegating.cs @@ -0,0 +1,27 @@ +using System; + +namespace MyLibrary +{ + public class MyClass + { + public void FetchResource(string uriString) // Noncompliant + { + Console.WriteLine(uriString); + } + + public void FetchResource(Uri uri) + { + Console.WriteLine(uri); + } + + public void Download(string url) + { + Download(new Uri(url)); + } + + public void Download(Uri url) + { + Console.WriteLine(url); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/stringbuilder-never-read.cs b/docs/multiple-tests/codacy-rules-csharp/src/stringbuilder-never-read.cs new file mode 100644 index 0000000..a3da8f5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/stringbuilder-never-read.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Text; + +namespace Tests.Performance +{ + class Builders + { + public void DoSomething(List strings) + { + var sb = new StringBuilder(); // Noncompliant + sb.Append("Got: "); + foreach (var str in strings) + { + sb.Append(str).Append(", "); + } + } + + public string Used(List strings) + { + var sb = new StringBuilder(); + foreach (var str in strings) + { + sb.Append(str); + } + return sb.ToString(); + } + + public void Passed() + { + var sb = new StringBuilder(); + sb.Append("x"); + Write(sb); + } + + void Write(StringBuilder sb) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/struct-without-iequatable.cs b/docs/multiple-tests/codacy-rules-csharp/src/struct-without-iequatable.cs new file mode 100644 index 0000000..060aa25 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/struct-without-iequatable.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tests.Performance +{ + struct MyStruct // Noncompliant + { + public int Value { get; set; } + } + + struct Proper : IEquatable + { + public int Value { get; set; } + public bool Equals(Proper other) => Value == other.Value; + } + + ref struct SpanLike + { + public int Value; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/substring-before-indexof.cs b/docs/multiple-tests/codacy-rules-csharp/src/substring-before-indexof.cs new file mode 100644 index 0000000..b434abf --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/substring-before-indexof.cs @@ -0,0 +1,15 @@ +namespace Tests.Performance +{ + class Substrings + { + void M(string str, int startIndex, char char1) + { + if (str.Substring(startIndex).IndexOf(char1) == -1) // Noncompliant + { + } + if (str.IndexOf(char1, startIndex) == -1) + { + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-outside-dispose.cs b/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-outside-dispose.cs new file mode 100644 index 0000000..551a820 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-outside-dispose.cs @@ -0,0 +1,25 @@ +using System; + +namespace Tests.Bugs +{ + class Resource : IDisposable + { + public void Dispose() + { + GC.SuppressFinalize(this); + } + + public void Close() + { + GC.SuppressFinalize(this); // Noncompliant + } + } + + class Explicit : IDisposable + { + void IDisposable.Dispose() + { + GC.SuppressFinalize(this); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-without-finalizer.cs b/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-without-finalizer.cs new file mode 100644 index 0000000..ae00eae --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/suppress-finalize-without-finalizer.cs @@ -0,0 +1,22 @@ +using System; + +namespace Tests.Practices +{ + sealed class MyClass : IDisposable + { + public void Dispose() + { + GC.SuppressFinalize(this); //Noncompliant + } + } + + sealed class WithFinalizer : IDisposable + { + public void Dispose() + { + GC.SuppressFinalize(this); + } + + ~WithFinalizer() { Dispose(); } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/switch-too-few-cases.cs b/docs/multiple-tests/codacy-rules-csharp/src/switch-too-few-cases.cs new file mode 100644 index 0000000..08df5be --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/switch-too-few-cases.cs @@ -0,0 +1,48 @@ +namespace Tests.Style +{ + public class Switches + { + int M(int variable) + { + switch (variable) // Noncompliant + { + case 0: + DoSomething(); + break; + default: + DoSomethingElse(); + break; + } + + switch (variable) + { + case 0: + DoSomething(); + break; + case 1: + DoSomething(); + break; + default: + DoSomethingElse(); + break; + } + + var foo = variable switch // Noncompliant + { + 0 => 1, + _ => 2, + }; + + var bar = variable switch + { + 0 => 1, + 1 => 3, + _ => 2, + }; + return foo + bar; + } + + void DoSomething() { } + void DoSomethingElse() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/switch-without-default.cs b/docs/multiple-tests/codacy-rules-csharp/src/switch-without-default.cs new file mode 100644 index 0000000..5b4a229 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/switch-without-default.cs @@ -0,0 +1,29 @@ +using System; + +namespace Tests.Bugs +{ + public class Switches + { + void M(int foo) + { + switch (foo) // Noncompliant + { + case 0: + Console.WriteLine("foo = 0"); + break; + case 42: + Console.WriteLine("foo = 42"); + break; + } + + switch (foo) + { + case 0: + Console.WriteLine("foo = 0"); + break; + default: + throw new InvalidOperationException("Unexpected value"); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/tab-characters.cs b/docs/multiple-tests/codacy-rules-csharp/src/tab-characters.cs new file mode 100644 index 0000000..1185b49 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/tab-characters.cs @@ -0,0 +1,8 @@ +namespace Tests.Layout +{ + public class Tabs + { + private int a; // Noncompliant + private int b; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/temporal-type-as-primary-key.cs b/docs/multiple-tests/codacy-rules-csharp/src/temporal-type-as-primary-key.cs new file mode 100644 index 0000000..e517d5b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/temporal-type-as-primary-key.cs @@ -0,0 +1,30 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Tests.Bugs +{ + internal class Account + { + public DateTime Id { get; set; } // Noncompliant + public string Name { get; set; } + } + + internal class Person + { + [Key] + public DateTime PersonIdentifier { get; set; } // Noncompliant + public string Name { get; set; } + } + + internal class Order + { + public DateTime OrderId { get; set; } // Noncompliant + public DateTime CreatedAt { get; set; } + } + + internal class Product + { + public int Id { get; set; } + public DateTime Created { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/test-class-without-tests.cs b/docs/multiple-tests/codacy-rules-csharp/src/test-class-without-tests.cs new file mode 100644 index 0000000..133d991 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/test-class-without-tests.cs @@ -0,0 +1,31 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class SomeOtherClassTest // Noncompliant + { + } + + [TestClass] + public class RealTest + { + [TestMethod] + public void Works() + { + Assert.IsTrue(true); + } + } + + [TestClass] + public abstract class BaseTest + { + } + + [TestClass] + public class Setup + { + [AssemblyInitialize] + public static void Init(TestContext context) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/test-without-assertion.cs b/docs/multiple-tests/codacy-rules-csharp/src/test-without-assertion.cs new file mode 100644 index 0000000..713de26 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/test-without-assertion.cs @@ -0,0 +1,38 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class CalculatorTest + { + [TestMethod] + public void Add_SingleNumber_ReturnsSameNumber() // Noncompliant + { + var stringCalculator = new StringCalculator(); + var actual = stringCalculator.Add("0"); + } + + [TestMethod] + public void Add_WithAssert() + { + var stringCalculator = new StringCalculator(); + var actual = stringCalculator.Add("0"); + Assert.AreEqual(0, actual); + } + + [TestMethod] + public void Add_Nested() + { + var calculator = new StringCalculator(); + foreach (var input in new[] { "0", "1" }) + { + Assert.IsTrue(calculator.Add(input) >= 0); + } + } + } + + public class StringCalculator + { + public int Add(string s) => 0; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/this-exposed-from-constructor.cs b/docs/multiple-tests/codacy-rules-csharp/src/this-exposed-from-constructor.cs new file mode 100644 index 0000000..5a470a7 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/this-exposed-from-constructor.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + public class Monument + { + public static readonly List ALL_MONUMENTS = new List(); + private readonly string location; + + public Monument(string location, Registry registry) + { + ALL_MONUMENTS.Add(this); // Noncompliant + registry.Owner = this; // Noncompliant + this.location = location; + } + + public void Register() + { + ALL_MONUMENTS.Add(this); + } + } + + public class Registry + { + public Monument Owner { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/thread-sleep-in-test.cs b/docs/multiple-tests/codacy-rules-csharp/src/thread-sleep-in-test.cs new file mode 100644 index 0000000..bfa297f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/thread-sleep-in-test.cs @@ -0,0 +1,21 @@ +using System.Threading; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tests.Practices +{ + [TestClass] + public class SleepTests + { + [TestMethod] + public void SomeTest() + { + Thread.Sleep(500); // Noncompliant + Assert.IsTrue(true); + } + + public void Helper() + { + Thread.Sleep(10); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/thread-suspend-resume.cs b/docs/multiple-tests/codacy-rules-csharp/src/thread-suspend-resume.cs new file mode 100644 index 0000000..467caf8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/thread-suspend-resume.cs @@ -0,0 +1,14 @@ +using System.Threading; + +namespace Tests.Bugs +{ + class Threads + { + void M(Thread thread) + { + thread.Suspend(); // Noncompliant + thread.Resume(); // Noncompliant + thread.Join(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-field-initialized.cs b/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-field-initialized.cs new file mode 100644 index 0000000..da023e9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-field-initialized.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tests.Bugs +{ + public class Foo + { + [ThreadStatic] + public static object PerThreadObject = new object(); // Noncompliant + + [ThreadStatic] + private static object lazy; + + public static object Lazy => lazy ??= new object(); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-on-instance-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-on-instance-field.cs new file mode 100644 index 0000000..2de7f86 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/threadstatic-on-instance-field.cs @@ -0,0 +1,13 @@ +using System; + +namespace Tests.Bugs +{ + public class MyClass + { + [ThreadStatic] // Noncompliant@+1 + private int count = 0; + + [ThreadStatic] + private static int staticCount; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finalizer.cs b/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finalizer.cs new file mode 100644 index 0000000..0569149 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finalizer.cs @@ -0,0 +1,18 @@ +using System; + +namespace Tests.Bugs +{ + class MyClass + { + ~MyClass() + { + Cleanup(); + throw new NotImplementedException(); // Noncompliant + } + + void Cleanup() + { + throw new InvalidOperationException(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finally.cs b/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finally.cs new file mode 100644 index 0000000..3b132ff --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/throw-in-finally.cs @@ -0,0 +1,38 @@ +using System; + +namespace Tests.Bugs +{ + class Finally + { + void M() + { + try + { + throw new ArgumentException(); + } + finally + { + Cleanup(); + throw new InvalidOperationException(); // Noncompliant + } + } + + void N() + { + try + { + Cleanup(); + } + catch (ArgumentException) + { + throw new InvalidOperationException(); + } + finally + { + Cleanup(); + } + } + + void Cleanup() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/todo-tag.cs b/docs/multiple-tests/codacy-rules-csharp/src/todo-tag.cs new file mode 100644 index 0000000..8e59cd1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/todo-tag.cs @@ -0,0 +1,15 @@ +namespace Tests.Practices +{ + public class Todos + { + private void DoSomething() + { + // TODO // Noncompliant + } + + /* + * TODO: support the new format // Noncompliant + */ + private void Todolist() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/too-many-generic-parameters.cs b/docs/multiple-tests/codacy-rules-csharp/src/too-many-generic-parameters.cs new file mode 100644 index 0000000..2e9edb9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/too-many-generic-parameters.cs @@ -0,0 +1,16 @@ +namespace Tests.Complexity +{ + public class Pair + { + } + + public class Triple // Noncompliant + { + } + + public class Methods + { + public void Foo() { } // Noncompliant + public void Bar() { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/too-many-parameters.cs b/docs/multiple-tests/codacy-rules-csharp/src/too-many-parameters.cs new file mode 100644 index 0000000..5eee899 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/too-many-parameters.cs @@ -0,0 +1,27 @@ +namespace Tests.Complexity +{ + public class BaseClass + { + public BaseClass(int p1) { } + } + + public class Params : BaseClass + { + public Params(int a, int b, int c, int d, int e, int f, int g, int h) : base(a) { } + public Params(int a, int b, int c, int d, int e, int f, int g, int h, int i) : base(a) { } + void SetCoordinates(int x1, int y1, int z1, int x2, int y2, int z2) { } + void Seven(int a, int b, int c, int d, int e, int f, int g) { } + void Eight(int a, int b, int c, int d, int e, int f, int g, int h) { } // Noncompliant + int Arrow(int a, int b, int c, int d, int e, int f, int g, int h) => a; // Noncompliant + } + + public class Plain + { + public Plain(int a, int b, int c, int d, int e, int f, int g, int h) { } // Noncompliant + } + + public interface IWide + { + void Wide(int a, int b, int c, int d, int e, int f, int g, int h); // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/tostring-returns-null.cs b/docs/multiple-tests/codacy-rules-csharp/src/tostring-returns-null.cs new file mode 100644 index 0000000..b35596d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/tostring-returns-null.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Tests.Bugs +{ + class Items + { + private List collection = new List(); + + public override string ToString() + { + if (this.collection.Count == 0) + { + return null; // Noncompliant + } + return string.Join(",", collection); + } + } + + class Empty + { + public override string ToString() => null; // Noncompliant + } + + class Fine + { + public override string ToString() => string.Empty; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/trace-write.cs b/docs/multiple-tests/codacy-rules-csharp/src/trace-write.cs new file mode 100644 index 0000000..ef53fd3 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/trace-write.cs @@ -0,0 +1,23 @@ +using System; +using System.Diagnostics; + +namespace Tests.Practices +{ + class Tracing + { + void M() + { + try + { + var message = Retrieve(); + Trace.Write($"Message received: {message}"); // Noncompliant + } + catch (Exception ex) + { + Trace.TraceError(ex.Message); + } + } + + string Retrieve() => "x"; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/trace-writelineif-with-traceswitch.cs b/docs/multiple-tests/codacy-rules-csharp/src/trace-writelineif-with-traceswitch.cs new file mode 100644 index 0000000..65623c8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/trace-writelineif-with-traceswitch.cs @@ -0,0 +1,17 @@ +using System.Diagnostics; + +namespace Tests.Practices +{ + class Switches + { + void M(TraceSwitch traceSwitch) + { + Trace.WriteLineIf(traceSwitch.TraceError, "An error occurred."); // Noncompliant + Trace.WriteLineIf(traceSwitch.TraceWarning, "A warning occurred."); // Noncompliant + if (traceSwitch.TraceError) + { + Trace.TraceError("An error occurred."); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/trivial-property.cs b/docs/multiple-tests/codacy-rules-csharp/src/trivial-property.cs new file mode 100644 index 0000000..9d94756 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/trivial-property.cs @@ -0,0 +1,22 @@ +namespace Tests.Style +{ + public class Car + { + private string _make; + public string Make // Noncompliant + { + get { return _make; } + set { _make = value; } + } + + private int _speed; + public int Speed + { + get { return _speed; } + set { _speed = value < 0 ? 0 : value; } + } + + private string _model; + public string Model { get => _model; set => _model = value; } // Noncompliant + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/type-check-on-this.cs b/docs/multiple-tests/codacy-rules-csharp/src/type-check-on-this.cs new file mode 100644 index 0000000..c6559e2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/type-check-on-this.cs @@ -0,0 +1,17 @@ +namespace Tests.Practices +{ + public class Food + { + public void DoSomething() + { + if (this is Pizza) // Noncompliant + { + Bake(); + } + } + + void Bake() { } + } + + public class Pizza : Food { } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/type-name-matches-namespace.cs b/docs/multiple-tests/codacy-rules-csharp/src/type-name-matches-namespace.cs new file mode 100644 index 0000000..68d59cd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/type-name-matches-namespace.cs @@ -0,0 +1,14 @@ +namespace Tests.Naming +{ + public class Text // Noncompliant + { + } + + public class TextFormatter + { + } + + public interface Collections // Noncompliant + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/type-outside-namespace.cs b/docs/multiple-tests/codacy-rules-csharp/src/type-outside-namespace.cs new file mode 100644 index 0000000..da6e86b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/type-outside-namespace.cs @@ -0,0 +1,18 @@ +public class Foo // Noncompliant +{ + public class Nested + { + } +} + +public enum Bar // Noncompliant +{ + A +} + +namespace Tests.Practices +{ + public class Inside + { + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/type-parameter-not-inferable.cs b/docs/multiple-tests/codacy-rules-csharp/src/type-parameter-not-inferable.cs new file mode 100644 index 0000000..32fd799 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/type-parameter-not-inferable.cs @@ -0,0 +1,18 @@ +namespace Tests.Practices +{ + public class Generics + { + public void MyMethod() // Noncompliant + { + } + + public void Inferred(T value) + { + } + + void Caller() + { + MyMethod(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/type-pascal-case.cs b/docs/multiple-tests/codacy-rules-csharp/src/type-pascal-case.cs new file mode 100644 index 0000000..265865a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/type-pascal-case.cs @@ -0,0 +1,17 @@ +namespace Tests.Naming +{ + class my_class { } // Noncompliant + class SOMEName42 { } // Noncompliant + class SomeName42 { } + class MyXClass { } + class XC { } // Noncompliant + interface IFoo { } + interface IXmlParser { } + interface iFoo { } // Noncompliant + struct point { } // Noncompliant + struct Point { } + enum colors { Red } // Noncompliant + enum Color { Red } + record person(string Name); // Noncompliant + record Person(string Name); +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unassigned-field.cs b/docs/multiple-tests/codacy-rules-csharp/src/unassigned-field.cs new file mode 100644 index 0000000..b208e64 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unassigned-field.cs @@ -0,0 +1,16 @@ +namespace Tests.Practices +{ + class MyClass + { + private int field; // Noncompliant + private int assigned; + private string initialized = "x"; + + public MyClass(int value) + { + assigned = value; + } + + public int Sum() => field + assigned + initialized.Length; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unauthenticated-ldap-connection.cs b/docs/multiple-tests/codacy-rules-csharp/src/unauthenticated-ldap-connection.cs new file mode 100644 index 0000000..c0f21af --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unauthenticated-ldap-connection.cs @@ -0,0 +1,15 @@ +using System.DirectoryServices; + +namespace Tests.Security +{ + class Ldap + { + void M(string adPath) + { + DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath); + myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant + DirectoryEntry other = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.None); // Noncompliant + DirectoryEntry secure = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.Secure); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unchecked-enumerable-sum.cs b/docs/multiple-tests/codacy-rules-csharp/src/unchecked-enumerable-sum.cs new file mode 100644 index 0000000..4e18a95 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unchecked-enumerable-sum.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Practices +{ + class Sums + { + void Add(List list) + { + int total1 = unchecked(list.Sum()); // Noncompliant + + unchecked + { + int total2 = list.Sum(); // Noncompliant + try + { + int total3 = list.Sum(); + } + catch (OverflowException e) + { + Console.WriteLine(e.Message); + } + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unconstrained-generic-null-comparison.cs b/docs/multiple-tests/codacy-rules-csharp/src/unconstrained-generic-null-comparison.cs new file mode 100644 index 0000000..3287dd8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unconstrained-generic-null-comparison.cs @@ -0,0 +1,19 @@ +namespace Tests.Bugs +{ + class Generics + { + bool IsDefault(T value) + { + if (value == null) // Noncompliant + { + return true; + } + return false; + } + + bool IsNull(T value) where T : class + { + return value == null; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unix-epoch-created-manually.cs b/docs/multiple-tests/codacy-rules-csharp/src/unix-epoch-created-manually.cs new file mode 100644 index 0000000..ecf853c --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unix-epoch-created-manually.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tests.Practices +{ + class Epoch + { + void GetEpochTime() + { + var epochTime = new DateTime(1970, 1, 1); // Noncompliant + var utcEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // Noncompliant + var other = new DateTime(1971, 1, 1); + var good = DateTime.UnixEpoch; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-archive-extraction.cs b/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-archive-extraction.cs new file mode 100644 index 0000000..0732b41 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-archive-extraction.cs @@ -0,0 +1,18 @@ +using System.IO; +using System.IO.Compression; + +namespace Tests.Security +{ + class Archives + { + void M() + { + using var zipToOpen = new FileStream(@"ZipBomb.zip", FileMode.Open); + using var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read); + foreach (ZipArchiveEntry entry in archive.Entries) + { + entry.ExtractToFile("./output_onlyfortesting.txt", true); // Noncompliant + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-deserialization.cs b/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-deserialization.cs new file mode 100644 index 0000000..5cd1794 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unrestricted-deserialization.cs @@ -0,0 +1,23 @@ +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Tests.Security +{ + class Deserialization + { + void M(Stream stream) + { + var myBinaryFormatter = new BinaryFormatter(); + myBinaryFormatter.Deserialize(stream); // Noncompliant + + var restricted = new BinaryFormatter(); + restricted.Binder = new CustomBinder(); + restricted.Deserialize(stream); + } + } + + class CustomBinder : System.Runtime.Serialization.SerializationBinder + { + public override System.Type BindToType(string assemblyName, string typeName) => null; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unsafe-code-block.cs b/docs/multiple-tests/codacy-rules-csharp/src/unsafe-code-block.cs new file mode 100644 index 0000000..d9e55ec --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unsafe-code-block.cs @@ -0,0 +1,21 @@ +namespace Tests.Security +{ + class Unsafe + { + public unsafe int SubarraySum(int[] array, int start, int end) // Noncompliant + { + var sum = 0; + fixed (int* firstNumber = array) + { + for (int i = start; i < end; i++) + { + sum += *(firstNumber + i); + } + } + return sum; + } + + // this method is not unsafe + public int Safe(int[] array) => array.Length; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/untestable-system-clock.cs b/docs/multiple-tests/codacy-rules-csharp/src/untestable-system-clock.cs new file mode 100644 index 0000000..b61c247 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/untestable-system-clock.cs @@ -0,0 +1,18 @@ +using System; + +namespace Tests.Practices +{ + public interface IClock + { + DateTime UtcNow(); + } + + public class Foo + { + public string HelloTime() => + $"Hello at {DateTime.UtcNow}"; // Noncompliant + + public string HelloClock(IClock clock) => + $"Hello at {clock.UtcNow()}"; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unused-local-variable.cs b/docs/multiple-tests/codacy-rules-csharp/src/unused-local-variable.cs new file mode 100644 index 0000000..7d9e9e8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unused-local-variable.cs @@ -0,0 +1,26 @@ +using System.IO; + +namespace Tests.Unused +{ + public class Locals + { + public int NumberOfMinutes(int hours) + { + int seconds = 0; // Noncompliant + int minutes = hours * 60; + return minutes; + } + + public void UsingResource(string path) + { + using (var t = File.OpenRead(path)) + { + } + var used = path.Length; + if (used > 3) + { + System.Console.WriteLine(path); + } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unused-private-method-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/unused-private-method-parameter.cs new file mode 100644 index 0000000..ea5a6f1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unused-private-method-parameter.cs @@ -0,0 +1,38 @@ +using System; + +namespace Tests.Practices +{ + public class Parameters + { + private void DoSomething(int a, int b) // Noncompliant + { + Compute(a); + } + + private void DoSomething2(int a) // Noncompliant + { + var a2 = 10; + Compute(a2); + } + + public void Visible(int unused) + { + Compute(1); + } + + private void Used(int a, int b) + { + if (a > 0) + { + Compute(b); + } + } + + private void NotImplemented(int a) + { + throw new NotImplementedException(); + } + + private void Compute(int x) { Console.WriteLine(x); } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/unused-type-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/unused-type-parameter.cs new file mode 100644 index 0000000..54d329b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/unused-type-parameter.cs @@ -0,0 +1,20 @@ +namespace Tests.Unused +{ + public class MoreMath // Noncompliant + { + public int Add(int a, int b) // Noncompliant + { + return a + b; + } + + public void Use(V value) + { + System.Console.WriteLine(value); + } + } + + public class Box + { + public T Value { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/uri-string-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-parameter.cs new file mode 100644 index 0000000..6326b8a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-parameter.cs @@ -0,0 +1,10 @@ +namespace MyLibrary +{ + public class MyClass + { + public void FetchResource(string uriString) { } // Noncompliant + public void Download(string sourceUrl) { } // Noncompliant + public void Format(string returnValue) { } + private void Internal(string url) { } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/uri-string-property.cs b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-property.cs new file mode 100644 index 0000000..64b81c9 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-property.cs @@ -0,0 +1,15 @@ +namespace MyLibrary +{ + public class MyClass + { + private string myUri; + + public string MyUri // Noncompliant + { + get { return myUri; } + set { myUri = value; } + } + + public string Name { get; set; } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/uri-string-return-value.cs b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-return-value.cs new file mode 100644 index 0000000..bfaf73d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/uri-string-return-value.cs @@ -0,0 +1,15 @@ +namespace MyLibrary +{ + public class MyClass + { + public string GetParentUri() // Noncompliant + { + return "http://www.mysite.com"; + } + + public string GetName() + { + return "name"; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/use-exists-instead-of-any.cs b/docs/multiple-tests/codacy-rules-csharp/src/use-exists-instead-of-any.cs new file mode 100644 index 0000000..4c4b356 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/use-exists-instead-of-any.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Lists + { + bool ContainsEven(List data) => + data.Any(x => x % 2 == 0); // Noncompliant + + bool ContainsEven(int[] data) => + data.Any(x => x % 2 == 0); // Noncompliant + + bool ContainsEven(IEnumerable data) => + data.Any(x => x % 2 == 0); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/use-find-instead-of-firstordefault.cs b/docs/multiple-tests/codacy-rules-csharp/src/use-find-instead-of-firstordefault.cs new file mode 100644 index 0000000..42b7f49 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/use-find-instead-of-firstordefault.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Lists + { + int GetValue(List data) => + data.FirstOrDefault(x => x % 2 == 0); // Noncompliant + + int GetValue(int[] data) => + data.FirstOrDefault(x => x % 2 == 0); // Noncompliant + + int GetValue(IEnumerable data) => + data.FirstOrDefault(x => x % 2 == 0); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/use-string-isnullorempty.cs b/docs/multiple-tests/codacy-rules-csharp/src/use-string-isnullorempty.cs new file mode 100644 index 0000000..877d2f1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/use-string-isnullorempty.cs @@ -0,0 +1,13 @@ +namespace Tests.Performance +{ + class Strings + { + void M(string name) + { + if ("".Equals(name)) { } // Noncompliant + if (!name.Equals("")) { } // Noncompliant + if (name.Length == 0) { } // Noncompliant + if (string.IsNullOrEmpty(name)) { } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/use-trueforall-instead-of-all.cs b/docs/multiple-tests/codacy-rules-csharp/src/use-trueforall-instead-of-all.cs new file mode 100644 index 0000000..6247c85 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/use-trueforall-instead-of-all.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tests.Performance +{ + class Lists + { + public bool AreAllEven(List data) => + data.All(x => x % 2 == 0); // Noncompliant + + public bool AreAllEven(IEnumerable data) => + data.All(x => x % 2 == 0); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/useless-bitwise-operation.cs b/docs/multiple-tests/codacy-rules-csharp/src/useless-bitwise-operation.cs new file mode 100644 index 0000000..093262f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/useless-bitwise-operation.cs @@ -0,0 +1,13 @@ +namespace Tests.Style +{ + class Bitwise + { + void M(int anyValue) + { + var a = anyValue & -1; // Noncompliant + var b = anyValue | 0; // Noncompliant + var c = anyValue ^ 0; // Noncompliant + var d = anyValue & 0xFF; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/useless-increment.cs b/docs/multiple-tests/codacy-rules-csharp/src/useless-increment.cs new file mode 100644 index 0000000..f5c29b0 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/useless-increment.cs @@ -0,0 +1,20 @@ +namespace Tests.Bugs +{ + class Increments + { + private int counter; + + int PickNumber() + { + int i = 0; + int j = 0; + i = i++; // Noncompliant + return j--; // Noncompliant + } + + int Next() + { + return counter++; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/valuetask-consumed-incorrectly.cs b/docs/multiple-tests/codacy-rules-csharp/src/valuetask-consumed-incorrectly.cs new file mode 100644 index 0000000..7b3a59b --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/valuetask-consumed-incorrectly.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; + +namespace Tests.Bugs +{ + class ValueTasks + { + async Task M() + { + ValueTask vt = ComputeAsync(); + int result = await vt; + result = await vt; // Noncompliant + + ValueTask other = ComputeAsync(); + int value = other.Result; // Noncompliant + + ValueTask checkedTask = ComputeAsync(); + if (checkedTask.IsCompletedSuccessfully) + { + value = checkedTask.Result; + } + } + + ValueTask ComputeAsync() => new ValueTask(1); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/vararg-parameter.cs b/docs/multiple-tests/codacy-rules-csharp/src/vararg-parameter.cs new file mode 100644 index 0000000..5768866 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/vararg-parameter.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.InteropServices; + +namespace Tests.Compatibility +{ + public class Foo + { + public void Bar(__arglist) // Noncompliant + { + ArgIterator argumentIterator = new ArgIterator(__arglist); + } + + [DllImport("msvcrt40.dll")] + public static extern int printf(string format, __arglist); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/verbose-declaration.cs b/docs/multiple-tests/codacy-rules-csharp/src/verbose-declaration.cs new file mode 100644 index 0000000..0f4e070 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/verbose-declaration.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Tests.Style +{ + public class Verbose + { + void M() + { + var l = new List() {}; // Noncompliant + var o = new object() {}; // Noncompliant + var ints = new int[3] {1, 2, 3}; // Noncompliant + int? i = new int?(5); // Noncompliant + var ok = new List { 1 }; + var arr = new[] { 1, 2, 3 }; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/virtual-field-like-event.cs b/docs/multiple-tests/codacy-rules-csharp/src/virtual-field-like-event.cs new file mode 100644 index 0000000..2b82f04 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/virtual-field-like-event.cs @@ -0,0 +1,17 @@ +using System; + +namespace Tests.Bugs +{ + abstract class Car + { + public virtual event EventHandler OnRefuel; // Noncompliant + public event EventHandler OnStart; + + private EventHandler stopHandlers; + public virtual event EventHandler OnStop + { + add { stopHandlers += value; } + remove { stopHandlers -= value; } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/visible-pinvoke-method.cs b/docs/multiple-tests/codacy-rules-csharp/src/visible-pinvoke-method.cs new file mode 100644 index 0000000..5613019 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/visible-pinvoke-method.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace MyLibrary +{ + public class Foo + { + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern bool RemoveDirectory(string name); // Noncompliant + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + private static extern bool CreateDirectory(string name, System.IntPtr attributes); + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/visible-unmanaged-pointer.cs b/docs/multiple-tests/codacy-rules-csharp/src/visible-unmanaged-pointer.cs new file mode 100644 index 0000000..060f60d --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/visible-unmanaged-pointer.cs @@ -0,0 +1,12 @@ +using System; + +namespace MyLibrary +{ + public class MyClass + { + public IntPtr myPointer; // Noncompliant + protected UIntPtr myOtherPointer; // Noncompliant + public readonly IntPtr fixedPointer; + private IntPtr hidden; + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-cipher-algorithm.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-cipher-algorithm.cs new file mode 100644 index 0000000..e3e8eed --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-cipher-algorithm.cs @@ -0,0 +1,14 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Ciphers + { + public void Encrypt() + { + var simpleDES = new DESCryptoServiceProvider(); // Noncompliant + var tripleDes = TripleDES.Create(); // Noncompliant + var aes = Aes.Create(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-cryptographic-key.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-cryptographic-key.cs new file mode 100644 index 0000000..c491757 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-cryptographic-key.cs @@ -0,0 +1,17 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Keys + { + public void Encrypt() + { + var rsaCsp = new RSACryptoServiceProvider(); // Noncompliant + var dsaCsp = new DSACryptoServiceProvider(); // Noncompliant + var small = RSA.Create(1024); // Noncompliant + ECDsa ecdsa = ECDsa.Create(ECCurve.NamedCurves.brainpoolP160t1); // Noncompliant + var good = RSA.Create(2048); + ECDsa goodCurve = ECDsa.Create(ECCurve.NamedCurves.nistP256); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-hashing-algorithm.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-hashing-algorithm.cs new file mode 100644 index 0000000..65d6618 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-hashing-algorithm.cs @@ -0,0 +1,15 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Hashes + { + void M() + { + var hashProvider1 = new MD5CryptoServiceProvider(); // Noncompliant + var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("MD5"); // Noncompliant + var hashProvider3 = SHA1.Create(); // Noncompliant + var good = SHA256.Create(); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-password-hashing.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-password-hashing.cs new file mode 100644 index 0000000..b6a3d90 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-password-hashing.cs @@ -0,0 +1,14 @@ +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Passwords + { + void M(string password, byte[] salt) + { + var kdf = new Rfc2898DeriveBytes(password, salt); // Noncompliant + var kdf2 = new Rfc2898DeriveBytes(password, salt, 100, HashAlgorithmName.SHA256); // Noncompliant + var good = new Rfc2898DeriveBytes(password, salt, 600000, HashAlgorithmName.SHA256); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-pseudorandom-number-generator.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-pseudorandom-number-generator.cs new file mode 100644 index 0000000..d5a5aec --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-pseudorandom-number-generator.cs @@ -0,0 +1,17 @@ +using System; +using System.Security.Cryptography; + +namespace Tests.Security +{ + class Tokens + { + string M() + { + var random = new Random(); // Noncompliant + byte[] data = new byte[16]; + random.NextBytes(data); + var secure = RandomNumberGenerator.GetBytes(16); + return BitConverter.ToString(data) + BitConverter.ToString(secure); + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/weak-ssl-tls-protocol.cs b/docs/multiple-tests/codacy-rules-csharp/src/weak-ssl-tls-protocol.cs new file mode 100644 index 0000000..be83af1 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/weak-ssl-tls-protocol.cs @@ -0,0 +1,19 @@ +using System.Net; +using System.Net.Http; +using System.Security.Authentication; + +namespace Tests.Security +{ + class Tls + { + public void Encrypt() + { + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; // Noncompliant + var handler = new HttpClientHandler + { + SslProtocols = SslProtocols.Tls11 // Noncompliant + }; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/write-only-property.cs b/docs/multiple-tests/codacy-rules-csharp/src/write-only-property.cs new file mode 100644 index 0000000..799eb26 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/write-only-property.cs @@ -0,0 +1,21 @@ +namespace Tests.Practices +{ + class Program + { + private int foo; + + public int Foo //Noncompliant + { + set + { + foo = value; + } + } + + public int Bar + { + get { return foo; } + set { foo = value; } + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/xml-external-entity-processing.cs b/docs/multiple-tests/codacy-rules-csharp/src/xml-external-entity-processing.cs new file mode 100644 index 0000000..0fb5942 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/xml-external-entity-processing.cs @@ -0,0 +1,20 @@ +using System.Xml; + +namespace Tests.Security +{ + class Xml + { + public static void Decode() + { + XmlDocument parser = new XmlDocument(); + parser.XmlResolver = new XmlUrlResolver(); // Noncompliant + parser.LoadXml(""); + + var settings = new XmlReaderSettings(); + settings.DtdProcessing = DtdProcessing.Parse; // Noncompliant + + var safe = new XmlReaderSettings(); + safe.DtdProcessing = DtdProcessing.Prohibit; + } + } +} diff --git a/docs/multiple-tests/codacy-rules-csharp/src/xml-signature-checked-without-key.cs b/docs/multiple-tests/codacy-rules-csharp/src/xml-signature-checked-without-key.cs new file mode 100644 index 0000000..76b1e4a --- /dev/null +++ b/docs/multiple-tests/codacy-rules-csharp/src/xml-signature-checked-without-key.cs @@ -0,0 +1,17 @@ +using System.Security.Cryptography.X509Certificates; +using System.Security.Cryptography.Xml; +using System.Xml; + +namespace Tests.Security +{ + class Signatures + { + bool M(XmlDocument xmlDoc, X509Certificate2 trusted) + { + SignedXml signedXml = new SignedXml(xmlDoc); + bool valid = signedXml.CheckSignature(); // Noncompliant + bool good = signedXml.CheckSignature(trusted, true); + return valid && good; + } + } +} From 5ac8e643c724b4ebd34e53d8d52f2b06290ec608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9lio=20Rocha?= Date: Thu, 15 Oct 2026 21:57:32 +0100 Subject: [PATCH 4/4] Add C and C++ correctness and security rules Add 18 rules in docs/codacy-rules-c-cpp.yaml that target memory-safety and correctness bugs (CWE-tagged) rather than dangerous function names, which the GitLab and opengrep-rules sets already cover. Rules shared by both languages use codacy.c.*, C++-only rules use codacy.cpp.*. Tests live in docs/multiple-tests/codacy-rules-c-cpp/ with one file per rule and 49 expected results. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- docs/codacy-rules-c-cpp.yaml | 488 ++++++++++++++++++ .../codacy-rules-c-cpp/patterns.xml | 21 + .../codacy-rules-c-cpp/results.xml | 94 ++++ .../src/allocation-missing-null-terminator.c | 28 + .../allocation-missing-null-terminator.cpp | 13 + .../src/assignment-in-condition.c | 50 ++ .../src/char-passed-to-ctype-function.c | 33 ++ ...comparison-result-against-specific-value.c | 20 + ...mparison-result-against-specific-value.cpp | 9 + .../dangling-pointer-to-temporary-string.cpp | 39 ++ .../src/exception-caught-by-value.cpp | 30 ++ .../src/exception-thrown-by-pointer.cpp | 9 + .../codacy-rules-c-cpp/src/file-not-closed.c | 39 ++ .../src/memset-zero-length.c | 16 + .../src/mismatched-deallocation.cpp | 52 ++ ...rphic-class-without-virtual-destructor.cpp | 40 ++ .../src/realloc-result-overwrites-pointer.c | 15 + .../src/return-address-of-local.c | 39 ++ .../src/return-address-of-local.cpp | 14 + .../src/sizeof-pointer-as-buffer-size.c | 34 ++ .../src/thread-unsafe-function.c | 29 ++ .../src/unchecked-allocation-result.c | 54 ++ .../src/unsafe-call-in-signal-handler.c | 30 ++ .../src/unsigned-compared-with-zero.c | 34 ++ internal/docgen/parsing.go | 1 + 26 files changed, 1232 insertions(+), 1 deletion(-) create mode 100644 docs/codacy-rules-c-cpp.yaml create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/patterns.xml create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/results.xml create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/assignment-in-condition.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/char-passed-to-ctype-function.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/dangling-pointer-to-temporary-string.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/exception-caught-by-value.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/exception-thrown-by-pointer.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/file-not-closed.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/memset-zero-length.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/mismatched-deallocation.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/polymorphic-class-without-virtual-destructor.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/realloc-result-overwrites-pointer.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.cpp create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/sizeof-pointer-as-buffer-size.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/thread-unsafe-function.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/unchecked-allocation-result.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/unsafe-call-in-signal-handler.c create mode 100644 docs/multiple-tests/codacy-rules-c-cpp/src/unsigned-compared-with-zero.c diff --git a/README.md b/README.md index 3c31e7f..f654242 100755 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This is a **Codacy engine**: a Go wrapper (`cmd/tool`, `internal/tool`, built on The `docs/` directory holds both hand-maintained inputs and generated outputs: -- `docs/codacy-rules.yaml`, `docs/codacy-rules-i18n.yaml`, `docs/codacy-rules-ai.yaml`, `docs/codacy-rules-exotic.yaml`, `docs/codacy-rules-csharp.yaml` — Codacy's own custom Semgrep-style rules, hand-maintained, merged in alongside the upstream rule sets. `codacy-rules-csharp.yaml` holds the C# code quality and security rules (`codacy.csharp..`); each rule has a test file named after it in `docs/multiple-tests/codacy-rules-csharp/src/`, where `// Noncompliant` comments mark the expected findings (the file-level copyright rule is tested separately in `docs/multiple-tests/codacy-rules-csharp-header/`). +- `docs/codacy-rules.yaml`, `docs/codacy-rules-i18n.yaml`, `docs/codacy-rules-ai.yaml`, `docs/codacy-rules-exotic.yaml`, `docs/codacy-rules-csharp.yaml`, `docs/codacy-rules-c-cpp.yaml` — Codacy's own custom Semgrep-style rules, hand-maintained, merged in alongside the upstream rule sets. `codacy-rules-csharp.yaml` holds the C# code quality and security rules (`codacy.csharp..`); each rule has a test file named after it in `docs/multiple-tests/codacy-rules-csharp/src/`, where `// Noncompliant` comments mark the expected findings (the file-level copyright rule is tested separately in `docs/multiple-tests/codacy-rules-csharp-header/`). `codacy-rules-c-cpp.yaml` holds the C and C++ rules (`codacy.c..` for rules shared by both languages, `codacy.cpp..` for C++-only rules), tested the same way in `docs/multiple-tests/codacy-rules-c-cpp/src/`. - `docs/tool-description.md` — short blurb about the tool, hand-maintained. - `docs/patterns.json`, `docs/description/*.json`, `docs/description/*.md`, `docs/rules.yaml`, `docs/semgrep-pro-rules.yaml` — **generated, git-ignored** (see `.gitignore`: "Ignore generated documentation files to avoid licensing issues"). Do not hand-edit and do not expect to see them in `git status`/PR diffs — they're produced fresh on every `go run ./cmd/docgen` and inside the `Dockerfile` build itself. diff --git a/docs/codacy-rules-c-cpp.yaml b/docs/codacy-rules-c-cpp.yaml new file mode 100644 index 0000000..2212d02 --- /dev/null +++ b/docs/codacy-rules-c-cpp.yaml @@ -0,0 +1,488 @@ +rules: + - id: codacy.c.security.allocation-missing-null-terminator + severity: ERROR + languages: [c, cpp] + message: >- + Add 1 to this allocation size to make room for the terminating null character. + A buffer of strlen(s) bytes is one byte too small to hold a copy of s, so copying the string into it overflows the buffer. + pattern-either: + - pattern: malloc(strlen($S)) + - pattern: malloc(sizeof(char) * strlen($S)) + - pattern: malloc(strlen($S) * sizeof(char)) + - pattern: calloc(strlen($S), $N) + - pattern: realloc($P, strlen($S)) + - pattern: alloca(strlen($S)) + - pattern: new char[strlen($S)] + metadata: + category: security + cwe: "CWE-131: Incorrect Calculation of Buffer Size" + confidence: HIGH + - id: codacy.c.correctness.sizeof-pointer-as-buffer-size + severity: ERROR + languages: [c, cpp] + message: >- + Use the size of the pointed-to buffer instead of the size of the pointer. + sizeof applied to a pointer returns the size of the pointer itself, typically 4 or 8 bytes, not the size of the buffer it points to. + patterns: + - pattern-either: + - pattern-inside: | + $R $F(..., $T *$P, ...) { ... } + - pattern-inside: | + $R $F(..., $T $P[], ...) { ... } + - pattern-inside: | + $R $F(..., $T $P[$N], ...) { ... } + - pattern-inside: | + $T *$P = $INIT; + ... + - pattern-inside: | + $T *$P; + ... + - pattern-either: + - pattern: memset($P, $V, sizeof($P)) + - pattern: memcpy($P, $SRC, sizeof($P)) + - pattern: memcpy($DST, $P, sizeof($P)) + - pattern: memmove($P, $SRC, sizeof($P)) + - pattern: memmove($DST, $P, sizeof($P)) + - pattern: memcmp($P, $O, sizeof($P)) + - pattern: memcmp($O, $P, sizeof($P)) + - pattern: strncpy($P, $SRC, sizeof($P)) + - pattern: strncat($P, $SRC, sizeof($P)) + - pattern: snprintf($P, sizeof($P), ...) + - pattern: fgets($P, sizeof($P), $FILE) + - pattern: read($FD, $P, sizeof($P)) + - pattern: fread($P, $SZ, sizeof($P), $FILE) + - pattern: bzero($P, sizeof($P)) + metadata: + category: correctness + cwe: "CWE-467: Use of sizeof() on a Pointer Type" + confidence: HIGH + - id: codacy.c.correctness.realloc-result-overwrites-pointer + severity: WARNING + languages: [c, cpp] + message: >- + Assign the result of realloc to a temporary pointer before overwriting the original one. + If realloc fails it returns NULL and keeps the original block, which is then leaked because the only pointer to it was overwritten. + pattern: $P = realloc($P, $N) + metadata: + category: correctness + cwe: "CWE-401: Missing Release of Memory after Effective Lifetime" + confidence: HIGH + - id: codacy.c.security.unchecked-allocation-result + severity: ERROR + languages: [c, cpp] + message: >- + Check that this allocation succeeded before using the returned pointer. + Allocation functions return NULL when memory is exhausted, and dereferencing that NULL pointer crashes the program or corrupts memory. + patterns: + - pattern-either: + - pattern-inside: | + $T *$P = $ALLOC(...); + ... + - pattern-inside: | + $T *$P = ($C) $ALLOC(...); + ... + - pattern-inside: | + $P = $ALLOC(...); + ... + - pattern-inside: | + $P = ($C) $ALLOC(...); + ... + - metavariable-regex: + metavariable: $ALLOC + regex: '^(?:malloc|calloc|realloc|strdup|strndup|aligned_alloc)$' + - pattern-either: + - pattern: $P[$I] + - patterns: + - pattern: '*$P' + - pattern-not-inside: $P->$FIELD + - pattern: $P->$FIELD + - pattern: memcpy($P, ...) + - pattern: memset($P, ...) + - pattern: memmove($P, ...) + - pattern: strcpy($P, ...) + - pattern: strncpy($P, ...) + - pattern: strcat($P, ...) + - pattern: sprintf($P, ...) + - pattern: snprintf($P, ...) + - pattern-not-inside: | + if ($P == NULL) $S; + ... + - pattern-not-inside: | + if (NULL == $P) $S; + ... + - pattern-not-inside: | + if (!$P) $S; + ... + - pattern-not-inside: | + if ($P == 0) $S; + ... + - pattern-not-inside: | + if ($P == nullptr) $S; + ... + - pattern-not-inside: if ($P) $S; + - pattern-not-inside: if ($P != NULL) $S; + - pattern-not-inside: if (NULL != $P) $S; + - pattern-not-inside: if ($P != nullptr) $S; + - pattern-not-inside: $P && $E + - pattern-not-inside: $P != NULL && $E + - pattern-not-inside: | + assert($P); + ... + metadata: + category: security + cwe: "CWE-690: Unchecked Return Value to NULL Pointer Dereference" + confidence: MEDIUM + - id: codacy.c.security.return-address-of-local + severity: ERROR + languages: [c, cpp] + message: >- + Do not return the address of this local variable. + The variable is destroyed when the function returns, so the caller receives a dangling pointer. + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $R *$F(...) { ... $T $X[$N]; ... } + - pattern-inside: | + $R *$F(...) { ... $T $X[$N] = $INIT; ... } + - pattern-inside: | + $R *$F(...) { ... $T $X[] = $INIT; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... static $T $X[$N]; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... static $T $X[$N] = $INIT; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... static $T $X[] = $INIT; ... } + - pattern: return $X; + - patterns: + - pattern-either: + - pattern-inside: | + $R $F(...) { ... $T $X; ... } + - pattern-inside: | + $R $F(...) { ... $T $X = $INIT; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... static $T $X; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... static $T $X = $INIT; ... } + - pattern-not-inside: | + $R2 $F2(...) { ... extern $T $X; ... } + - pattern: return &$X; + metadata: + category: security + cwe: "CWE-562: Return of Stack Variable Address" + confidence: HIGH + - id: codacy.cpp.security.mismatched-deallocation + severity: ERROR + languages: [cpp] + message: >- + Release this memory with the deallocation function that matches how it was allocated. + Memory from new[] must be released with delete[], memory from new with delete, and memory from malloc with free; mixing them is undefined behavior. + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $T *$P = $NEW; + ... + - pattern-inside: | + $P = $NEW; + ... + - metavariable-regex: + metavariable: $NEW + regex: '^new\s+[\w:<>,\s*&]+\[' + - pattern-either: + - pattern: delete $P; + - pattern: free($P); + - patterns: + - pattern-either: + - pattern-inside: | + $T *$P = $NEW; + ... + - pattern-inside: | + $P = $NEW; + ... + - metavariable-regex: + metavariable: $NEW + regex: '^new\s+[\w:<>,\s*&]+[({][\s\S]*[)}]$' + - pattern-either: + - pattern: delete[] $P; + - pattern: free($P); + - patterns: + - pattern-either: + - pattern-inside: | + $T *$P = $ALLOC(...); + ... + - pattern-inside: | + $T *$P = ($C) $ALLOC(...); + ... + - pattern-inside: | + $P = ($C) $ALLOC(...); + ... + - metavariable-regex: + metavariable: $ALLOC + regex: '^(?:malloc|calloc|realloc|strdup)$' + - pattern-either: + - pattern: delete $P; + - pattern: delete[] $P; + metadata: + category: security + cwe: "CWE-762: Mismatched Memory Management Routines" + confidence: HIGH + - id: codacy.c.correctness.assignment-in-condition + severity: WARNING + languages: [c, cpp] + message: >- + Use '==' to compare, or wrap the assignment in an extra pair of parentheses if it is intended. + An assignment used as a condition is a frequent typo for a comparison and makes the condition always depend on the assigned value. + patterns: + - pattern-either: + - pattern: if ($A = $B) { ... } + - pattern: if ($A = $B) $S; + - pattern: while ($A = $B) { ... } + - pattern: while ($A = $B) $S; + - pattern-regex: '\b(?:if|while)[ \t]*\([ \t]*(?!\()(?:[^()=;]|\((?:[^()]|\([^()]*\))*\)|==|!=|<=|>=)*?(?+\-*/%&|^])=(?!=)' + options: + constant_propagation: false + metadata: + category: correctness + cwe: "CWE-481: Assigning instead of Comparing" + confidence: MEDIUM + - id: codacy.c.correctness.unsigned-compared-with-zero + severity: WARNING + languages: [c, cpp] + message: >- + Remove or correct this comparison, an unsigned value is never negative. + The comparison always has the same result, which usually means the variable has the wrong type or the check is wrong. + patterns: + - pattern-either: + - pattern-inside: | + $T $X = $V; + ... + - pattern-inside: | + $T $X; + ... + - pattern-inside: | + $R $F(..., $T $X, ...) { ... } + - metavariable-regex: + metavariable: $T + regex: '^(?:unsigned(?:\s+(?:int|long|short|char|long\s+long))?|size_t|std::size_t|uint(?:8|16|32|64)_t|std::uint(?:8|16|32|64)_t|uintptr_t|uintmax_t)$' + - pattern-either: + - pattern: $X < 0 + - pattern: $X >= 0 + - pattern: 0 > $X + - pattern: 0 <= $X + options: + constant_propagation: false + metadata: + category: correctness + cwe: "CWE-570: Expression is Always False" + confidence: HIGH + - id: codacy.c.correctness.memset-zero-length + severity: ERROR + languages: [c, cpp] + message: >- + Check the arguments of this memset call, it sets zero bytes. + A length of 0 usually means the value and length arguments were swapped, so the buffer is never initialized. + pattern-either: + - pattern: memset($P, $V, 0) + - pattern: std::memset($P, $V, 0) + options: + constant_propagation: false + metadata: + category: correctness + cwe: "CWE-687: Function Call With Incorrectly Specified Argument Value" + confidence: HIGH + - id: codacy.c.correctness.comparison-result-against-specific-value + severity: WARNING + languages: [c, cpp] + message: >- + Compare the result of this comparison function with 0 instead of 1 or -1. + Functions such as strcmp and memcmp only guarantee the sign of their result, not its value. + patterns: + - pattern-either: + - pattern: $CMP(...) == $K + - pattern: $CMP(...) != $K + - pattern: $K == $CMP(...) + - pattern: $K != $CMP(...) + - pattern: $O.compare(...) == $K + - pattern: $O.compare(...) != $K + - metavariable-regex: + metavariable: $K + regex: '^(?:-1|1)$' + - pattern-either: + - pattern: $O.compare(...) == $K + - pattern: $O.compare(...) != $K + - patterns: + - pattern-either: + - pattern: $CMP(...) == $K + - pattern: $CMP(...) != $K + - pattern: $K == $CMP(...) + - pattern: $K != $CMP(...) + - metavariable-regex: + metavariable: $CMP + regex: '^(?:std::)?(?:strcmp|strncmp|strcasecmp|strncasecmp|memcmp|wcscmp|wcsncmp|_stricmp|_strnicmp|strcoll)$' + options: + constant_propagation: false + metadata: + category: correctness + cwe: "CWE-697: Incorrect Comparison" + confidence: HIGH + - id: codacy.c.correctness.thread-unsafe-function + severity: WARNING + languages: [c, cpp] + message: >- + Use the reentrant version of this function, such as localtime_r or getpwnam_r. + This function returns a pointer to static data that can be overwritten by concurrent calls from other threads. + patterns: + - pattern: $FN(...) + - metavariable-regex: + metavariable: $FN + regex: '^(?:std::)?(?:localtime|gmtime|ctime|asctime|getpwnam|getpwuid|getgrnam|getgrgid|gethostbyname|gethostbyaddr|inet_ntoa|ttyname|getpwent|getgrent)$' + metadata: + category: correctness + cwe: "CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')" + confidence: MEDIUM + - id: codacy.c.security.unsafe-call-in-signal-handler + severity: ERROR + languages: [c, cpp] + message: >- + Only call async-signal-safe functions from this signal handler. + Functions such as printf, malloc or exit can deadlock or corrupt state when a signal interrupts them; set a volatile sig_atomic_t flag instead. + patterns: + - pattern-either: + - pattern-inside: | + void $H(int $SIG) { ... } + ... + signal($N, $H); + - pattern-inside: | + void $H(int $SIG) { ... } + ... + $SA.sa_handler = $H; + - pattern-inside: | + signal($N, $H); + ... + void $H(int $SIG) { ... } + - pattern-inside: | + void $H(int $SIG) { ... } + - pattern: $FN(...) + - metavariable-regex: + metavariable: $FN + regex: '^(?:std::)?(?:printf|fprintf|sprintf|snprintf|vprintf|vfprintf|puts|fputs|putchar|fputc|perror|malloc|calloc|realloc|free|exit|syslog|fopen|fclose|fflush|fwrite|longjmp|strerror|localtime|time)$' + metadata: + category: security + cwe: "CWE-479: Signal Handler Use of a Non-reentrant Function" + confidence: HIGH + - id: codacy.c.correctness.file-not-closed + severity: WARNING + languages: [c, cpp] + message: >- + Close this file or directory handle on every path through the function. + Handles that are never released leak file descriptors, and buffered writes may be lost. + patterns: + - pattern-inside: | + $R $FN(...) { ... } + - pattern-either: + - patterns: + - pattern-either: + - pattern: $T *$F = fopen(...); + - pattern: $F = fopen(...); + - pattern: $T *$F = fdopen(...); + - pattern-not-inside: | + $R $FN(...) { ... fclose($F); ... } + - patterns: + - pattern-either: + - pattern: $T *$F = popen(...); + - pattern: $F = popen(...); + - pattern-not-inside: | + $R $FN(...) { ... pclose($F); ... } + - patterns: + - pattern-either: + - pattern: $T *$F = opendir(...); + - pattern: $F = opendir(...); + - pattern-not-inside: | + $R $FN(...) { ... closedir($F); ... } + - pattern-not-inside: | + $R $FN(...) { ... return $F; ... } + - pattern-not-inside: | + $R $FN(...) { ... $X->$FIELD = $F; ... } + - pattern-not-inside: | + $R $FN(...) { ... $X.$FIELD = $F; ... } + metadata: + category: correctness + cwe: "CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime" + confidence: MEDIUM + - id: codacy.c.correctness.char-passed-to-ctype-function + severity: WARNING + languages: [c, cpp] + message: >- + Cast this character to unsigned char before passing it to the character classification function. + Passing a negative char value, such as a non-ASCII character, to these functions is undefined behavior. + patterns: + - pattern-either: + - pattern-inside: | + char $C = $V; + ... + - pattern-inside: | + char $C; + ... + - pattern-inside: | + $R $F(..., char $C, ...) { ... } + - pattern: $FN($C) + - pattern-not: $FN(($CAST) $C) + - pattern-not: $FN(static_cast<$CAST>($C)) + - metavariable-regex: + metavariable: $FN + regex: '^(?:std::)?(?:isalnum|isalpha|isblank|iscntrl|isdigit|isgraph|islower|isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper)$' + metadata: + category: correctness + cwe: "CWE-704: Incorrect Type Conversion or Cast" + confidence: HIGH + - id: codacy.cpp.correctness.exception-caught-by-value + severity: WARNING + languages: [cpp] + message: >- + Catch this exception by const reference instead of by value. + Catching by value copies the exception and slices derived exception types, losing their data and overridden behavior. + pattern-regex: '\bcatch[ \t]*\([ \t]*(?:const[ \t]+)?\K(?!(?:int|long|short|char|unsigned|signed|bool|float|double|size_t|std::size_t)\b)[A-Za-z_][\w:]*(?:<[^<>()]*>)?(?=[ \t]+\w+[ \t]*\))' + metadata: + category: correctness + cwe: "CWE-755: Improper Handling of Exceptional Conditions" + confidence: HIGH + - id: codacy.cpp.correctness.exception-thrown-by-pointer + severity: WARNING + languages: [cpp] + message: >- + Throw this exception by value instead of allocating it with new. + Handlers expecting a reference never catch a pointer, and the allocated exception object is usually leaked. + pattern: throw new $T(...) + metadata: + category: correctness + cwe: "CWE-401: Missing Release of Memory after Effective Lifetime" + confidence: HIGH + - id: codacy.cpp.security.dangling-pointer-to-temporary-string + severity: ERROR + languages: [cpp] + message: >- + Do not keep a pointer into this temporary string, it is destroyed at the end of the statement. + Using the pointer afterwards reads freed memory. + pattern-either: + - pattern: $T *$P = $F(...).c_str(); + - pattern: $T *$P = $O.$F(...).c_str(); + - pattern: $T *$P = ($A + $B).c_str(); + - pattern: $P = $F(...).c_str(); + - pattern: $P = $O.$F(...).c_str(); + - pattern: $P = ($A + $B).c_str(); + metadata: + category: security + cwe: "CWE-416: Use After Free" + confidence: MEDIUM + - id: codacy.cpp.correctness.polymorphic-class-without-virtual-destructor + severity: WARNING + languages: [cpp] + message: >- + Make the destructor of this class virtual, or protected and non-virtual. + Deleting a derived object through a pointer to this base class without a virtual destructor is undefined behavior and leaks resources. + pattern-regex: '\b(?:class|struct)[ \t]+\K(\w+)\b(?![ \t]*final\b)(?=[ \t]*\{)(?=\s*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\n[ \t]*virtual\b)(?!\s*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\bvirtual[ \t]+~\1\b)(?!\s*\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?\bprotected[ \t]*:(?:(?!\b(?:public|private)[ \t]*:)[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*?~\1\b)' + metadata: + category: correctness + cwe: "CWE-1079: Parent Class without Virtual Destructor Method" + confidence: MEDIUM diff --git a/docs/multiple-tests/codacy-rules-c-cpp/patterns.xml b/docs/multiple-tests/codacy-rules-c-cpp/patterns.xml new file mode 100644 index 0000000..c847a1f --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/patterns.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/multiple-tests/codacy-rules-c-cpp/results.xml b/docs/multiple-tests/codacy-rules-c-cpp/results.xml new file mode 100644 index 0000000..eaad138 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/results.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.c b/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.c new file mode 100644 index 0000000..54446bd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.c @@ -0,0 +1,28 @@ +#include +#include + +char *copy_bad(const char *s) { + char *d = malloc(strlen(s)); // Noncompliant + strcpy(d, s); + return d; +} + +char *copy_bad2(const char *s) { + char *d = (char *) malloc(sizeof(char) * strlen(s)); // Noncompliant + strcpy(d, s); + return d; +} + +char *copy_bad3(const char *s) { + return calloc(strlen(s), 1); // Noncompliant +} + +char *copy_good(const char *s) { + char *d = malloc(strlen(s) + 1); + strcpy(d, s); + return d; +} + +char *copy_good2(const char *s) { + return calloc(strlen(s) + 1, sizeof(char)); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.cpp new file mode 100644 index 0000000..ff922be --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/allocation-missing-null-terminator.cpp @@ -0,0 +1,13 @@ +#include + +char *dup_bad(const char *s) { + char *d = new char[strlen(s)]; // Noncompliant + strcpy(d, s); + return d; +} + +char *dup_good(const char *s) { + char *d = new char[strlen(s) + 1]; + strcpy(d, s); + return d; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/assignment-in-condition.c b/docs/multiple-tests/codacy-rules-c-cpp/src/assignment-in-condition.c new file mode 100644 index 0000000..f2b5ad6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/assignment-in-condition.c @@ -0,0 +1,50 @@ +#include + +int check_bad(int x, int y) { + if (x = y) { // Noncompliant + return 1; + } + return 0; +} + +void loop_bad(int *p, int v) { + while (*p = v) // Noncompliant + p++; +} + +int check_good(int x, int y) { + if (x == y) { + return 1; + } + return 0; +} + +void read_good(FILE *f) { + int c; + while ((c = fgetc(f)) != EOF) { + putchar(c); + } +} + +void intended_good(char *dst, const char *src) { + while ((*dst++ = *src++)) + ; +} + +int nested_good(int *out, int x) { + int r; + if ((r = x * 2)) { + if (r > 10) { + *out = r; + } + if (r != 3) + return 1; + } + return 0; +} + +int compound_good(int x) { + if (x <= 3 && x >= 0) + return 1; + return 0; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/char-passed-to-ctype-function.c b/docs/multiple-tests/codacy-rules-c-cpp/src/char-passed-to-ctype-function.c new file mode 100644 index 0000000..df5c8fb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/char-passed-to-ctype-function.c @@ -0,0 +1,33 @@ +#include + +int count_digits_bad(const char *s) { + int n = 0; + for (; *s; s++) { + char c = *s; + if (isdigit(c)) // Noncompliant + n++; + } + return n; +} + +int upper_bad(char c) { + return toupper(c); // Noncompliant +} + +int count_digits_good(const char *s) { + int n = 0; + for (; *s; s++) { + unsigned char c = (unsigned char) *s; + if (isdigit(c)) + n++; + } + return n; +} + +int upper_good(char c) { + return toupper((unsigned char) c); +} + +int is_space_good(int c) { + return isspace(c); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.c b/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.c new file mode 100644 index 0000000..9bad2f8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.c @@ -0,0 +1,20 @@ +#include + +int greater_bad(const char *a, const char *b) { + return strcmp(a, b) == 1; // Noncompliant +} + +int less_bad(const void *a, const void *b, size_t n) { + if (memcmp(a, b, n) == -1) { // Noncompliant + return 1; + } + return 0; +} + +int greater_good(const char *a, const char *b) { + return strcmp(a, b) > 0; +} + +int equal_good(const char *a, const char *b) { + return strcmp(a, b) == 0; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.cpp new file mode 100644 index 0000000..278cbd8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/comparison-result-against-specific-value.cpp @@ -0,0 +1,9 @@ +#include + +bool after_bad(const std::string &a, const std::string &b) { + return a.compare(b) == 1; // Noncompliant +} + +bool after_good(const std::string &a, const std::string &b) { + return a.compare(b) > 0; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/dangling-pointer-to-temporary-string.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/dangling-pointer-to-temporary-string.cpp new file mode 100644 index 0000000..5b147cc --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/dangling-pointer-to-temporary-string.cpp @@ -0,0 +1,39 @@ +#include +#include + +std::string get_name(); + +struct User { std::string name() const; }; + +void print_bad(const User &u) { + const char *p = get_name().c_str(); // Noncompliant + std::puts(p); +} + +void print_bad2(const User &u) { + const char *p = u.name().c_str(); // Noncompliant + std::puts(p); +} + +void print_bad3(const std::string &a, const std::string &b) { + const char *p = (a + b).c_str(); // Noncompliant + std::puts(p); +} + +void print_good(const User &u) { + std::string name = u.name(); + const char *p = name.c_str(); + std::puts(p); +} + +void print_good2() { + std::puts(get_name().c_str()); +} + +struct Slice { const char *data() const; }; +Slice generate(int n); + +void slice_good() { + const char *p = generate(10).data(); + std::puts(p); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/exception-caught-by-value.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/exception-caught-by-value.cpp new file mode 100644 index 0000000..b65c7d6 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/exception-caught-by-value.cpp @@ -0,0 +1,30 @@ +#include +#include + +void run_bad() { + try { + throw std::runtime_error("failed"); + } catch (std::exception e) { // Noncompliant + std::cerr << e.what(); + } +} + +void run_bad2() { + try { + throw std::runtime_error("failed"); + } catch (const std::runtime_error e) { // Noncompliant + std::cerr << e.what(); + } +} + +void run_good() { + try { + throw std::runtime_error("failed"); + } catch (const std::exception &e) { + std::cerr << e.what(); + } catch (int code) { + std::cerr << code; + } catch (...) { + std::cerr << "unknown"; + } +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/exception-thrown-by-pointer.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/exception-thrown-by-pointer.cpp new file mode 100644 index 0000000..e7d7680 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/exception-thrown-by-pointer.cpp @@ -0,0 +1,9 @@ +#include + +void fail_bad() { + throw new std::runtime_error("failed"); // Noncompliant +} + +void fail_good() { + throw std::runtime_error("failed"); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/file-not-closed.c b/docs/multiple-tests/codacy-rules-c-cpp/src/file-not-closed.c new file mode 100644 index 0000000..c87e0fa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/file-not-closed.c @@ -0,0 +1,39 @@ +#include +#include + +int first_byte_bad(const char *path) { + FILE *f = fopen(path, "r"); // Noncompliant + if (f == NULL) + return -1; + return fgetc(f); +} + +int count_bad(const char *path) { + int n = 0; + DIR *d = opendir(path); // Noncompliant + while (readdir(d) != NULL) + n++; + return n; +} + +int first_byte_good(const char *path) { + int c; + FILE *f = fopen(path, "r"); + if (f == NULL) + return -1; + c = fgetc(f); + fclose(f); + return c; +} + +FILE *open_log_good(const char *path) { + FILE *f = fopen(path, "a"); + return f; +} + +struct ctx { FILE *out; }; + +void attach_good(struct ctx *c, const char *path) { + FILE *f = fopen(path, "w"); + c->out = f; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/memset-zero-length.c b/docs/multiple-tests/codacy-rules-c-cpp/src/memset-zero-length.c new file mode 100644 index 0000000..1701ccd --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/memset-zero-length.c @@ -0,0 +1,16 @@ +#include + +void clear_bad(char *buf, size_t len) { + memset(buf, len, 0); // Noncompliant +} + +void clear_good(char *buf, size_t len) { + memset(buf, 0, len); +} + +void clear_later_good(char *buf) { + size_t len = 0; + if (buf[0]) + len = 16; + memset(buf, 0, len); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/mismatched-deallocation.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/mismatched-deallocation.cpp new file mode 100644 index 0000000..ddf5013 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/mismatched-deallocation.cpp @@ -0,0 +1,52 @@ +#include + +struct Widget { int id; }; + +void array_bad(int n) { + int *values = new int[n]; + values[0] = 1; + delete values; // Noncompliant +} + +void object_bad() { + Widget *w = new Widget(); + delete[] w; // Noncompliant +} + +void malloc_bad() { + char *p = (char *) malloc(16); + delete p; // Noncompliant +} + +void new_free_bad() { + Widget *w = new Widget(); + free(w); // Noncompliant +} + +void array_good(int n) { + int *values = new int[n]; + values[0] = 1; + delete[] values; +} + +void object_good() { + Widget *w = new Widget(); + delete w; +} + +void malloc_good() { + char *p = (char *) malloc(16); + free(p); +} + +void pointer_array_good(int n) { + Widget **list = new Widget*[n]; + list[0] = new Widget(); + delete list[0]; + delete[] list; +} + +void pointer_array_bad(int n) { + Widget **list = new Widget*[n]; + delete list; // Noncompliant +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/polymorphic-class-without-virtual-destructor.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/polymorphic-class-without-virtual-destructor.cpp new file mode 100644 index 0000000..f5bb499 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/polymorphic-class-without-virtual-destructor.cpp @@ -0,0 +1,40 @@ +class Shape { // Noncompliant +public: + virtual double area() const = 0; + ~Shape() {} +}; + +class Animal { // Noncompliant +public: + virtual void speak(); +}; + +class Base { +public: + virtual ~Base() {} + virtual void run(); +}; + +class Interface { +public: + virtual void call() = 0; +protected: + ~Interface() {} +}; + +class Leaf final { +public: + virtual void call(); +}; + +class Plain { +public: + void call(); + ~Plain() {} +}; + +struct Iterator { + int flags; /* when set, iteration visits a virtual leaf (the value + stored in the parent) */ + void *data; +}; diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/realloc-result-overwrites-pointer.c b/docs/multiple-tests/codacy-rules-c-cpp/src/realloc-result-overwrites-pointer.c new file mode 100644 index 0000000..59677bf --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/realloc-result-overwrites-pointer.c @@ -0,0 +1,15 @@ +#include + +int grow_bad(int *items, size_t n) { + items = realloc(items, n * sizeof(int)); // Noncompliant + return items != NULL; +} + +int grow_good(int **items, size_t n) { + int *tmp = realloc(*items, n * sizeof(int)); + if (tmp == NULL) { + return 0; + } + *items = tmp; + return 1; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.c b/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.c new file mode 100644 index 0000000..1a4f4d5 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.c @@ -0,0 +1,39 @@ +#include + +char *name_bad(int id) { + char buf[32]; + snprintf(buf, sizeof(buf), "user-%d", id); + return buf; // Noncompliant +} + +int *counter_bad(void) { + int count = 0; + return &count; // Noncompliant +} + +char *name_good(int id) { + static char buf[32]; + snprintf(buf, sizeof(buf), "user-%d", id); + return buf; +} + +int *counter_good(void) { + static int count = 0; + return &count; +} + +int value_good(void) { + int count = 0; + return count; +} + +extern int global_counter; +static char global_buf[16]; + +int *global_good(void) { + return &global_counter; +} + +char *global_buf_good(void) { + return global_buf; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.cpp b/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.cpp new file mode 100644 index 0000000..04586fb --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/return-address-of-local.cpp @@ -0,0 +1,14 @@ +#include +#include + +std::string key_good(int i) { + char buf[100]; + std::snprintf(buf, sizeof(buf), "key_%d", i); + return buf; +} + +const char *key_bad(int i) { + char buf[100]; + std::snprintf(buf, sizeof(buf), "key_%d", i); + return buf; // Noncompliant +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/sizeof-pointer-as-buffer-size.c b/docs/multiple-tests/codacy-rules-c-cpp/src/sizeof-pointer-as-buffer-size.c new file mode 100644 index 0000000..f9046fa --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/sizeof-pointer-as-buffer-size.c @@ -0,0 +1,34 @@ +#include +#include +#include + +void clear_bad(char *buf) { + memset(buf, 0, sizeof(buf)); // Noncompliant +} + +void copy_bad(char *dst, const char *src) { + strncpy(dst, src, sizeof(dst)); // Noncompliant +} + +void read_bad(FILE *f) { + char *line = malloc(128); + fgets(line, sizeof(line), f); // Noncompliant + free(line); +} + +void format_bad(char buf[], int n) { + snprintf(buf, sizeof(buf), "%d", n); // Noncompliant +} + +void clear_good(void) { + char buf[64]; + memset(buf, 0, sizeof(buf)); +} + +void clear_good2(char *buf, size_t len) { + memset(buf, 0, len); +} + +void clear_struct(struct stat_like *p) { + memset(p, 0, sizeof(*p)); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/thread-unsafe-function.c b/docs/multiple-tests/codacy-rules-c-cpp/src/thread-unsafe-function.c new file mode 100644 index 0000000..6d48336 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/thread-unsafe-function.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +void log_time_bad(time_t now) { + struct tm *t = localtime(&now); // Noncompliant + printf("%d\n", t->tm_hour); +} + +void log_user_bad(uid_t uid) { + struct passwd *pw = getpwuid(uid); // Noncompliant + printf("%s\n", pw->pw_name); +} + +void log_time_good(time_t now) { + struct tm t; + localtime_r(&now, &t); + printf("%d\n", t.tm_hour); +} + +void log_user_good(uid_t uid) { + struct passwd pw; + struct passwd *result; + char buf[1024]; + getpwuid_r(uid, &pw, buf, sizeof(buf), &result); + printf("%s\n", strerror(errno)); +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/unchecked-allocation-result.c b/docs/multiple-tests/codacy-rules-c-cpp/src/unchecked-allocation-result.c new file mode 100644 index 0000000..bc335d8 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/unchecked-allocation-result.c @@ -0,0 +1,54 @@ +#include +#include + +struct node { int value; struct node *next; }; + +struct node *make_bad(int v) { + struct node *n = malloc(sizeof(struct node)); + n->value = v; // Noncompliant + n->next = NULL; // Noncompliant + return n; +} + +int *zeros_bad(size_t count) { + int *a = calloc(count, sizeof(int)); + a[0] = 1; // Noncompliant + return a; +} + +char *dup_bad(const char *s) { + char *d = (char *) malloc(strlen(s) + 1); + strcpy(d, s); // Noncompliant + return d; +} + +struct node *make_good(int v) { + struct node *n = malloc(sizeof(struct node)); + if (n == NULL) { + return NULL; + } + n->value = v; + n->next = NULL; + return n; +} + +int *zeros_good(size_t count) { + int *a = calloc(count, sizeof(int)); + if (!a) + return NULL; + a[0] = 1; + return a; +} + +char *dup_good(const char *s) { + char *d = malloc(strlen(s) + 1); + if (d != NULL) { + strcpy(d, s); + } + return d; +} + +int first_good(size_t count) { + int *a = malloc(count * sizeof(int)); + return a && a[0]; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/unsafe-call-in-signal-handler.c b/docs/multiple-tests/codacy-rules-c-cpp/src/unsafe-call-in-signal-handler.c new file mode 100644 index 0000000..a5c6de2 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/unsafe-call-in-signal-handler.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +static volatile sig_atomic_t stop_requested = 0; + +void on_interrupt(int sig) { + printf("interrupted by %d\n", sig); // Noncompliant + exit(1); // Noncompliant +} + +void on_term(int sig) { + stop_requested = 1; + _exit(0); +} + +void not_a_handler(int code) { + printf("code %d\n", code); +} + +int main(void) { + signal(SIGINT, on_interrupt); + signal(SIGTERM, on_term); + not_a_handler(2); + while (!stop_requested) { + pause(); + } + return 0; +} diff --git a/docs/multiple-tests/codacy-rules-c-cpp/src/unsigned-compared-with-zero.c b/docs/multiple-tests/codacy-rules-c-cpp/src/unsigned-compared-with-zero.c new file mode 100644 index 0000000..01f2361 --- /dev/null +++ b/docs/multiple-tests/codacy-rules-c-cpp/src/unsigned-compared-with-zero.c @@ -0,0 +1,34 @@ +#include +#include + +int find_bad(const int *a, size_t n, int v) { + size_t i; + for (i = n - 1; i >= 0; i--) { // Noncompliant + if (a[i] == v) + return 1; + } + return 0; +} + +int valid_bad(unsigned int len) { + if (len < 0) { // Noncompliant + return 0; + } + return 1; +} + +int check_bad(void) { + uint32_t value = 10; + return value >= 0; // Noncompliant +} + +int valid_good(int len) { + if (len < 0) { + return 0; + } + return 1; +} + +int empty_good(size_t n) { + return n == 0; +} diff --git a/internal/docgen/parsing.go b/internal/docgen/parsing.go index 4eb6638..57ebd43 100644 --- a/internal/docgen/parsing.go +++ b/internal/docgen/parsing.go @@ -117,6 +117,7 @@ func getCodacyRules(docsDir string) (*ParsedSemgrepRules, error) { "codacy-rules-ai.yaml", "codacy-rules-exotic.yaml", "codacy-rules-csharp.yaml", + "codacy-rules-c-cpp.yaml", } for _, file := range customRulesFiles { filePath, _ := filepath.Abs(path.Join(docsDir, file))