Skip to content

Commit ef3d4f3

Browse files
committed
Swift: Add qhelp and example.
1 parent 1a980c9 commit ef3d4f3

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Using a length value from an <code>NSString</code> in a <code>String</code>, or a count from a <code>String</code> in an <code>NSString</code>, may cause unexpected behavior. This is because certain unicode sequences are represented as one character in a <code>String</code> but as a sequence of multiple characters in an <code>NSString</code>. For example, a 'thumbs up' emoji with a skin tone modifier (&#x1F44D;&#x1F3FF;) is represented as U+1F44D (&#x1F44D;) then the modifier U+1F3FF.</p>
7+
8+
</overview>
9+
<recommendation>
10+
11+
<p>Use <code>String.count</code> when working with a <code>String</code>. Use <code>NSString.length</code> when working with an <code>NSString</code>. Do not mix values for lengths and offsets between the two types as they are not compatible measures.</p>
12+
13+
<p>If you need to convert between <code>Range</code> and <code>NSRange</code>, do so directly using the appropriate constructor. Do not attempt to use incompatible length and offset values to accomplish conversion.</p>
14+
15+
</recommendation>
16+
<example>
17+
18+
<p>In the following example, a <code>String</code> is converted to <code>NSString</code>, but a range is created from the <code>String</code> to do some processing on it.</p>
19+
20+
<sample src="StringLengthConflationBad.swift" />
21+
22+
<p>This is dangerous because, if the input contains certain characters, the range computed on the <code>String</code> will be wrong for the <code>NSString</code>. This will lead to incorrect behaviour in the string processing that follows. To fix the problem, we can use <code>NSString.length</code> to create the <code>NSRange</code> instead, as follows:</p>
23+
24+
<sample src="StringLengthConflationGood.swift" />
25+
26+
</example>
27+
<references>
28+
29+
<li>
30+
<a href="https://talk.objc.io/episodes/S01E80-swift-string-vs-nsstring">Swift String vs. NSString</a>
31+
</li>
32+
33+
</references>
34+
</qhelp>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
func myFunction(s: String) {
3+
let ns = NSString(string: s)
4+
let nsrange = NSMakeRange(0, s.count) // BAD: String length used in NSMakeRange
5+
6+
// ... use nsrange to process ns
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
func myFunction(s: String) {
3+
let ns = NSString(string: s)
4+
let nsrange = NSMakeRange(0, ns.length) // Fixed: NSString length used in NSMakeRange
5+
6+
// ... use nsrange to process ns
7+
}

0 commit comments

Comments
 (0)