Skip to content

Commit 0b7bea4

Browse files
committed
[NSScanner] Fix a bug in the initialization of _NSStringBuffer that makes NSScanner unable to find any number.
After writing a simple test case for NSScanner, I found that NSScanner always returns 0 when scanning numbers. The problem is in _NSStringBuffer's init function, `curChar` was assigned to `buffer[0]` before `buffer` gets characters from scanned string. Changing `curChar` to a optional variable and assign it to `buffer[0]` after buffer got all characters from scanned string fixed this.
1 parent a276da3 commit 0b7bea4

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
5BF7AEBF1BCD51F9008F214A /* NSURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4A1BCC5DCB00ED97BB /* NSURL.swift */; };
197197
5BF7AEC01BCD51F9008F214A /* NSUUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4B1BCC5DCB00ED97BB /* NSUUID.swift */; };
198198
5BF7AEC11BCD51F9008F214A /* NSValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4C1BCC5DCB00ED97BB /* NSValue.swift */; };
199+
844DC3331C17584F005611F9 /* TestNSScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844DC3321C17584F005611F9 /* TestNSScanner.swift */; };
199200
84BA558E1C16F90900F48C54 /* TestNSTimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BA558D1C16F90900F48C54 /* TestNSTimeZone.swift */; };
200201
C93559291C12C49F009FD6A9 /* TestNSAffineTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */; };
201202
DCDBB8331C1768AC00313299 /* TestNSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCDBB8321C1768AC00313299 /* TestNSData.swift */; };
@@ -521,6 +522,7 @@
521522
5BDC3FCF1BCF17E600ED97BB /* NSCFSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCFSet.swift; sourceTree = "<group>"; };
522523
5BDC405C1BD6D83B00ED97BB /* TestFoundation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestFoundation.app; sourceTree = BUILT_PRODUCTS_DIR; };
523524
5BF7AEC21BCD568D008F214A /* ForSwiftFoundationOnly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForSwiftFoundationOnly.h; sourceTree = "<group>"; };
525+
844DC3321C17584F005611F9 /* TestNSScanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSScanner.swift; sourceTree = "<group>"; };
524526
84BA558D1C16F90900F48C54 /* TestNSTimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSTimeZone.swift; sourceTree = "<group>"; };
525527
C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAffineTransform.swift; sourceTree = "<group>"; };
526528
DCDBB8321C1768AC00313299 /* TestNSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSData.swift; sourceTree = "<group>"; };
@@ -1030,6 +1032,7 @@
10301032
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */,
10311033
DCDBB8321C1768AC00313299 /* TestNSData.swift */,
10321034
84BA558D1C16F90900F48C54 /* TestNSTimeZone.swift */,
1035+
844DC3321C17584F005611F9 /* TestNSScanner.swift */,
10331036
);
10341037
name = Tests;
10351038
sourceTree = "<group>";
@@ -1714,6 +1717,7 @@
17141717
files = (
17151718
525AECED1BF2C9C500D15BB0 /* TestNSFileManager.swift in Sources */,
17161719
EA66F6501BF1619600136161 /* TestNSNumber.swift in Sources */,
1720+
844DC3331C17584F005611F9 /* TestNSScanner.swift in Sources */,
17171721
E876A73E1C1180E000F279EC /* TestNSRange.swift in Sources */,
17181722
EA66F6521BF1619600136161 /* TestNSPropertyList.swift in Sources */,
17191723
4DC1D0801C12EEEF00B5948A /* TestNSPipe.swift in Sources */,

Foundation/NSScanner.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private struct _NSStringBuffer {
7979
var stringLen: Int
8080
var stringLoc: Int
8181
var buffer = Array<unichar>(count: 32, repeatedValue: 0)
82-
var curChar: unichar
82+
var curChar: unichar?
8383

8484
static let EndCharacter = unichar(0xffff)
8585

@@ -92,10 +92,10 @@ private struct _NSStringBuffer {
9292
bufferLen = min(32, stringLen - stringLoc);
9393
let range = NSMakeRange(stringLoc, bufferLen)
9494
bufferLoc = 1
95-
curChar = buffer[0]
9695
buffer.withUnsafeMutableBufferPointer({ (inout ptr: UnsafeMutableBufferPointer<unichar>) -> Void in
9796
self.string.getCharacters(ptr.baseAddress, range: range)
9897
})
98+
curChar = buffer[0]
9999
} else {
100100
bufferLen = 0
101101
bufferLoc = 1
@@ -104,7 +104,7 @@ private struct _NSStringBuffer {
104104
}
105105

106106
var currentCharacter: unichar {
107-
return curChar
107+
return curChar!
108108
}
109109

110110
var isAtEnd: Bool {

TestFoundation/TestNSScanner.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
11+
12+
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
13+
import Foundation
14+
import XCTest
15+
#else
16+
import SwiftFoundation
17+
import SwiftXCTest
18+
#endif
19+
20+
21+
22+
class TestNSScanner : XCTestCase {
23+
24+
var allTests : [(String, () -> Void)] {
25+
return [
26+
("test_scanInteger", test_scanInteger),
27+
]
28+
}
29+
30+
func test_scanInteger() {
31+
let scanner = NSScanner(string: "123")
32+
var value: Int = 0
33+
XCTAssert(scanner.scanInteger(&value), "An Integer should be found in the string `123`.")
34+
XCTAssertEqual(value, 123, "Scanned Integer value of the string `123` should be `123`.")
35+
}
36+
}

TestFoundation/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ XCTMain([
3939
TestNSDate(),
4040
TestNSData(),
4141
TestNSTimeZone(),
42+
TestNSScanner(),
4243
])

0 commit comments

Comments
 (0)