Merge pull request #5212 from GregTho/win32close
Use ::_close rather than ::close in Win32 stubs.
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index db5d3b6..c866411 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -3084,6 +3084,14 @@
result->encodingSelector = @selector(set##NAME:); \
break; \
}
+#define CASE_SET_COPY(NAME) \
+ case GPBDataType##NAME: { \
+ result->impToAdd = imp_implementationWithBlock(^(id obj, id value) { \
+ return GPBSetRetainedObjectIvarWithFieldInternal(obj, field, [value copy], syntax); \
+ }); \
+ result->encodingSelector = @selector(set##NAME:); \
+ break; \
+ }
CASE_SET(Bool, BOOL, Bool)
CASE_SET(Fixed32, uint32_t, UInt32)
CASE_SET(SFixed32, int32_t, Int32)
@@ -3097,8 +3105,8 @@
CASE_SET(SInt64, int64_t, Int64)
CASE_SET(UInt32, uint32_t, UInt32)
CASE_SET(UInt64, uint64_t, UInt64)
- CASE_SET(Bytes, id, Object)
- CASE_SET(String, id, Object)
+ CASE_SET_COPY(Bytes)
+ CASE_SET_COPY(String)
CASE_SET(Message, id, Object)
CASE_SET(Group, id, Object)
CASE_SET(Enum, int32_t, Enum)
@@ -3178,7 +3186,7 @@
// full lookup.
const GPBFileSyntax syntax = descriptor.file.syntax;
result.impToAdd = imp_implementationWithBlock(^(id obj, id value) {
- return GPBSetObjectIvarWithFieldInternal(obj, field, value, syntax);
+ GPBSetObjectIvarWithFieldInternal(obj, field, value, syntax);
});
result.encodingSelector = @selector(setArray:);
break;
diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m
index e2a12ca..1aedb6c 100644
--- a/objectivec/GPBUtilities.m
+++ b/objectivec/GPBUtilities.m
@@ -448,6 +448,36 @@
//% GPBSetObjectIvarWithField(self, field, (id)value);
//%}
//%
+//%PDDM-DEFINE IVAR_ALIAS_DEFN_COPY_OBJECT(NAME, TYPE)
+//%// Only exists for public api, no core code should use this.
+//%TYPE *GPBGetMessage##NAME##Field(GPBMessage *self,
+//% TYPE$S NAME$S GPBFieldDescriptor *field) {
+//%#if defined(DEBUG) && DEBUG
+//% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
+//% GPBDataType##NAME),
+//% @"Attempting to get value of TYPE from field %@ "
+//% @"of %@ which is of type %@.",
+//% [self class], field.name,
+//% TypeToString(GPBGetFieldDataType(field)));
+//%#endif
+//% return (TYPE *)GPBGetObjectIvarWithField(self, field);
+//%}
+//%
+//%// Only exists for public api, no core code should use this.
+//%void GPBSetMessage##NAME##Field(GPBMessage *self,
+//% NAME$S GPBFieldDescriptor *field,
+//% NAME$S TYPE *value) {
+//%#if defined(DEBUG) && DEBUG
+//% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
+//% GPBDataType##NAME),
+//% @"Attempting to set field %@ of %@ which is of type %@ with "
+//% @"value of type TYPE.",
+//% [self class], field.name,
+//% TypeToString(GPBGetFieldDataType(field)));
+//%#endif
+//% GPBSetCopyObjectIvarWithField(self, field, (id)value);
+//%}
+//%
// Object types are handled slightly differently, they need to be released
// and retained.
@@ -483,6 +513,24 @@
syntax);
}
+static void GPBSetCopyObjectIvarWithField(GPBMessage *self,
+ GPBFieldDescriptor *field, id value);
+
+// GPBSetCopyObjectIvarWithField is blocked from the analyzer because it flags
+// a leak for the -copy even though GPBSetRetainedObjectIvarWithFieldInternal
+// is marked as consuming the value. Note: For some reason this doesn't happen
+// with the -retain in GPBSetObjectIvarWithField.
+#if !defined(__clang_analyzer__)
+// This exists only for briging some aliased types, nothing else should use it.
+static void GPBSetCopyObjectIvarWithField(GPBMessage *self,
+ GPBFieldDescriptor *field, id value) {
+ if (self == nil || field == nil) return;
+ GPBFileSyntax syntax = [self descriptor].file.syntax;
+ GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value copy],
+ syntax);
+}
+#endif // !defined(__clang_analyzer__)
+
void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field, id value,
GPBFileSyntax syntax) {
@@ -1168,7 +1216,7 @@
// Aliases are function calls that are virtually the same.
-//%PDDM-EXPAND IVAR_ALIAS_DEFN_OBJECT(String, NSString)
+//%PDDM-EXPAND IVAR_ALIAS_DEFN_COPY_OBJECT(String, NSString)
// This block of code is generated, do not edit it directly.
// Only exists for public api, no core code should use this.
@@ -1197,10 +1245,10 @@
[self class], field.name,
TypeToString(GPBGetFieldDataType(field)));
#endif
- GPBSetObjectIvarWithField(self, field, (id)value);
+ GPBSetCopyObjectIvarWithField(self, field, (id)value);
}
-//%PDDM-EXPAND IVAR_ALIAS_DEFN_OBJECT(Bytes, NSData)
+//%PDDM-EXPAND IVAR_ALIAS_DEFN_COPY_OBJECT(Bytes, NSData)
// This block of code is generated, do not edit it directly.
// Only exists for public api, no core code should use this.
@@ -1229,7 +1277,7 @@
[self class], field.name,
TypeToString(GPBGetFieldDataType(field)));
#endif
- GPBSetObjectIvarWithField(self, field, (id)value);
+ GPBSetCopyObjectIvarWithField(self, field, (id)value);
}
//%PDDM-EXPAND IVAR_ALIAS_DEFN_OBJECT(Message, GPBMessage)
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
index a41be9f..faf562b 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
@@ -891,7 +891,7 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
@@ -961,7 +961,7 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
index 470652d..3847bcc 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
@@ -914,7 +914,7 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
@@ -985,7 +985,7 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
diff --git a/objectivec/Tests/GPBMessageTests+Runtime.m b/objectivec/Tests/GPBMessageTests+Runtime.m
index 0058311..b0d58c9 100644
--- a/objectivec/Tests/GPBMessageTests+Runtime.m
+++ b/objectivec/Tests/GPBMessageTests+Runtime.m
@@ -2491,6 +2491,72 @@
XCTAssertEqualObjects(@"bar", message.mapStringString[@"foo"]);
}
+- (void)test_StringFieldsCopy {
+ // ObjC conventions call for NSString properites to be copy, ensure
+ // that is done correctly and the string isn't simply retained.
+
+ Message2 *msg1 = [Message2 message];
+ Message2 *msg2 = [Message2 message];
+
+ GPBFieldDescriptor *fieldDesc =
+ [[Message2 descriptor] fieldWithNumber:Message2_FieldNumber_OptionalString];
+ NSMutableString *mutableStr = [NSMutableString stringWithString:@"foo"];
+
+ msg1.optionalString = mutableStr;
+ GPBSetMessageStringField(msg2, fieldDesc, mutableStr);
+
+ XCTAssertEqualObjects(msg1.optionalString, mutableStr);
+ XCTAssertEqualObjects(msg1.optionalString, @"foo");
+ XCTAssertTrue(msg1.optionalString != mutableStr); // Ptr comparision.
+
+ XCTAssertEqualObjects(msg2.optionalString, mutableStr);
+ XCTAssertEqualObjects(msg2.optionalString, @"foo");
+ XCTAssertTrue(msg2.optionalString != mutableStr); // Ptr comparision.
+
+ [mutableStr appendString:@"bar"];
+
+ XCTAssertNotEqualObjects(msg1.optionalString, mutableStr);
+ XCTAssertEqualObjects(msg1.optionalString, @"foo");
+ XCTAssertTrue(msg1.optionalString != mutableStr); // Ptr comparision.
+
+ XCTAssertNotEqualObjects(msg2.optionalString, mutableStr);
+ XCTAssertEqualObjects(msg2.optionalString, @"foo");
+ XCTAssertTrue(msg2.optionalString != mutableStr); // Ptr comparision.
+}
+
+- (void)test_BytesFieldsCopy {
+ // ObjC conventions call for NSData properites to be copy, ensure
+ // that is done correctly and the data isn't simply retained.
+
+ Message2 *msg1 = [Message2 message];
+ Message2 *msg2 = [Message2 message];
+
+ GPBFieldDescriptor *fieldDesc =
+ [[Message2 descriptor] fieldWithNumber:Message2_FieldNumber_OptionalBytes];
+ NSMutableData *mutableData = [NSMutableData dataWithData:DataFromCStr("abc")];
+
+ msg1.optionalBytes = mutableData;
+ GPBSetMessageBytesField(msg2, fieldDesc, mutableData);
+
+ XCTAssertEqualObjects(msg1.optionalBytes, mutableData);
+ XCTAssertEqualObjects(msg1.optionalBytes, DataFromCStr("abc"));
+ XCTAssertTrue(msg1.optionalBytes != mutableData); // Ptr comparision.
+
+ XCTAssertEqualObjects(msg2.optionalBytes, mutableData);
+ XCTAssertEqualObjects(msg2.optionalBytes, DataFromCStr("abc"));
+ XCTAssertTrue(msg2.optionalBytes != mutableData); // Ptr comparision.
+
+ [mutableData appendData:DataFromCStr("123")];
+
+ XCTAssertNotEqualObjects(msg1.optionalBytes, mutableData);
+ XCTAssertEqualObjects(msg1.optionalBytes, DataFromCStr("abc"));
+ XCTAssertTrue(msg1.optionalBytes != mutableData); // Ptr comparision.
+
+ XCTAssertNotEqualObjects(msg2.optionalBytes, mutableData);
+ XCTAssertEqualObjects(msg2.optionalBytes, DataFromCStr("abc"));
+ XCTAssertTrue(msg2.optionalBytes != mutableData); // Ptr comparision.
+}
+
#pragma mark - Subset from from map_tests.cc
// TEST(GeneratedMapFieldTest, IsInitialized)