Skip to content

Commit 70ca37a

Browse files
committed
Swift: Model utf8, utf16 a\nd unicodeScalars sources.
1 parent 89d5bbb commit 70ca37a

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ class StringLengthConflationFlowState extends string {
2424
this = "String" and singular = "a String"
2525
or
2626
this = "NSString" and singular = "an NSString"
27+
or
28+
this = "String.utf8" and singular = "a String.utf8"
29+
or
30+
this = "String.utf16" and singular = "a String.utf16"
31+
or
32+
this = "String.unicodeScalars" and singular = "a String.unicodeScalars"
2733
}
2834

2935
/**
@@ -56,6 +62,30 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration {
5662
node.asExpr() = member and
5763
flowstate = "NSString"
5864
)
65+
or
66+
// result of a call to `String.utf8.count`
67+
exists(MemberRefExpr member |
68+
member.getBaseExpr().getType().getName() = "String.UTF8View" and
69+
member.getMember().(VarDecl).getName() = "count" and
70+
node.asExpr() = member and
71+
flowstate = "String.utf8"
72+
)
73+
or
74+
// result of a call to `String.utf16.count`
75+
exists(MemberRefExpr member |
76+
member.getBaseExpr().getType().getName() = "String.UTF16View" and
77+
member.getMember().(VarDecl).getName() = "count" and
78+
node.asExpr() = member and
79+
flowstate = "String.utf16"
80+
)
81+
or
82+
// result of a call to `String.unicodeScalars.count`
83+
exists(MemberRefExpr member |
84+
member.getBaseExpr().getType().getName() = "String.UnicodeScalarView" and
85+
member.getMember().(VarDecl).getName() = "count" and
86+
node.asExpr() = member and
87+
flowstate = "String.unicodeScalars"
88+
)
5989
}
6090

6191
/**

swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@ edges
1616
| StringLengthConflation.swift:144:28:144:30 | .count : | StringLengthConflation.swift:144:28:144:38 | ... call to -(_:_:) ... |
1717
nodes
1818
| StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length |
19+
| StringLengthConflation.swift:54:43:54:50 | .count | semmle.label | .count |
20+
| StringLengthConflation.swift:55:43:55:51 | .count | semmle.label | .count |
21+
| StringLengthConflation.swift:56:43:56:60 | .count | semmle.label | .count |
1922
| StringLengthConflation.swift:60:47:60:50 | .length : | semmle.label | .length : |
2023
| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... |
2124
| StringLengthConflation.swift:66:33:66:36 | .length : | semmle.label | .length : |
2225
| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... |
2326
| StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count |
2427
| StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count |
28+
| StringLengthConflation.swift:79:47:79:54 | .count | semmle.label | .count |
29+
| StringLengthConflation.swift:80:47:80:55 | .count | semmle.label | .count |
30+
| StringLengthConflation.swift:81:47:81:64 | .count | semmle.label | .count |
2531
| StringLengthConflation.swift:96:28:96:31 | .length : | semmle.label | .length : |
2632
| StringLengthConflation.swift:96:28:96:40 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... |
2733
| StringLengthConflation.swift:100:27:100:30 | .length : | semmle.label | .length : |
@@ -51,10 +57,16 @@ nodes
5157
subpaths
5258
#select
5359
| 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. |
60+
| StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | This String.utf8 length is used in a String, but it may not be equivalent. |
61+
| StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | This String.utf16 length is used in a String, but it may not be equivalent. |
62+
| StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. |
5463
| 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. |
5564
| 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. |
5665
| StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | This String length is used in an NSString, but it may not be equivalent. |
5766
| StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | This String length is used in an NSString, but it may not be equivalent. |
67+
| StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | This String.utf8 length is used in an NSString, but it may not be equivalent. |
68+
| StringLengthConflation.swift:80:47:80:55 | .count | StringLengthConflation.swift:80:47:80:55 | .count | StringLengthConflation.swift:80:47:80:55 | .count | This String.utf16 length is used in an NSString, but it may not be equivalent. |
69+
| StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | This String.unicodeScalars length is used in an NSString, but it may not be equivalent. |
5870
| StringLengthConflation.swift:96:28:96:40 | ... call to -(_:_:) ... | StringLengthConflation.swift:96:28:96:31 | .length : | StringLengthConflation.swift:96:28:96:40 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
5971
| StringLengthConflation.swift:100:27:100:39 | ... call to -(_:_:) ... | StringLengthConflation.swift:100:27:100:30 | .length : | StringLengthConflation.swift:100:27:100:39 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
6072
| StringLengthConflation.swift:104:25:104:37 | ... call to -(_:_:) ... | StringLengthConflation.swift:104:25:104:28 | .length : | StringLengthConflation.swift:104:25:104:37 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |

swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ func test(s: String) {
5151

5252
let ix1 = String.Index(encodedOffset: s.count) // GOOD
5353
let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index
54-
let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index [NOT DETECTED]
55-
let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index [NOT DETECTED]
56-
let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index [NOT DETECTED]
54+
let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index
55+
let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index
56+
let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index
5757
print("String.Index '\(ix1.encodedOffset)' / '\(ix2.encodedOffset)' '\(ix3.encodedOffset)' '\(ix4.encodedOffset)' '\(ix5.encodedOffset)'")
5858

5959
let ix6 = s.index(s.startIndex, offsetBy: s.count / 2) // GOOD
@@ -76,9 +76,9 @@ func test(s: String) {
7676

7777
let range5 = NSRange(location: 0, length: ns.length) // GOOD
7878
let range6 = NSRange(location: 0, length: s.count) // BAD: String length used in NSMakeRange
79-
let range7 = NSRange(location: 0, length: s.utf8.count) // BAD: String.utf8 length used in NSMakeRange [NOT DETECTED]
80-
let range8 = NSRange(location: 0, length: s.utf16.count) // BAD: String.utf16 length used in NSMakeRange [NOT DETECTED]
81-
let range9 = NSRange(location: 0, length: s.unicodeScalars.count) // BAD: String.unicodeScalars length used in NSMakeRange [NOT DETECTED]
79+
let range7 = NSRange(location: 0, length: s.utf8.count) // BAD: String.utf8 length used in NSMakeRange
80+
let range8 = NSRange(location: 0, length: s.utf16.count) // BAD: String.utf16 length used in NSMakeRange
81+
let range9 = NSRange(location: 0, length: s.unicodeScalars.count) // BAD: String.unicodeScalars length used in NSMakeRange
8282
print("NSRange '\(range5.description)' / '\(range6.description)' '\(range7.description)' '\(range8.description)' '\(range9.description)'")
8383

8484
// --- converting Range to NSRange ---

0 commit comments

Comments
 (0)