Merge branch 'main' into add-activerecord-annotate

This commit is contained in:
thiggy1342
2022-07-20 10:26:44 -04:00
committed by GitHub
82 changed files with 327 additions and 183 deletions

View File

@@ -1,3 +1,9 @@
## 0.3.1
### Minor Analysis Improvements
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.
## 0.3.0
### Deprecated APIs

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions.
## 0.3.1
### Minor Analysis Improvements
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.3.0
lastReleaseVersion: 0.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.3.1-dev
version: 0.3.2-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.
## 0.2.0
## 0.1.4

View File

@@ -1,4 +1,5 @@
---
category: breaking
---
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- cpp
- queries

View File

@@ -1,3 +1,5 @@
## 1.2.1
## 1.2.0
## 1.1.4

View File

@@ -0,0 +1 @@
## 1.2.1

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.2.0
lastReleaseVersion: 1.2.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.2.1-dev
version: 1.2.2-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,5 @@
## 1.2.1
## 1.2.0
## 1.1.4

View File

@@ -0,0 +1 @@
## 1.2.1

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.2.0
lastReleaseVersion: 1.2.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.2.1-dev
version: 1.2.2-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,5 @@
## 0.3.1
## 0.3.0
### Deprecated APIs

View File

@@ -0,0 +1 @@
## 0.3.1

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.3.0
lastReleaseVersion: 0.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.3.1-dev
version: 0.3.2-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.
## 0.2.0
### Query Metadata Changes

View File

@@ -1,4 +1,5 @@
---
category: breaking
---
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- csharp
- queries

View File

@@ -1,3 +1,5 @@
## 0.2.1
## 0.2.0
### Deprecated APIs

View File

@@ -0,0 +1 @@
## 0.2.1

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.2.1

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 0.2.1-dev
version: 0.2.2-dev
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,3 +1,5 @@
## 0.2.1
## 0.2.0
## 0.1.4

View File

@@ -0,0 +1 @@
## 0.2.1

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.2.1

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 0.2.1-dev
version: 0.2.2-dev
groups:
- go
- queries

View File

@@ -1,3 +1,16 @@
## 0.3.1
### New Features
* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type.
### Minor Analysis Improvements
* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance.
* Added `Modifier.isInline()`.
* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs.
* Added additional flow sources for uses of external storage on Android.
## 0.3.0
### Deprecated APIs

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
Added additional flow sources for uses of external storage on Android.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
Added `Modifier.isInline()`.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance.

View File

@@ -0,0 +1,12 @@
## 0.3.1
### New Features
* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type.
### Minor Analysis Improvements
* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance.
* Added `Modifier.isInline()`.
* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs.
* Added additional flow sources for uses of external storage on Android.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.3.0
lastReleaseVersion: 0.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 0.3.1-dev
version: 0.3.2-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -1,3 +1,15 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package.
### New Queries
* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added.
This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered
to receive system intents.
## 0.2.0
### Minor Analysis Improvements

View File

@@ -1,6 +0,0 @@
---
category: newQuery
---
* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added.
This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered
to receive system intents.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package.

View File

@@ -0,0 +1,11 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package.
### New Queries
* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added.
This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered
to receive system intents.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- java
- queries

View File

@@ -1,3 +1,11 @@
## 0.2.1
### Minor Analysis Improvements
* The `chownr` library is now modeled as a sink for the `js/path-injection` query.
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).
* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query.
## 0.2.0
### Major Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `chownr` library is now modeled as a sink for the `js/path-injection` query.

View File

@@ -0,0 +1,7 @@
## 0.2.1
### Minor Analysis Improvements
* The `chownr` library is now modeled as a sink for the `js/path-injection` query.
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).
* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.2.1

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 0.2.1-dev
version: 0.2.2-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -28,6 +28,9 @@ module Actions {
/** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */
YAMLMapping getJobs() { result = this.lookup("jobs") }
/** Gets the name of the workflow. */
string getName() { result = this.lookup("name").(YAMLString).getValue() }
/** Gets the name of the workflow file. */
string getFileName() { result = this.getFile().getBaseName() }
@@ -129,6 +132,9 @@ module Actions {
/** Gets the value of the `if` field in this step, if any. */
StepIf getIf() { result.getStep() = this }
/** Gets the ID of this step, if any. */
string getId() { result = this.lookup("id").(YAMLString).getValue() }
}
/**

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package.
## 0.2.0
### Minor Analysis Improvements

View File

@@ -1,4 +1,5 @@
---
category: breaking
---
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- javascript
- queries

View File

@@ -1,3 +1,18 @@
## 0.5.1
### Deprecated APIs
- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node`
have been renamed as follows:
- `getAnImmediateUse` -> `asSource`
- `getARhs` -> `asSink`
- `getAUse` -> `getAValueReachableFromSource`
- `getAValueReachingRhs` -> `getAValueReachingSink`
### Minor Analysis Improvements
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).
## 0.5.0
### Deprecated APIs

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).

View File

@@ -1,6 +1,6 @@
---
category: deprecated
---
## 0.5.1
### Deprecated APIs
- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node`
have been renamed as follows:
@@ -8,3 +8,7 @@ category: deprecated
- `getARhs` -> `asSink`
- `getAUse` -> `getAValueReachableFromSource`
- `getAValueReachingRhs` -> `getAValueReachingSink`
### Minor Analysis Improvements
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.0
lastReleaseVersion: 0.5.1

View File

@@ -1,5 +1,5 @@
name: codeql/python-all
version: 0.5.1-dev
version: 0.5.2-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package.
## 0.2.0
### Major Analysis Improvements

View File

@@ -1,4 +1,5 @@
---
category: breaking
---
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/python-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- python
- queries

View File

@@ -1,3 +1,12 @@
## 0.3.1
### Minor Analysis Improvements
* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist:
* The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem.
* The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`.
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).
## 0.3.0
### Deprecated APIs

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).

View File

@@ -1,6 +1,8 @@
---
category: minorAnalysis
---
## 0.3.1
### Minor Analysis Improvements
* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist:
* The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem.
* The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`.
* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively).

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.3.0
lastReleaseVersion: 0.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-all
version: 0.3.1-dev
version: 0.3.2-dev
groups: ruby
extractor: ruby
dbscheme: ruby.dbscheme

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package.
## 0.2.0
### New Queries

View File

@@ -1,4 +1,5 @@
---
category: breaking
---
## 0.3.0
### Breaking Changes
* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.0
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-queries
version: 0.2.1-dev
version: 0.3.1-dev
groups:
- ruby
- queries

View File

@@ -41,88 +41,80 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration {
}
override predicate isSink(DataFlow::Node node, string flowstate) {
// arguments to method calls...
exists(
string className, string methodName, string paramName, ClassDecl c, AbstractFunctionDecl f,
CallExpr call, int arg
AbstractFunctionDecl funcDecl, CallExpr call, string funcName, string paramName, int arg
|
(
// `NSRange.init`
className = "NSRange" and
methodName = "init(location:length:)" and
paramName = ["location", "length"]
// arguments to method calls...
exists(string className, ClassDecl c |
(
// `NSRange.init`
className = "NSRange" and
funcName = "init(location:length:)" and
paramName = ["location", "length"]
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
funcName = "character(at:)" and
paramName = "at"
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
funcName = "substring(from:)" and
paramName = "from"
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
funcName = "substring(to:)" and
paramName = "to"
or
// `NSMutableString.insert`
className = "NSMutableString" and
funcName = "insert(_:at:)" and
paramName = "at"
) and
c.getName() = className and
c.getAMember() = funcDecl and
call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and
flowstate = "String" // `String` length flowing into `NSString`
)
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
methodName = "character(at:)" and
paramName = "at"
// arguments to function calls...
// `NSMakeRange`
funcName = "NSMakeRange(_:_:)" and
paramName = ["loc", "len"] and
call.getStaticTarget() = funcDecl and
flowstate = "String" // `String` length flowing into `NSString`
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
methodName = "substring(from:)" and
paramName = "from"
or
// `NSString.character`
className = ["NSString", "NSMutableString"] and
methodName = "substring(to:)" and
paramName = "to"
or
// `NSMutableString.insert`
className = "NSMutableString" and
methodName = "insert(_:at:)" and
paramName = "at"
// arguments to method calls...
(
// `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast`
funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and
paramName = "k"
or
// `String.prefix`, `String.suffix`
funcName = ["prefix(_:)", "suffix(_:)"] and
paramName = "maxLength"
or
// `String.Index.init`
funcName = "init(encodedOffset:)" and
paramName = "offset"
or
// `String.index`
funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and
paramName = "n"
or
// `String.formIndex`
funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and
paramName = "distance"
) and
call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and
flowstate = "NSString" // `NSString` length flowing into `String`
) and
c.getName() = className and
c.getAMember() = f and // TODO: will this even work if its defined in a parent class?
call.getFunction().(ApplyExpr).getStaticTarget() = f and
f.getName() = methodName and
f.getParam(pragma[only_bind_into](arg)).getName() = paramName and
call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and
flowstate = "String" // `String` length flowing into `NSString`
)
or
// arguments to function calls...
exists(string funcName, string paramName, CallExpr call, int arg |
// `NSMakeRange`
funcName = "NSMakeRange(_:_:)" and
paramName = ["loc", "len"] and
call.getStaticTarget().getName() = funcName and
call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and
call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and
flowstate = "String" // `String` length flowing into `NSString`
)
or
// arguments to function calls...
exists(string funcName, string paramName, CallExpr call, int arg |
(
// `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast`
funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and
paramName = "k"
or
// `String.prefix`, `String.suffix`
funcName = ["prefix(_:)", "suffix(_:)"] and
paramName = "maxLength"
or
// `String.Index.init`
funcName = "init(encodedOffset:)" and
paramName = "offset"
or
// `String.index`
funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and
paramName = "n"
or
// `String.formIndex`
funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and
paramName = "distance"
) and
call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and
call.getFunction()
.(ApplyExpr)
.getStaticTarget()
.getParam(pragma[only_bind_into](arg))
.getName() = paramName and
call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and
flowstate = "NSString" // `NSString` length flowing into `String`
// match up `funcName`, `paramName`, `arg`, `node`.
funcDecl.getName() = funcName and
funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and
call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr()
)
}

View File

@@ -1,4 +1,5 @@
edges
| StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... |
| StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... |
| StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... |
| StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... |
@@ -15,6 +16,8 @@ edges
| StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... |
| StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... |
nodes
| StringLengthConflation2.swift:37:34:37:36 | .count : | semmle.label | .count : |
| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... |
| StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length |
| StringLengthConflation.swift:60:47:60:50 | .length : | semmle.label | .length : |
| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... |
@@ -50,6 +53,7 @@ nodes
| StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... |
subpaths
#select
| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |

View File

@@ -0,0 +1,42 @@
// this test is in a separate file, because we want to test with a slightly different library
// implementation. In this version, some of the functions of `NSString` are in fact implemented
// in a base class `NSStringBase`.
// --- stubs ---
func print(_ items: Any...) {}
typealias unichar = UInt16
class NSObject
{
}
class NSStringBase : NSObject
{
func substring(from: Int) -> String { return "" }
}
class NSString : NSStringBase
{
init(string: String) { length = string.count }
func substring(to: Int) -> String { return "" }
private(set) var length: Int
}
// --- tests ---
func test(s: String) {
let ns = NSString(string: s)
let nstr1 = ns.substring(from: ns.length - 1) // GOOD
let nstr2 = ns.substring(from: s.count - 1) // BAD: String length used in NSString [NOT DETECTED]
let nstr3 = ns.substring(to: ns.length - 1) // GOOD
let nstr4 = ns.substring(to: s.count - 1) // BAD: String length used in NSString
print("substrings '\(nstr1)' '\(nstr2)' / '\(nstr3)' '\(nstr4)'")
}
// `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier
test(s: "begin \u{0001F44D}\u{0001F3FF} end")