From 5d31b35b3cfdfb6a1635bf12a797ee5b38413711 Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Wed, 30 Aug 2023 15:47:55 +0000 Subject: [PATCH 1/4] Issue a warning instead of throwing an exception --- Source/NSLock.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/NSLock.m b/Source/NSLock.m index 420480638d..d621496d65 100644 --- a/Source/NSLock.m +++ b/Source/NSLock.m @@ -247,8 +247,7 @@ - (void) unlock\ {\ if (0 != GS_MUTEX_UNLOCK(_mutex))\ {\ - [NSException raise: NSLockException\ - format: @"failed to unlock mutex"];\ + NSLog(@"failed to unlock mutex");\ }\ CHK(Drop) \ } From 87d8a188f44f5b3d610e6c9b9851b6caa805389c Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Thu, 2 Nov 2023 15:55:57 -0400 Subject: [PATCH 2/4] Add Royal's patch to the current stable branch for keysight --- ChangeLog | 7 ++ Source/Additions/NSURL+GNUstepBase.m | 2 +- Source/GSSocketStream.h | 18 ++-- Source/GSSocketStream.m | 40 ++++---- Source/NSISO8601DateFormatter.m | 132 ++++++++++++++------------- Source/win32/NSStream.m | 9 ++ base.xcodeproj/project.pbxproj | 2 + 7 files changed, 116 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8cc942cc99..9bdcffe33b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-10-26 Richard Frith-Macdonald + + * Source/NSISO8601DateFormatter.m: + * Tests/base/NSDateFormatter/NSISO8601DateFormatter.m: + Add a couple of testcases, tidy up source code formatting, and make + fix for github issue #339 as suggested by kevinpeizner + 2023-10-10 Richard Frith-Macdonald * Source/GSPrivate.h: New method to set up system error information. diff --git a/Source/Additions/NSURL+GNUstepBase.m b/Source/Additions/NSURL+GNUstepBase.m index 70c4302845..2143911851 100644 --- a/Source/Additions/NSURL+GNUstepBase.m +++ b/Source/Additions/NSURL+GNUstepBase.m @@ -87,7 +87,7 @@ - (id) initWithScheme: (NSString*)scheme if ([host length] > 0) { [urlString appendString: - [host stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; + [host stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLHostAllowedCharacterSet]]]; } if ([port intValue] > 0) { diff --git a/Source/GSSocketStream.h b/Source/GSSocketStream.h index d7d44f7477..4ec703949e 100644 --- a/Source/GSSocketStream.h +++ b/Source/GSSocketStream.h @@ -30,7 +30,7 @@ #import "GSNetwork.h" typedef union { - struct sockaddr s; + struct sockaddr_storage s; /* Increased memory allocation for IPv6 addresses*/ struct sockaddr_in i4; #ifdef AF_INET6 struct sockaddr_in6 i6; @@ -62,12 +62,12 @@ SOCKIVARS /** * get the sockaddr */ -- (struct sockaddr*) _address; +- (struct sockaddr_storage*) _address; /** * set the sockaddr */ -- (void) _setAddress: (struct sockaddr*)address; +- (void) _setAddress: (struct sockaddr_storage*)address; /** * setter for closing flag ... the remote end has stopped either sending @@ -119,8 +119,8 @@ SOCKIVARS SOCKIVARS @end @interface GSSocketInputStream (AddedBehaviors) -- (struct sockaddr*) _address; -- (void) _setAddress: (struct sockaddr*)address; +- (struct sockaddr_storage*) _address; +- (void) _setAddress: (struct sockaddr_storage*)address; - (NSInteger) _read: (uint8_t *)buffer maxLength: (NSUInteger)len; - (void) _setClosing: (BOOL)passive; - (void) _setHandler: (id)h; @@ -161,8 +161,8 @@ SOCKIVARS SOCKIVARS @end @interface GSSocketOutputStream (AddedBehaviors) -- (struct sockaddr*) _address; -- (void) _setAddress: (struct sockaddr*)address; +- (struct sockaddr_storage*) _address; +- (void) _setAddress: (struct sockaddr_storage*)address; - (void) _setClosing: (BOOL)passive; - (void) _setHandler: (id)h; - (void) _setPassive: (BOOL)passive; @@ -217,8 +217,8 @@ SOCKIVARS @end @interface GSSocketServerStream (AddedBehaviors) -- (struct sockaddr*) _address; -- (void) _setAddress: (struct sockaddr*)address; +- (struct sockaddr_storage*) _address; +- (void) _setAddress: (struct sockaddr_storage*)address; - (void) _setClosing: (BOOL)passive; - (void) _setHandler: (id)h; - (void) _setPassive: (BOOL)passive; diff --git a/Source/GSSocketStream.m b/Source/GSSocketStream.m index 323001fdab..0870992207 100644 --- a/Source/GSSocketStream.m +++ b/Source/GSSocketStream.m @@ -943,7 +943,7 @@ + (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o if (conf != nil) { GSSOCKS *h; - struct sockaddr *sa = [i _address]; + struct sockaddr_storage *sa = [i _address]; NSString *v; BOOL i6 = NO; @@ -958,15 +958,15 @@ + (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o } #if defined(AF_INET6) - if (sa->sa_family == AF_INET6) + if (sa->ss_family == AF_INET6) { i6 = YES; } else #endif - if (sa->sa_family != AF_INET) + if (sa->ss_family != AF_INET) { - GSOnceMLog(@"SOCKS not supported for socket type %d", sa->sa_family); + GSOnceMLog(@"SOCKS not supported for socket type %d", sa->ss_family); return; } @@ -1563,12 +1563,12 @@ - (id) init #endif _sock = INVALID_SOCKET; _handler = nil; - _address.s.sa_family = AF_UNSPEC; + _address.s.ss_family = AF_UNSPEC; } return self; } -- (struct sockaddr*) _address +- (struct sockaddr_storage*) _address { return &_address.s; } @@ -1577,7 +1577,7 @@ - (id) propertyForKey: (NSString *)key { id result = [super propertyForKey: key]; - if (result == nil && _address.s.sa_family != AF_UNSPEC) + if (result == nil && _address.s.ss_family != AF_UNSPEC) { SOCKET s = [self _sock]; sockaddr_any sin; @@ -1693,7 +1693,7 @@ - (BOOL) _setSocketAddress: (NSString*)address } else { - [self _setAddress: (struct sockaddr*)&peer]; + [self _setAddress: (struct sockaddr_storage*)&peer]; return YES; } } @@ -1715,7 +1715,7 @@ - (BOOL) _setSocketAddress: (NSString*)address else { strncpy(peer.sun_path, c_addr, sizeof(peer.sun_path)-1); - [self _setAddress: (struct sockaddr*)&peer]; + [self _setAddress: (struct sockaddr_storage*)&peer]; return YES; } } @@ -1726,7 +1726,7 @@ - (BOOL) _setSocketAddress: (NSString*)address } } -- (void) _setAddress: (struct sockaddr*)address +- (void) _setAddress: (struct sockaddr_storage*)address { memcpy(&_address.s, address, GSPrivateSockaddrLength(address)); } @@ -1831,7 +1831,7 @@ - (void) open { [GSSOCKS tryInput: self output: _sibling]; } - s = socket(_address.s.sa_family, SOCK_STREAM, 0); + s = socket(_address.s.ss_family, SOCK_STREAM, 0); if (BADSOCKET(s)) { [self _recordError]; @@ -1849,7 +1849,7 @@ - (void) open [GSTLSHandler tryInput: self output: _sibling]; } - result = connect([self _sock], &_address.s, + result = connect([self _sock], (struct sockaddr*)&_address.s, GSPrivateSockaddrLength(&_address.s)); if (socketError(result)) { @@ -2352,7 +2352,7 @@ - (void) open { [GSSOCKS tryInput: _sibling output: self]; } - s = socket(_address.s.sa_family, SOCK_STREAM, 0); + s = socket(_address.s.ss_family, SOCK_STREAM, 0); if (BADSOCKET(s)) { [self _recordError]; @@ -2370,7 +2370,7 @@ - (void) open [GSTLSHandler tryInput: _sibling output: self]; } - result = connect([self _sock], &_address.s, + result = connect([self _sock], (struct sockaddr*)&_address.s, GSPrivateSockaddrLength(&_address.s)); if (socketError(result)) { @@ -2756,7 +2756,7 @@ - (void) open return; } - s = socket(_address.s.sa_family, SOCK_STREAM, 0); + s = socket(_address.s.ss_family, SOCK_STREAM, 0); if (BADSOCKET(s)) { [self _recordError]; @@ -2769,9 +2769,9 @@ - (void) open } #ifndef BROKEN_SO_REUSEADDR - if (_address.s.sa_family == AF_INET + if (_address.s.ss_family == AF_INET #ifdef AF_INET6 - || _address.s.sa_family == AF_INET6 + || _address.s.ss_family == AF_INET6 #endif ) { @@ -2792,7 +2792,7 @@ - (void) open #endif bindReturn = bind([self _sock], - &_address.s, GSPrivateSockaddrLength(&_address.s)); + (struct sockaddr*)&_address.s, GSPrivateSockaddrLength(&_address.s)); if (socketError(bindReturn)) { [self _recordError]; @@ -2854,11 +2854,11 @@ - (void) acceptWithInputStream: (NSInputStream **)inputStream struct { uint8_t bytes[BUFSIZ]; } __attribute__((aligned(2)))buf; - struct sockaddr *addr = (struct sockaddr*)&buf; + struct sockaddr_storage *addr = (struct sockaddr_storage*)&buf; socklen_t len = sizeof(buf); int acceptReturn; - acceptReturn = accept([self _sock], addr, (OPTLEN*)&len); + acceptReturn = accept([self _sock], (struct sockaddr*)addr, (OPTLEN*)&len); _events &= ~NSStreamEventHasBytesAvailable; if (socketError(acceptReturn)) { // test for real error diff --git a/Source/NSISO8601DateFormatter.m b/Source/NSISO8601DateFormatter.m index 6d51afec6f..c093c4d94d 100644 --- a/Source/NSISO8601DateFormatter.m +++ b/Source/NSISO8601DateFormatter.m @@ -30,40 +30,6 @@ @implementation NSISO8601DateFormatter -- (instancetype) init -{ - self = [super init]; - if (self != nil) - { - _formatter = [[NSDateFormatter alloc] init]; - _timeZone = RETAIN([NSTimeZone localTimeZone]); - _formatOptions = NSISO8601DateFormatWithInternetDateTime; - } - return self; -} - -- (oneway void) dealloc -{ - RELEASE(_formatter); - RELEASE(_timeZone); - [super dealloc]; -} - -- (NSTimeZone *) timeZone -{ - return _timeZone; -} - -- (void) setTimeZone: (NSTimeZone *)tz -{ - _timeZone = tz; -} - -- (NSISO8601DateFormatOptions) formatOptions -{ - return _formatOptions; -} - - (NSString *) _buildFormatWithOptions { NSString *result = @""; @@ -73,8 +39,8 @@ - (NSString *) _buildFormatWithOptions { result = [result stringByAppendingString: @"yyyy"]; } - if (_formatOptions & NSISO8601DateFormatWithDashSeparatorInDate && - _formatOptions & NSISO8601DateFormatWithMonth) + if ((_formatOptions & NSISO8601DateFormatWithDashSeparatorInDate) + && (_formatOptions & NSISO8601DateFormatWithMonth)) { result = [result stringByAppendingString: @"-"]; } @@ -82,8 +48,8 @@ - (NSString *) _buildFormatWithOptions { result = [result stringByAppendingString: @"MM"]; } - if (_formatOptions & NSISO8601DateFormatWithDashSeparatorInDate && - _formatOptions & NSISO8601DateFormatWithDay) + if ((_formatOptions & NSISO8601DateFormatWithDashSeparatorInDate) + && (_formatOptions & NSISO8601DateFormatWithDay)) { result = [result stringByAppendingString: @"-"]; } @@ -93,8 +59,8 @@ - (NSString *) _buildFormatWithOptions } // Build time... - if (_formatOptions & NSISO8601DateFormatWithSpaceBetweenDateAndTime && - _formatOptions & NSISO8601DateFormatWithTime) + if ((_formatOptions & NSISO8601DateFormatWithSpaceBetweenDateAndTime) + && (_formatOptions & NSISO8601DateFormatWithTime)) { result = [result stringByAppendingString: @" "]; } @@ -122,7 +88,7 @@ - (NSString *) _buildFormatWithOptions { if (_formatOptions & NSISO8601DateFormatWithColonSeparatorInTimeZone) { - result = [result stringByAppendingString: @"ZZ:ZZ"]; + result = [result stringByAppendingString: @"ZZZZZ"]; } else { @@ -133,38 +99,22 @@ - (NSString *) _buildFormatWithOptions return result; } -- (void) setFormatOptions: (NSISO8601DateFormatOptions)options -{ - _formatOptions = options; -} - -- (NSString *) stringFromDate: (NSDate *)date -{ - NSString *formatString = [self _buildFormatWithOptions]; - [_formatter setTimeZone: _timeZone]; - [_formatter setDateFormat: formatString]; - return [_formatter stringFromDate: date]; -} - - (NSDate *) dateFromString: (NSString *)string { NSString *formatString = [self _buildFormatWithOptions]; + [_formatter setTimeZone: _timeZone]; [_formatter setDateFormat: formatString]; return [_formatter dateFromString: string]; } -+ (NSString *) stringFromDate: (NSDate *)date - timeZone: (NSTimeZone *)timeZone - formatOptions: (NSISO8601DateFormatOptions)formatOptions +- (oneway void) dealloc { - NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init]; - AUTORELEASE(formatter); - [formatter setTimeZone: timeZone]; - [formatter setFormatOptions: formatOptions]; - return [formatter stringFromDate: date]; + RELEASE(_formatter); + RELEASE(_timeZone); + [super dealloc]; } - + - (void) encodeWithCoder: (NSCoder *)coder { if ([coder allowsKeyedCoding]) @@ -179,6 +129,23 @@ - (void) encodeWithCoder: (NSCoder *)coder } } +- (NSISO8601DateFormatOptions) formatOptions +{ + return _formatOptions; +} + +- (instancetype) init +{ + self = [super init]; + if (self != nil) + { + _formatter = [[NSDateFormatter alloc] init]; + _timeZone = RETAIN([NSTimeZone localTimeZone]); + _formatOptions = NSISO8601DateFormatWithInternetDateTime; + } + return self; +} + - (id) initWithCoder: (NSCoder *)decoder { if ((self = [super init]) != nil) @@ -191,10 +158,47 @@ - (id) initWithCoder: (NSCoder *)decoder else { ASSIGN(_timeZone, [decoder decodeObject]); - [decoder decodeValueOfObjCType: @encode(NSUInteger) at: &_formatOptions]; + [decoder decodeValueOfObjCType: @encode(NSUInteger) + at: &_formatOptions]; } } return self; } +- (void) setFormatOptions: (NSISO8601DateFormatOptions)options +{ + _formatOptions = options; +} + +- (void) setTimeZone: (NSTimeZone *)tz +{ + _timeZone = tz; +} + +- (NSString *) stringFromDate: (NSDate *)date +{ + NSString *formatString = [self _buildFormatWithOptions]; + + [_formatter setTimeZone: _timeZone]; + [_formatter setDateFormat: formatString]; + return [_formatter stringFromDate: date]; +} + ++ (NSString *) stringFromDate: (NSDate *)date + timeZone: (NSTimeZone *)timeZone + formatOptions: (NSISO8601DateFormatOptions)formatOptions +{ + NSISO8601DateFormatter *formatter; + + formatter = AUTORELEASE([[NSISO8601DateFormatter alloc] init]); + [formatter setTimeZone: timeZone]; + [formatter setFormatOptions: formatOptions]; + return [formatter stringFromDate: date]; +} + +- (NSTimeZone *) timeZone +{ + return _timeZone; +} + @end diff --git a/Source/win32/NSStream.m b/Source/win32/NSStream.m index b66e78deed..eab31f7045 100644 --- a/Source/win32/NSStream.m +++ b/Source/win32/NSStream.m @@ -961,6 +961,15 @@ + (void) getStreamsToHost: (NSHost *)host #endif } + //IPv6 + if(!ins) + { + #if defined(AF_INET6) + ins = (GSSocketStream*)AUTORELEASE([[GSInet6InputStream alloc] initToAddr: address port: port]); + outs = (GSSocketStream*)AUTORELEASE([[GSInet6OutputStream alloc] initToAddr: address port: port]); + #endif + } + /* * Windows only permits a single event to be associated with a socket * at any time, but the runloop system only allows an event handle to diff --git a/base.xcodeproj/project.pbxproj b/base.xcodeproj/project.pbxproj index a2b66c3642..72908ac6de 100644 --- a/base.xcodeproj/project.pbxproj +++ b/base.xcodeproj/project.pbxproj @@ -4062,6 +4062,7 @@ ); INFOPLIST_FILE = "Support/Foundation/Foundation-Info.plist"; LIBRARY_SEARCH_PATHS = /opt/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.14; OTHER_CFLAGS = ( "-DGNUSTEP", "-DNeXT_RUNTIME", @@ -4100,6 +4101,7 @@ ); INFOPLIST_FILE = "Support/Foundation/Foundation-Info.plist"; LIBRARY_SEARCH_PATHS = /opt/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.14; OTHER_CFLAGS = ( "-DGNUSTEP", "-DNeXT_RUNTIME", From b68e304a39c4be7ffc1583e8fd17c2fbf5bc810b Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sun, 26 Nov 2023 00:54:06 -0500 Subject: [PATCH 3/4] Fix some warnings and suppress some unavoidable ones --- Source/GSSocketStream.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Source/GSSocketStream.m b/Source/GSSocketStream.m index 0870992207..2bffd9e15a 100644 --- a/Source/GSSocketStream.m +++ b/Source/GSSocketStream.m @@ -1645,6 +1645,11 @@ - (void) _sendEvent: (NSStreamEvent)event } } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wincompatible-pointer-types" - (BOOL) _setSocketAddress: (NSString*)address port: (NSInteger)port family: (NSInteger)family @@ -1670,7 +1675,7 @@ - (BOOL) _setSocketAddress: (NSString*)address } else { - [self _setAddress: (struct sockaddr*)&peer]; + [self _setAddress: (struct sockaddr_storage*)&peer]; return YES; } } @@ -2934,6 +2939,11 @@ - (void) acceptWithInputStream: (NSInputStream **)inputStream */ } +#pragma GCC diagnostic pop // cast align + +#pragma GCC diagnostic pop // incompatible pointer types... + + - (void) _dispatch { #if defined(_WIN32) From 8525ee19a806823aeab67d6c37d5972e98fc2f07 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sun, 26 Nov 2023 01:33:35 -0500 Subject: [PATCH 4/4] Initial IPv6 test --- Tests/base/NSStream/ipv6test.m | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 Tests/base/NSStream/ipv6test.m diff --git a/Tests/base/NSStream/ipv6test.m b/Tests/base/NSStream/ipv6test.m new file mode 100644 index 0000000000..be6757a410 --- /dev/null +++ b/Tests/base/NSStream/ipv6test.m @@ -0,0 +1,84 @@ +#if defined(GNUSTEP_BASE_LIBRARY) +/** + * This test tests IPv6 using NSStream + */ +#import +#import "Testing.h" + +@interface IPV6Server : NSObject + +- (void) main; + +@end + +@implementation IPV6Server + +- (void) main +{ +} + +@end + +int main() +{ + NSAutoreleasePool *arp = [NSAutoreleasePool new]; + + NSInputStream *inputStream; + NSOutputStream *outputStream; + IPV6Server *svr = [[IPV6Server alloc] init]; + + NSString *ipv6ServerAddress = @"::1"; // Replace with your actual IPv6 server address + uint16_t port = 12345; // Replace with the actual port number + + // Resolve the IPv6 address using NSHost + NSHost *host = [NSHost hostWithName: ipv6ServerAddress]; + NSArray *addresses = [host addresses]; + + PASS([addresses count] > 0, "Resolve IPv6 address"); + + NSString *ipv6Address = [addresses objectAtIndex: 0]; + NSThread *thread = [[NSThread alloc] initWithTarget: svr selector: @selector(main) object: nil]; + + PASS(thread != nil, "Created thread for server"); + + [thread start]; + + [NSStream getStreamsToHost: [NSHost hostWithName: ipv6Address] + port: port + inputStream: &inputStream + outputStream: &outputStream]; + + [inputStream open]; + [outputStream open]; + + // Perform your tests here to validate the IPv6 stream + // You can write and read data from the stream and assert the expected results + // For example: + + NSString *testData = @"Test Data"; + NSData *dataToWrite = [testData dataUsingEncoding:NSUTF8StringEncoding]; + NSInteger bytesWritten = [outputStream write: [dataToWrite bytes] maxLength: [dataToWrite length]]; + + PASS(bytesWritten > 0, "Write data to the stream"); + + uint8_t buffer[1024]; + NSInteger bytesRead = [inputStream read:buffer maxLength:1024]; + NSString *receivedString = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding]; + + PASS(bytesRead > 0, "Read data from the stream"); + PASS([receivedString isEqualToString: testData], "Received data matches the expected data"); + + [inputStream close]; + [outputStream close]; + + [arp release]; + arp = nil; + + return 0; +} +#else +int main() +{ + return 0; +} +#endif