Skip to content

Commit c2b2785

Browse files
committed
Fix NSURLSession memory management of libdispatch objects and overrelease in GSHTTPURLProtocol.
1 parent eea71ab commit c2b2785

File tree

7 files changed

+48
-13
lines changed

7 files changed

+48
-13
lines changed

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2023-01-13 Frederik Seiffert <[email protected]>
2+
3+
* Source/GSEasyHandle.m:
4+
* Source/GSMultiHandle.m:
5+
* Source/GSTimeoutSource.h:
6+
* Source/GSTimeoutSource.m:
7+
* Source/NSURLSession.m:
8+
Fix NSURLSession memory management of libdispatch objects.
9+
* Source/GSHTTPURLProtocol.m:
10+
Fix overrelease.
11+
112
2023-01-13 Frederik Seiffert <[email protected]>
213

314
* Headers/Foundation/NSURLSession.h:

Source/GSEasyHandle.m

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ - (void) dealloc
195195
curl_slist_free_all(_headerList);
196196
free(_errorBuffer);
197197
DESTROY(_config);
198+
[_timeoutTimer cancel];
198199
DESTROY(_timeoutTimer);
199200
DESTROY(_URL);
200201
[super dealloc];
@@ -217,6 +218,7 @@ - (GSTimeoutSource*) timeoutTimer
217218

218219
- (void) setTimeoutTimer: (GSTimeoutSource*)timer
219220
{
221+
[_timeoutTimer cancel];
220222
ASSIGN(_timeoutTimer, timer);
221223
}
222224

@@ -234,10 +236,13 @@ - (void) resetTimer
234236
{
235237
// simply create a new timer with the same queue, timeout and handler
236238
// this must cancel the old handler and reset the timer
237-
DESTROY(_timeoutTimer);
238-
_timeoutTimer = [[GSTimeoutSource alloc] initWithQueue: [_timeoutTimer queue]
239-
milliseconds: [_timeoutTimer milliseconds]
240-
handler: [_timeoutTimer handler]];
239+
if (_timeoutTimer) {
240+
[_timeoutTimer cancel];
241+
_timeoutTimer = [[GSTimeoutSource alloc] initWithQueue: [_timeoutTimer queue]
242+
milliseconds: [_timeoutTimer milliseconds]
243+
handler: [_timeoutTimer handler]];
244+
DESTROY(_timeoutTimer);
245+
}
241246
}
242247

243248
- (void) setupCallbacks

Source/GSHTTPURLProtocol.m

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,17 +592,14 @@ - (void) configureEasyHandleForRequest: (NSURLRequest*)request
592592
[hh addEntriesFromDictionary:
593593
[self transformLowercaseKeyForHTTPHeaders: HTTPHeaders]];
594594

595-
NSArray *curlHeaders = [self curlHeadersForHTTPHeaders: hh];
595+
NSMutableArray *curlHeaders = [self curlHeadersForHTTPHeaders: hh];
596596
if ([[request HTTPMethod] isEqualToString:@"POST"]
597597
&& [[request HTTPBody] length] > 0
598598
&& [request valueForHTTPHeaderField: @"Content-Type"] == nil)
599599
{
600-
NSMutableArray *temp = [curlHeaders mutableCopy];
601-
[temp addObject: @"Content-Type:application/x-www-form-urlencoded"];
602-
curlHeaders = temp;
600+
[curlHeaders addObject: @"Content-Type:application/x-www-form-urlencoded"];
603601
}
604602
[_easyHandle setCustomHeaders: curlHeaders];
605-
RELEASE(curlHeaders);
606603

607604
NSInteger timeoutInterval = [request timeoutInterval] * 1000;
608605
GSTimeoutSource *timeoutTimer;
@@ -874,7 +871,7 @@ - (NSDictionary*) transformLowercaseKeyForHTTPHeaders: (NSDictionary*)HTTPHeader
874871
// expects.
875872
//
876873
// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_HTTPHEADER.html
877-
- (NSArray*) curlHeadersForHTTPHeaders: (NSDictionary*)HTTPHeaders
874+
- (NSMutableArray*) curlHeadersForHTTPHeaders: (NSDictionary*)HTTPHeaders
878875
{
879876
NSMutableArray *result = [NSMutableArray array];
880877
NSMutableSet *names = [NSMutableSet set];
@@ -951,7 +948,7 @@ - (NSArray*) curlHeadersForHTTPHeaders: (NSDictionary*)HTTPHeaders
951948
[result addObject: [NSString stringWithFormat: @"%@:", k]];
952949
}
953950

954-
return AUTORELEASE([result copy]);
951+
return result;
955952
}
956953

957954
// Any header values that should be passed to libcurl

Source/GSMultiHandle.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,11 @@ - (void) dealloc
108108
NSEnumerator *e;
109109
GSEasyHandle *handle;
110110

111+
[_timeoutSource cancel];
111112
DESTROY(_timeoutSource);
112113

114+
dispatch_release(_queue);
115+
113116
e = [_easyHandles objectEnumerator];
114117
while (nil != (handle = [e nextObject]))
115118
{
@@ -193,10 +196,12 @@ - (void) updateTimeoutTimerToValue: (NSInteger)value
193196
// of milliseconds.
194197
if (-1 == value)
195198
{
199+
[_timeoutSource cancel];
196200
DESTROY(_timeoutSource);
197201
}
198202
else if (0 == value)
199203
{
204+
[_timeoutSource cancel];
200205
DESTROY(_timeoutSource);
201206
dispatch_async(_queue,
202207
^{
@@ -207,6 +212,7 @@ - (void) updateTimeoutTimerToValue: (NSInteger)value
207212
{
208213
if (nil == _timeoutSource || value != [_timeoutSource milliseconds])
209214
{
215+
[_timeoutSource cancel];
210216
DESTROY(_timeoutSource);
211217
_timeoutSource = [[GSTimeoutSource alloc] initWithQueue: _queue
212218
milliseconds: value
@@ -438,12 +444,14 @@ - (void) dealloc
438444
if (_readSource)
439445
{
440446
dispatch_source_cancel(_readSource);
447+
dispatch_release(_readSource);
441448
}
442449
_readSource = NULL;
443450

444451
if (_writeSource)
445452
{
446453
dispatch_source_cancel(_writeSource);
454+
dispatch_release(_writeSource);
447455
}
448456
_writeSource = NULL;
449457
[super dealloc];

Source/GSTimeoutSource.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
dispatch_block_t _handler;
1818
}
1919

20+
- (void) cancel;
21+
2022
- (NSInteger) milliseconds;
2123

2224
- (dispatch_queue_t) queue;

Source/GSTimeoutSource.m

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ - (instancetype) initWithQueue: (dispatch_queue_t)queue
99
if (nil != (self = [super init]))
1010
{
1111
_queue = queue;
12-
_handler = handler;
12+
_handler = Block_copy(handler);
1313
_milliseconds = milliseconds;
1414
_rawSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue);
1515

@@ -26,10 +26,20 @@ - (instancetype) initWithQueue: (dispatch_queue_t)queue
2626

2727
- (void) dealloc
2828
{
29-
dispatch_source_cancel(_rawSource);
29+
[self cancel];
30+
Block_release(_handler);
3031
[super dealloc];
3132
}
3233

34+
- (void) cancel
35+
{
36+
if (_rawSource) {
37+
dispatch_source_cancel(_rawSource);
38+
dispatch_release(_rawSource);
39+
_rawSource = NULL;
40+
}
41+
}
42+
3343
- (NSInteger) milliseconds
3444
{
3545
return _milliseconds;

Source/NSURLSession.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ - (void) dealloc
976976
DESTROY(_protocolBag);
977977
DESTROY(_dataCompletionHandler);
978978
DESTROY(_knownBody);
979+
dispatch_release(_workQueue);
979980
[super dealloc];
980981
}
981982

@@ -1218,6 +1219,7 @@ - (id) copyWithZone: (NSZone*)zone
12181219
copy->_state = _state;
12191220
copy->_error = [_error copyWithZone: zone];
12201221
copy->_session = _session;
1222+
dispatch_retain(_workQueue);
12211223
copy->_workQueue = _workQueue;
12221224
copy->_suspendCount = _suspendCount;
12231225
copy->_protocolLock = [_protocolLock copy];

0 commit comments

Comments
 (0)