aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar rsgowman <rgowman@google.com>2017-11-30 13:41:26 -0500
committerGravatar GitHub <noreply@github.com>2017-11-30 13:41:26 -0500
commit4ec5f00b1dec8220c1e458d852eecd602dd56b8f (patch)
tree5049bf41cb1a96085c6d4ad11b747f415ac05d46
parent072c3ae93df4e6363ad1b6cfd239877578b5b00b (diff)
Fix StringView to properly convert NSStrings (#509)
NSStrings are utf16, so NSString::length returns the number of utf16 characters present in the string. When the string is entirely made up of US-ASCII characters, everything's fine. But when characters requiring 16 bits are present, the size calculations were incorrect. Fixed by calculating the length based on the destination character set (i.e. UTF8).
-rw-r--r--Firestore/CHANGELOG.md2
-rw-r--r--Firestore/Example/Firestore.xcodeproj/project.pbxproj4
-rw-r--r--Firestore/Example/Tests/Local/StringViewTests.mm47
-rw-r--r--Firestore/Source/Local/StringView.h3
4 files changed, 55 insertions, 1 deletions
diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md
index 884af45..f1cd832 100644
--- a/Firestore/CHANGELOG.md
+++ b/Firestore/CHANGELOG.md
@@ -1,5 +1,7 @@
# Unreleased
- [changed] Firestore no longer has a direct dependency on FirebaseAuth.
+- [fixed] Fixed a crash when using path names with international characters
+ with persistence enabled.
# v0.9.3
- [changed] Improved performance loading documents matching a query.
diff --git a/Firestore/Example/Firestore.xcodeproj/project.pbxproj b/Firestore/Example/Firestore.xcodeproj/project.pbxproj
index f56af4c..ea9ae44 100644
--- a/Firestore/Example/Firestore.xcodeproj/project.pbxproj
+++ b/Firestore/Example/Firestore.xcodeproj/project.pbxproj
@@ -57,6 +57,7 @@
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
+ 61E1D8B11FCF6C5700753285 /* StringViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 61E1D8AF1FCF6AF500753285 /* StringViewTests.mm */; };
6ED54761B845349D43DB6B78 /* Pods_Firestore_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75A6FE51C1A02DF38F62FAAD /* Pods_Firestore_Example.framework */; };
71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; };
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
@@ -221,6 +222,7 @@
6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 61E1D8AF1FCF6AF500753285 /* StringViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringViewTests.mm; sourceTree = "<group>"; };
69F6A10DBD6187489481CD76 /* Pods_Firestore_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
75A6FE51C1A02DF38F62FAAD /* Pods_Firestore_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -551,6 +553,7 @@
DE51B1621F0D48AC0013853F /* Local */ = {
isa = PBXGroup;
children = (
+ 61E1D8AF1FCF6AF500753285 /* StringViewTests.mm */,
DE51B16A1F0D48AC0013853F /* FSTLocalStoreTests.h */,
DE51B1701F0D48AC0013853F /* FSTMutationQueueTests.h */,
DE51B1721F0D48AC0013853F /* FSTPersistenceTestHelpers.h */,
@@ -1216,6 +1219,7 @@
DE51B1E91F0D490D0013853F /* FSTLevelDBMutationQueueTests.mm in Sources */,
54764FAF1FAA21B90085E60A /* FSTGoogleTestTests.mm in Sources */,
DE51B1E61F0D490D0013853F /* FSTRemoteDocumentCacheTests.m in Sources */,
+ 61E1D8B11FCF6C5700753285 /* StringViewTests.mm in Sources */,
DE51B1D91F0D490D0013853F /* FSTEagerGarbageCollectorTests.m in Sources */,
DE51B1E21F0D490D0013853F /* FSTMutationQueueTests.m in Sources */,
DE51B1E81F0D490D0013853F /* FSTLevelDBKeyTests.mm in Sources */,
diff --git a/Firestore/Example/Tests/Local/StringViewTests.mm b/Firestore/Example/Tests/Local/StringViewTests.mm
new file mode 100644
index 0000000..fd97c13
--- /dev/null
+++ b/Firestore/Example/Tests/Local/StringViewTests.mm
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "Firestore/Source/Local/StringView.h"
+
+#import <XCTest/XCTest.h>
+#include <leveldb/slice.h>
+
+using Firestore::StringView;
+
+#define ASSERT_NSSTRING_TO_STRINGVIEW_AND_BACK_OK( nsstr ) \
+ StringView sv(nsstr); \
+ leveldb::Slice slice = sv; \
+ NSString *afterConversion = [[NSString alloc] initWithBytes:slice.data() \
+ length:slice.size() \
+ encoding:NSUTF8StringEncoding]; \
+ XCTAssertEqualObjects(afterConversion, nsstr);
+
+@interface StringViewTests : XCTestCase
+@end
+
+@implementation StringViewTests
+
+- (void)testStringViewNSStringToSliceWithUSAscii {
+ NSString *usAsciiChars = @"abcdefg ABCDEFG 12345 !@#$%";
+ ASSERT_NSSTRING_TO_STRINGVIEW_AND_BACK_OK(usAsciiChars);
+}
+
+- (void)testStringViewNSStringToSliceWithNonUSAscii {
+ NSString *nonUsAsciiChars = @"ó¹";
+ ASSERT_NSSTRING_TO_STRINGVIEW_AND_BACK_OK(nonUsAsciiChars);
+}
+
+@end
diff --git a/Firestore/Source/Local/StringView.h b/Firestore/Source/Local/StringView.h
index 799baf8..b81b7b5 100644
--- a/Firestore/Source/Local/StringView.h
+++ b/Firestore/Source/Local/StringView.h
@@ -46,7 +46,8 @@ class StringView {
// Creates a StringView from an NSString. When StringView is an argument type
// into which an NSString* is passed, the caller should ensure that the
// NSString is retained.
- StringView(NSString *str) : data_([str UTF8String]), size_(str.length) {
+ StringView(NSString *str)
+ : data_([str UTF8String]), size_([str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) {
}
// Creates a StringView from the given char* pointer with an explicit size.