Bug 184335 - Add necessary colon to CFNetwork selector
Summary: Add necessary colon to CFNetwork selector
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: John Wilander
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-04-05 11:11 PDT by John Wilander
Modified: 2018-04-09 16:39 PDT (History)
4 users (show)

See Also:


Attachments
Patch (1.48 KB, patch)
2018-04-05 11:17 PDT, John Wilander
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John Wilander 2018-04-05 11:11:21 PDT
There needs to be a colon in the CFNetwork selector we're testing for if the selector takes a parameter.
Comment 1 Radar WebKit Bug Importer 2018-04-05 11:11:57 PDT
<rdar://problem/39213124>
Comment 2 John Wilander 2018-04-05 11:17:40 PDT
Created attachment 337280 [details]
Patch
Comment 3 John Wilander 2018-04-05 12:35:09 PDT
Comment on attachment 337280 [details]
Patch

Mac-WK2 build successful.
Comment 4 John Wilander 2018-04-05 12:35:23 PDT
Thanks for the review, Brent!
Comment 5 WebKit Commit Bot 2018-04-05 13:02:24 PDT
Comment on attachment 337280 [details]
Patch

Clearing flags on attachment: 337280

Committed r230311: <https://trac.webkit.org/changeset/230311>
Comment 6 WebKit Commit Bot 2018-04-05 13:02:25 PDT
All reviewed patches have been landed.  Closing bug.
Comment 7 Darin Adler 2018-04-08 10:36:28 PDT
Comment on attachment 337280 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337280&action=review

> Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h:350
> +    if ([request respondsToSelector:@selector(_setIgnoreHSTS:)])
> +        [request performSelector:@selector(_setIgnoreHSTS:) withObject:[NSNumber numberWithBool:ignoreHSTS]];

This code is absolutely *not* correct. It is passing an object to a function that takes a boolean. I will provide a correct example shortly.
Comment 8 Darin Adler 2018-04-08 10:55:57 PDT
There are three problems with these HSTS functions:

1) These functions do not belong in the CFNetworkSPI.h, since they are not CFNetwork SPI, but rather convenience functions to make it easy to call the SPI. That’s not what should be in our SPI.h headers.

2) Two of the functions use the performSelector: return value incorrectly. The performSelector: method's return value only works if the return type is an object, or technically if it’s some non-object pointer type or if the return value is ignored. It is *not* correct to use if the return type is BOOL.

3) One of the functions uses performSelector:withObject: to pass an argument that is not an. Passing an NSNumber when the function takes a boolean won’t work properly; part of the NSNumber pointer is likely to be interpreted as the BOOL.

There are multiple correct ways to do this, none of which involve the performSelector: methods. One is to simply use the methods declared in the CFNetworkSPI.h header and be careful only to call if if the method is implemented. That’s probably the preferred one and easiest to get right. Another is to use <wtf/ObjcRuntimeExtras.h>, which contains correct alternatives to performSelector: for cases like these. A third is to use NSInvocation, which requires passing in the method signature.

Here is a sketch of the the first solution, leaving the code in a style suitable for a header (although I don’t think it should be in a header, and certainly not in CFNetworkSPI.h):

static bool schemeWasUpgradedDueToDynamicHSTS(NSURLRequest *request)
{
#if !USE(CFNETWORK_IGNORE_HSTS)
   UNUSED_PARAM(request);
   return false;
#else
   return [request respondsToSelector:@selector(_schemeWasUpgradedDueToDynamicHSTS)]
       && [request _schemeWasUpgradedDueToDynamicHSTS];
#endif
}

static void setIgnoreHSTS(NSMutableURLRequest *request, bool ignoreHSTS)
{
#if !USE(CFNETWORK_IGNORE_HSTS)
   UNUSED_PARAM(request);
#else
    if ([request respondsToSelector:@selector(_setIgnoreHSTS:)])
        [request _setIgnoreHSTS:ignoreHSTS];
#endif
}

static bool ignoreHSTS(NSURLRequest *request)
{
#if !USE(CFNETWORK_IGNORE_HSTS)
   UNUSED(request);
   return false;
#else
   return [request respondsToSelector:@selector(_ignoreHSTS)]
       && [request _ignoreHSTS];
#endif
}

I suggest filing a new bug and dealing with these issues.
Comment 9 Darin Adler 2018-04-08 10:58:37 PDT
The ObjcRuntimeExtras.h versions would look something like this:

static bool schemeWasUpgradedDueToDynamicHSTS(NSURLRequest *request)
{
   return [request respondsToSelector:@selector(_schemeWasUpgradedDueToDynamicHSTS)]
       && wtfObjcMsgSend<BOOL>(request, @selector(_schemeWasUpgradedDueToDynamicHSTS));
}

static void setIgnoreHSTS(NSMutableURLRequest *request, bool ignoreHSTS)
{
    BOOL ignoreHSTSArgument = ignoreHSTS; // Must be BOOL instead of bool.
    if ([request respondsToSelector:@selector(_setIgnoreHSTS:)])
        wtfObjcMsgSend<void>(request, @selector(_setIgnoreHSTS:), ignoreHSTSArgument);
}
Comment 10 Darin Adler 2018-04-08 11:02:24 PDT
Testing will show what does and does not work in practice. I suspect that the current argument problem in the current setIgnoreHSTS function without my suggested fix always sets the flag to true, but there is a chance it might behave differently on different architectures (ARM vs. Intel, 32-bit vs. 64-bit). The return value part might behave correctly by accident on some architectures, and incorrectly on others. Or might be harmless everywhere although incorrect; not sure.
Comment 11 John Wilander 2018-04-09 10:00:09 PDT
Thanks for your comments, Darin. I will look into them today, including further tests of the existing code.
Comment 12 John Wilander 2018-04-09 16:39:36 PDT
Follow-up work tracked in https://bugs.webkit.org/show_bug.cgi?id=184433.