Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix out-of-memory checking, a compiler warning, and allow subclassing #100

Open
wants to merge 11 commits into from

2 participants

@evands
  1. Error check the results of realloc() and malloc() to ensure we haven't failed to allocate sufficient buffers

  2. This simple change suppresses the 'undeclared selector' warning seen during compilation if that warning is enabled. The selectors in question are intended to be undeclared.

  3. by using [self class] instead of the hardcoded class name, subclasses can propagate to accepted sockets.

Evan D. Scho... and others added some commits
Evan D. Schoenberg, M.D Suppress an undeclared selector warning from the compiler; this selec…
…tor is intentionally undeclared and nonexistant.
a8af586
Evan D. Schoenberg, M.D Allow subclassing of GCDAsyncSocket such that accepted sockets are al…
…so the intended class.
762f03a
Evan D. Schoenberg, M.D Check the results of realloc() for out of memory conditions and fail …
…appropriately. Although an out of memory condition is unlikely on a modern system, it is a possibility which must be considered.
24aafc0
Evan D. Schoenberg, M.D Merge branch 'master' of github.com:evands/CocoaAsyncSocket into HEAD b08c7e7
Evan D. Schoenberg, M.D Error check the return value of malloc() to ensure we were able to cr…
…eate a sufficient preBuffer
c67b9f3
Evan D. Schoenberg, M.D Added a check against TARGET_OS_ATV2, which must be defined by the pr…
…oject, to allow avoiding reference to UIKit where necessary
df86e50
Evan D. Schoenberg, M.D Fix an uninitialized variable warning from clang when compiling for OS X fe8da72
Evan D. Schoenberg, M.D Merge branch 'uninitialized-variable-fix' 516ae10
Evan D. Schoenberg, M.D Merge branch 'master' of github.com:evands/CocoaAsyncSocket 56f46ee
Evan D. Schoenberg, M.D Merge branch 'master' of git://github.com/robbiehanson/CocoaAsyncSocket 415c830
Evan D. Schoenberg, M.D Merge branch 'master' of git://github.com/robbiehanson/CocoaAsyncSocket 84e77d1
@robbiehanson robbiehanson added this to the 7.4 milestone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 17, 2012
  1. Suppress an undeclared selector warning from the compiler; this selec…

    Evan D. Schoenberg, M.D authored
    …tor is intentionally undeclared and nonexistant.
Commits on Nov 18, 2012
  1. Allow subclassing of GCDAsyncSocket such that accepted sockets are al…

    Evan D. Schoenberg, M.D authored
    …so the intended class.
Commits on Dec 3, 2012
  1. Check the results of realloc() for out of memory conditions and fail …

    Evan D. Schoenberg, M.D authored
    …appropriately. Although an out of memory condition is unlikely on a modern system, it is a possibility which must be considered.
  2. Merge branch 'master' of github.com:evands/CocoaAsyncSocket into HEAD

    Evan D. Schoenberg, M.D authored
Commits on Dec 4, 2012
  1. Error check the return value of malloc() to ensure we were able to cr…

    Evan D. Schoenberg, M.D authored
    …eate a sufficient preBuffer
Commits on Mar 3, 2013
  1. Added a check against TARGET_OS_ATV2, which must be defined by the pr…

    Evan D. Schoenberg, M.D authored
    …oject, to allow avoiding reference to UIKit where necessary
Commits on May 6, 2013
  1. Merge branch 'uninitialized-variable-fix'

    Evan D. Schoenberg, M.D authored
Commits on Sep 22, 2013
  1. Merge branch 'master' of github.com:evands/CocoaAsyncSocket

    Evan D. Schoenberg, M.D authored
Commits on Nov 6, 2013
Commits on Jan 12, 2014
  1. Merge branch 'master' of git://github.com/robbiehanson/CocoaAsyncSocket

    Evan D. Schoenberg, M.D authored
This page is out of date. Refresh to see the latest.
Showing with 140 additions and 83 deletions.
  1. +134 −79 GCD/GCDAsyncSocket.m
  2. +6 −4 GCD/GCDAsyncUdpSocket.m
View
213 GCD/GCDAsyncSocket.m
@@ -343,7 +343,7 @@ @interface GCDAsyncSocketPreBuffer : NSObject
- (id)initWithCapacity:(size_t)numBytes;
-- (void)ensureCapacityForWrite:(size_t)numBytes;
+- (BOOL)ensureCapacityForWrite:(size_t)numBytes;
- (size_t)availableBytes;
- (uint8_t *)readBuffer;
@@ -370,7 +370,9 @@ - (id)initWithCapacity:(size_t)numBytes
{
preBufferSize = numBytes;
preBuffer = malloc(preBufferSize);
-
+ if (!preBuffer)
+ return nil;
+
readPointer = preBuffer;
writePointer = preBuffer;
}
@@ -383,8 +385,9 @@ - (void)dealloc
free(preBuffer);
}
-- (void)ensureCapacityForWrite:(size_t)numBytes
+- (BOOL)ensureCapacityForWrite:(size_t)numBytes
{
+ BOOL success;
size_t availableSpace = preBufferSize - (writePointer - readPointer);
if (numBytes > availableSpace)
@@ -393,16 +396,26 @@ - (void)ensureCapacityForWrite:(size_t)numBytes
size_t newPreBufferSize = preBufferSize + additionalBytes;
uint8_t *newPreBuffer = realloc(preBuffer, newPreBufferSize);
-
- size_t readPointerOffset = readPointer - preBuffer;
- size_t writePointerOffset = writePointer - preBuffer;
-
- preBuffer = newPreBuffer;
- preBufferSize = newPreBufferSize;
-
- readPointer = preBuffer + readPointerOffset;
- writePointer = preBuffer + writePointerOffset;
+ if (newPreBuffer)
+ {
+ size_t readPointerOffset = readPointer - preBuffer;
+ size_t writePointerOffset = writePointer - preBuffer;
+
+ preBuffer = newPreBuffer;
+ preBufferSize = newPreBufferSize;
+
+ readPointer = preBuffer + readPointerOffset;
+ writePointer = preBuffer + writePointerOffset;
+
+ success = YES;
+ }
+ else
+ success = NO;
}
+ else
+ success = YES;
+
+ return success;
}
- (size_t)availableBytes
@@ -1794,9 +1807,9 @@ - (BOOL)doAccept:(int)parentSocketFD
// Create GCDAsyncSocket instance for accepted socket
- GCDAsyncSocket *acceptedSocket = [[GCDAsyncSocket alloc] initWithDelegate:theDelegate
- delegateQueue:delegateQueue
- socketQueue:childSocketQueue];
+ GCDAsyncSocket *acceptedSocket = [[[self class] alloc] initWithDelegate:theDelegate
+ delegateQueue:delegateQueue
+ socketQueue:childSocketQueue];
if (isIPv4)
acceptedSocket->socket4FD = childSocketFD;
@@ -2997,6 +3010,17 @@ - (NSError *)connectionClosedError
return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketClosedError userInfo:userInfo];
}
+- (NSError *)outOfMemoryError
+{
+ NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncSocketOutOfMemoryError",
+ @"GCDAsyncSocket", [NSBundle mainBundle],
+ @"Out of memory", nil);
+
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
+
+ return [NSError errorWithDomain:GCDAsyncSocketErrorDomain code:GCDAsyncSocketOtherError userInfo:userInfo];
+}
+
- (NSError *)otherError:(NSString *)errMsg
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
@@ -4077,19 +4101,20 @@ - (void)flushSSLBuffers
CFIndex defaultBytesToRead = (1024 * 4);
- [preBuffer ensureCapacityForWrite:defaultBytesToRead];
-
- uint8_t *buffer = [preBuffer writeBuffer];
-
- CFIndex result = CFReadStreamRead(readStream, buffer, defaultBytesToRead);
- LogVerbose(@"%@ - CFReadStreamRead(): result = %i", THIS_METHOD, (int)result);
-
- if (result > 0)
+ if ([preBuffer ensureCapacityForWrite:defaultBytesToRead])
{
- [preBuffer didWrite:result];
+ uint8_t *buffer = [preBuffer writeBuffer];
+
+ CFIndex result = CFReadStreamRead(readStream, buffer, defaultBytesToRead);
+ LogVerbose(@"%@ - CFReadStreamRead(): result = %i", THIS_METHOD, (int)result);
+
+ if (result > 0)
+ {
+ [preBuffer didWrite:result];
+ }
+
+ flags &= ~kSecureSocketHasBytesAvailable;
}
-
- flags &= ~kSecureSocketHasBytesAvailable;
}
return;
@@ -4133,32 +4158,33 @@ - (void)flushSSLBuffers
// Make sure there's enough room in the prebuffer
- [preBuffer ensureCapacityForWrite:estimatedBytesAvailable];
-
- // Read data into prebuffer
-
- uint8_t *buffer = [preBuffer writeBuffer];
- size_t bytesRead = 0;
-
- OSStatus result = SSLRead(sslContext, buffer, (size_t)estimatedBytesAvailable, &bytesRead);
- LogVerbose(@"%@ - read from secure socket = %u", THIS_METHOD, (unsigned)bytesRead);
-
- if (bytesRead > 0)
- {
- [preBuffer didWrite:bytesRead];
- }
-
- LogVerbose(@"%@ - prebuffer.length = %zu", THIS_METHOD, [preBuffer availableBytes]);
-
- if (result != noErr)
+ if ([preBuffer ensureCapacityForWrite:estimatedBytesAvailable])
{
+ // Read data into prebuffer
+
+ uint8_t *buffer = [preBuffer writeBuffer];
+ size_t bytesRead = 0;
+
+ OSStatus result = SSLRead(sslContext, buffer, (size_t)estimatedBytesAvailable, &bytesRead);
+ LogVerbose(@"%@ - read from secure socket = %u", THIS_METHOD, (unsigned)bytesRead);
+
+ if (bytesRead > 0)
+ {
+ [preBuffer didWrite:bytesRead];
+ }
+
+ LogVerbose(@"%@ - prebuffer.length = %zu", THIS_METHOD, [preBuffer availableBytes]);
+
+ if (result != noErr)
+ {
+ done = YES;
+ }
+ else
+ {
+ updateEstimatedBytesAvailable();
+ }
+ } else
done = YES;
- }
- else
- {
- updateEstimatedBytesAvailable();
- }
-
} while (!done && estimatedBytesAvailable > 0);
}
@@ -4233,7 +4259,11 @@ - (void)doReadData
else
hasBytesAvailable = NO;
- #endif
+ #else
+ // This should never occur because usingCFStreamForTLS is only TRUE on iPhone, but it silences
+ // an uninitialized variable warning.
+ hasBytesAvailable = NO;
+ #endif
}
else
{
@@ -4492,9 +4522,14 @@ - (void)doReadData
if (readIntoPreBuffer)
{
- [preBuffer ensureCapacityForWrite:bytesToRead];
-
- buffer = [preBuffer writeBuffer];
+ if ([preBuffer ensureCapacityForWrite:bytesToRead])
+ buffer = [preBuffer writeBuffer];
+ else
+ {
+ error = [self outOfMemoryError];
+ [self closeWithError:error];
+ return;
+ }
}
else
{
@@ -4727,19 +4762,26 @@ - (void)doReadData
// Copy excess data into preBuffer
LogVerbose(@"copying %ld overflow bytes into preBuffer", (long)overflow);
- [preBuffer ensureCapacityForWrite:overflow];
-
- uint8_t *overflowBuffer = buffer + underflow;
- memcpy([preBuffer writeBuffer], overflowBuffer, overflow);
-
- [preBuffer didWrite:overflow];
- LogVerbose(@"preBuffer.length = %zu", [preBuffer availableBytes]);
-
- // Note: The completeCurrentRead method will trim the buffer for us.
-
- currentRead->bytesDone += underflow;
- totalBytesReadForCurrentRead += underflow;
- done = YES;
+ if ([preBuffer ensureCapacityForWrite:overflow])
+ {
+ uint8_t *overflowBuffer = buffer + underflow;
+ memcpy([preBuffer writeBuffer], overflowBuffer, overflow);
+
+ [preBuffer didWrite:overflow];
+ LogVerbose(@"preBuffer.length = %zu", [preBuffer availableBytes]);
+
+ // Note: The completeCurrentRead method will trim the buffer for us.
+
+ currentRead->bytesDone += underflow;
+ totalBytesReadForCurrentRead += underflow;
+ done = YES;
+ }
+ else
+ {
+ error = [self outOfMemoryError];
+ [self closeWithError:error];
+ return;
+ }
}
else
{
@@ -5959,11 +6001,17 @@ - (OSStatus)sslReadWithBuffer:(void *)buffer length:(size_t *)bufferLength
LogVerbose(@"%@: Reading into sslPreBuffer...", THIS_METHOD);
- [sslPreBuffer ensureCapacityForWrite:socketFDBytesAvailable];
-
- readIntoPreBuffer = YES;
- bytesToRead = (size_t)socketFDBytesAvailable;
- buf = [sslPreBuffer writeBuffer];
+ if ([sslPreBuffer ensureCapacityForWrite:socketFDBytesAvailable])
+ {
+ readIntoPreBuffer = YES;
+ bytesToRead = (size_t)socketFDBytesAvailable;
+ buf = [sslPreBuffer writeBuffer];
+ }
+ else
+ {
+ socketFDBytesAvailable = 0;
+ return errSSLClosedAbort;
+ }
}
else
{
@@ -6481,14 +6529,18 @@ - (void)ssl_startTLS
if (preBufferLength > 0)
{
- [sslPreBuffer ensureCapacityForWrite:preBufferLength];
-
- memcpy([sslPreBuffer writeBuffer], [preBuffer readBuffer], preBufferLength);
- [preBuffer didRead:preBufferLength];
- [sslPreBuffer didWrite:preBufferLength];
+ if ([sslPreBuffer ensureCapacityForWrite:preBufferLength])
+ {
+ memcpy([sslPreBuffer writeBuffer], [preBuffer readBuffer], preBufferLength);
+ [preBuffer didRead:preBufferLength];
+ [sslPreBuffer didWrite:preBufferLength];
+ sslErrCode = noErr;
+ }
+ else
+ sslErrCode = errSSLClosedAbort;
}
-
- sslErrCode = noErr;
+ else
+ sslErrCode = noErr;
// Start the SSL Handshake process
@@ -6712,11 +6764,14 @@ + (void)cfstreamThread { @autoreleasepool
// We can't run the run loop unless it has an associated input source or a timer.
// So we'll just create a timer that will never fire - unless the server runs for decades.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
[NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow]
target:self
selector:@selector(ignore:)
userInfo:nil
repeats:YES];
+#pragma clang diagnostic pop
[[NSRunLoop currentRunLoop] run];
View
10 GCD/GCDAsyncUdpSocket.m
@@ -424,10 +424,12 @@ - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQu
sendQueue = [[NSMutableArray alloc] initWithCapacity:5];
#if TARGET_OS_IPHONE
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationWillEnterForeground:)
- name:UIApplicationWillEnterForegroundNotification
- object:nil];
+ #ifndef TARGET_OS_ATV2
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(applicationWillEnterForeground:)
+ name:UIApplicationWillEnterForegroundNotification
+ object:nil];
+ #endif
#endif
}
return self;
Something went wrong with that request. Please try again.