ObjFW  Check-in [b8aeb99da6]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Don't use performSelector: if method returns void
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b8aeb99da6cd438b0f77e43dd68fa2ef867c4b289bd9a4d654112d0810b497de
User & Date: js 2025-04-22 13:43:45.910
Context
2025-04-22
13:58
class_registerAlias_np(): Fix return type check-in: 0940359d1d user: js tags: trunk
13:43
Don't use performSelector: if method returns void check-in: b8aeb99da6 user: js tags: trunk
10:59
Deprecate -[OFArray makeObjectsPerformSelector:] check-in: 1279330140 user: js tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/OFHTTPServer.m.
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
	[stream asyncReadLine];
}

-    (bool)socket: (OFStreamSocket *)sock
  didAcceptSocket: (OFStreamSocket *)acceptedSocket
	exception: (id)exception
{
	SEL selector = (_usesTLS
	    ? @selector(of_startTLSWithSocket:) : @selector(of_handleStream:));

	if (exception != nil) {
		if ([_delegate respondsToSelector: @selector(
		    server:didEncounterException:request:response:)]) {
			[_delegate	   server: self
			    didEncounterException: exception
					  request: nil
					 response: nil];







<
<
<







968
969
970
971
972
973
974



975
976
977
978
979
980
981
	[stream asyncReadLine];
}

-    (bool)socket: (OFStreamSocket *)sock
  didAcceptSocket: (OFStreamSocket *)acceptedSocket
	exception: (id)exception
{



	if (exception != nil) {
		if ([_delegate respondsToSelector: @selector(
		    server:didEncounterException:request:response:)]) {
			[_delegate	   server: self
			    didEncounterException: exception
					  request: nil
					 response: nil];
998
999
1000
1001
1002
1003
1004


1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016



1017



1018
1019
1020
1021
1022
1023
1024
#endif

		return false;
	}

#ifdef OF_HAVE_THREADS
	if (_numberOfThreads > 1) {


		OFHTTPServerThread *thread =
		    [_threadPool objectAtIndex: _nextThreadIndex];

		if (++_nextThreadIndex >= _numberOfThreads - 1)
			_nextThreadIndex = 0;

		[self performSelector: selector
			     onThread: thread
			   withObject: acceptedSocket
			waitUntilDone: false];
	} else
#endif



		[self performSelector: selector withObject: acceptedSocket];




	return true;
}

- (void)streamDidPerformServerHandshake: (OFTLSStream *)stream
			      exception: (id)exception
{







>
>










|

>
>
>
|
>
>
>







995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
#endif

		return false;
	}

#ifdef OF_HAVE_THREADS
	if (_numberOfThreads > 1) {
		SEL selector = (_usesTLS ? @selector(of_startTLSWithSocket:) :
		    @selector(of_handleStream:));
		OFHTTPServerThread *thread =
		    [_threadPool objectAtIndex: _nextThreadIndex];

		if (++_nextThreadIndex >= _numberOfThreads - 1)
			_nextThreadIndex = 0;

		[self performSelector: selector
			     onThread: thread
			   withObject: acceptedSocket
			waitUntilDone: false];
	} else {
#endif
		if (_usesTLS)
			[self of_startTLSWithSocket: acceptedSocket];
		else
			[self of_handleStream: acceptedSocket];
#ifdef OF_HAVE_THREADS
	}
#endif

	return true;
}

- (void)streamDidPerformServerHandshake: (OFTLSStream *)stream
			      exception: (id)exception
{
Changes to src/OFIRIHandler.m.
213
214
215
216
217
218
219




220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252



253
254
255
256
257
258
259
260
261
262
263




264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301



302
303
304
305
306
307
308
			       andType: NULL
			       forName: name
			   ofItemAtIRI: IRI];

	return data;
}





- (void)getExtendedAttributeData: (OFData **)data
			 andType: (id *)type
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	/*
	 * Only call into -[extendedAttributeDataForName:ofItemAtIRI:] if it
	 * has been overridden. This is to be backwards-compatible to
	 * subclasses that predate the introduction of
	 * -[getExtendedAttributeData:andType:forName:ofItemAtIRI:].
	 * Without this check, this would result in an infinite loop.
	 */
	SEL selector = @selector(extendedAttributeDataForName:ofItemAtIRI:);

	if (class_getMethodImplementation(object_getClass(self), selector) !=
	    class_getMethodImplementation([OFIRIHandler class], selector)) {
		/*
		 * Use -[performSelector:withObject:withObject:] to avoid
		 * deprecation warning. This entire thing is purely for
		 * backwards compatibility.
		 */
		*data = [self performSelector: selector
				   withObject: name
				   withObject: IRI];

		if (type != NULL)
			*type = nil;

		return;
	}

	OF_UNRECOGNIZED_SELECTOR
}




- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	[self setExtendedAttributeData: data
			       andType: nil
			       forName: name
			   ofItemAtIRI: IRI];
}





- (void)setExtendedAttributeData: (OFData *)data
			 andType: (id)type
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{

	if (type == nil) {
		/*
		 * Only call into
		 * -[setExtendedAttributeData:forName:ofItemAtIRI:] if it has
		 * been overridden. This is to be backwards-compatible to
		 * subclasses that predate the introduction of
		 * -[setExtendedAttributeData:andType:forName:ofItemAtIRI:].
		 * Without this check, this would result in an infinite loop.
		 */
		SEL selector =
		    @selector(setExtendedAttributeData:forName:ofItemAtIRI:);

		if (class_getMethodImplementation(object_getClass(self),
		    selector) !=
		    class_getMethodImplementation([OFIRIHandler class],
		    selector)) {
			/*
			 * Use
			 * -[performSelector:withObject:withObject:withObject:]
			 * to avoid deprecation warning. This entire thing is
			 * purely for backwards compatibility.
			 */
			[self performSelector: selector
				   withObject: data
				   withObject: name
				   withObject: IRI];
			return;
		}
	}

	OF_UNRECOGNIZED_SELECTOR
}




- (void)removeExtendedAttributeForName: (OFString *)name
			   ofItemAtIRI: (OFIRI *)IRI
{
	OF_UNRECOGNIZED_SELECTOR
}
@end







>
>
>
>







|








<
<
<
<
<
|
<
|









>
>
>











>
>
>
>





<




|











<
<
<
<
<
<
<
|
|
|






>
>
>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239





240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
			       andType: NULL
			       forName: name
			   ofItemAtIRI: IRI];

	return data;
}

#if defined(__clang__) || OF_GCC_VERSION >= 406
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
- (void)getExtendedAttributeData: (OFData **)data
			 andType: (id *)type
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	/*
	 * Only call into -[extendedAttributeDataForName:ofItemAtIRI:] if it
	 * has been overridden. This is to be backwards-compatible with
	 * subclasses that predate the introduction of
	 * -[getExtendedAttributeData:andType:forName:ofItemAtIRI:].
	 * Without this check, this would result in an infinite loop.
	 */
	SEL selector = @selector(extendedAttributeDataForName:ofItemAtIRI:);

	if (class_getMethodImplementation(object_getClass(self), selector) !=
	    class_getMethodImplementation([OFIRIHandler class], selector)) {





		*data = [self extendedAttributeDataForName: name

					       ofItemAtIRI: IRI];

		if (type != NULL)
			*type = nil;

		return;
	}

	OF_UNRECOGNIZED_SELECTOR
}
#if defined(__clang__) || OF_GCC_VERSION >= 406
# pragma GCC diagnostic pop
#endif

- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	[self setExtendedAttributeData: data
			       andType: nil
			       forName: name
			   ofItemAtIRI: IRI];
}

#if defined(__clang__) || OF_GCC_VERSION >= 406
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
- (void)setExtendedAttributeData: (OFData *)data
			 andType: (id)type
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{

	if (type == nil) {
		/*
		 * Only call into
		 * -[setExtendedAttributeData:forName:ofItemAtIRI:] if it has
		 * been overridden. This is to be backwards-compatible with
		 * subclasses that predate the introduction of
		 * -[setExtendedAttributeData:andType:forName:ofItemAtIRI:].
		 * Without this check, this would result in an infinite loop.
		 */
		SEL selector =
		    @selector(setExtendedAttributeData:forName:ofItemAtIRI:);

		if (class_getMethodImplementation(object_getClass(self),
		    selector) !=
		    class_getMethodImplementation([OFIRIHandler class],
		    selector)) {







			[self setExtendedAttributeData: data
					       forName: name
					   ofItemAtIRI: IRI];
			return;
		}
	}

	OF_UNRECOGNIZED_SELECTOR
}
#if defined(__clang__) || OF_GCC_VERSION >= 406
# pragma GCC diagnostic pop
#endif

- (void)removeExtendedAttributeForName: (OFString *)name
			   ofItemAtIRI: (OFIRI *)IRI
{
	OF_UNRECOGNIZED_SELECTOR
}
@end
Changes to src/OFTimer.m.
563
564
565
566
567
568
569


570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
		return;

#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif


		switch (_arguments) {
		case 0:
			[_target performSelector: _selector];
			break;
		case 1:
			[_target performSelector: _selector
				      withObject: _object1];
			break;
		case 2:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2];
			break;
		case 3:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3];
			break;
		case 4:
			[_target performSelector: _selector
				      withObject: _object1
				      withObject: _object2
				      withObject: _object3
				      withObject: _object4];
			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

	if  (!_repeats)







>
>


|


|
|


|
<
|


|
|
<
<
<

|
|
<
<
<







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586



587
588
589



590
591
592
593
594
595
596
		return;

#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(self);
	else {
#endif
		IMP method = [_target methodForSelector: _selector];

		switch (_arguments) {
		case 0:
			((void (*)(id, SEL))method)(_target, _selector);
			break;
		case 1:
			((void (*)(id, SEL, id))method)(_target, _selector,
			    _object1);
			break;
		case 2:
			((void (*)(id, SEL, id, id))method)(_target, _selector,

			    _object1, _object2);
			break;
		case 3:
			((void (*)(id, SEL, id, id, id))method)(_target,
			    _selector, _object1, _object2, _object3);



		case 4:
			((void (*)(id, SEL, id, id, id, id))method)(_target,
			    _selector, _object1, _object2, _object3, _object4);



			break;
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif

	if  (!_repeats)
Changes to src/test/OTAppDelegate.m.
421
422
423
424
425
426
427



428

429


430
431
432
433
434
435
436
					 inClass: class
					  status: StatusRunning
				     description: nil];

			instance = objc_autorelease([[class alloc] init]);

			@try {



				[instance setUp];

				[instance performSelector: test.pointerValue];


			} @catch (OTAssertionFailedException *e) {
				/*
				 * If an assertion fails during -[setUp], don't
				 * run the test.
				 * If an assertion fails during a test, abort
				 * the test.
				 */







>
>
>

>
|
>
>







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
					 inClass: class
					  status: StatusRunning
				     description: nil];

			instance = objc_autorelease([[class alloc] init]);

			@try {
				SEL selector;
				IMP method;

				[instance setUp];

				selector = test.pointerValue;
				method = [instance methodForSelector: selector];
				((void (*)(id, SEL))method)(instance, selector);
			} @catch (OTAssertionFailedException *e) {
				/*
				 * If an assertion fails during -[setUp], don't
				 * run the test.
				 * If an assertion fails during a test, abort
				 * the test.
				 */