Bug 88193

Summary: Duplicated CSP directives should throw a more accurate console error.
Product: WebKit Reporter: Mike West <mkwst>
Component: WebCore Misc.Assignee: Mike West <mkwst>
Status: RESOLVED FIXED    
Severity: Enhancement CC: abarth, jochen, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description Mike West 2012-06-03 10:37:39 PDT
Accidentally duplicating a CSP directive (by, for example, typoing `style-src` into `script-src`) leads to an error that reads "Unrecognized Content-Security-Policy directive 'script-src'." If, like me, you are slow witted, it might take you a half hour or so to figure out why things aren't working the way you expect them to, especially if the policy you expected to see active is in the second of the two. :)

I'd like to add an error for this condition, something along the lines of "Ignoring duplicate Content-Security-Policy directive: `script-src`."

WDYT?
Comment 1 jochen 2012-06-03 10:46:06 PDT
Seems reasonable
Comment 2 Mike West 2012-06-03 12:14:31 PDT
Created attachment 145490 [details]
Patch
Comment 3 Mike West 2012-06-03 12:16:59 PDT
Based on sifting through http://www.webkit.org/coding/RefPtr.html, I'm fairly certain I'm doing something wrong by passing the `OwnPtr<CSPDirective>` around without converting to `PassOwnPtr`. It's not clear to me how I ought to do it correctly in this scenario. Feedback would be appreciated. :)
Comment 4 Adam Barth 2012-06-03 12:30:55 PDT
Comment on attachment 145490 [details]
Patch

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

This looks fine.  A bunch of style nits below.

> Source/WebCore/page/ContentSecurityPolicy.cpp:520
> -    PassOwnPtr<CSPDirective> createCSPDirective(const String& name, const String& value);
> +    void setCSPDirective(OwnPtr<CSPDirective>&, const String& name, const String& value);

This isn't a common pattern in WebKit, but it's fine.  In this case, the OwnPtr is an in/out parameter for this function.  We usually put output parameters at the end of the argument list.

> Source/WebCore/page/ContentSecurityPolicy.cpp:830
> +      logDuplicateDirective(name);
> +      return;

Four-space indent.

> Source/WebCore/page/ContentSecurityPolicy.cpp:852
> +    else

Prefer early return.

> Source/WebCore/page/ContentSecurityPolicy.cpp:859
> +      logDuplicateDirective(name);

Four-space indent.

> Source/WebCore/page/ContentSecurityPolicy.cpp:860
> +    else {

Prefer early return.
Comment 5 Adam Barth 2012-06-03 12:34:50 PDT
PassOwnPtr is useful when you want to pass around ownership of an object (e.g., as a return value of a function).  Here you're passing around an l-value into which you're going to store the result.  Another idiom you could use is the following:

m_scriptSrc = createDirective(m_scriptSrc.get(), ...,  ...)

where the m_scriptSrc argument would be purely an in-parameter and the result would be returned as a return value.  What you've done instead is to have an in/out parameter, which can be trickier to read but removes the need to repeat m_scriptSrc twice (which can lead to an error if the two aren't the same).

Given that I'd expect folks to copy/paste this code when adding new directives, using the in/out parameter makes sense so we don't have the error case of not editing both m_blah values when copy/pasting.
Comment 6 jochen 2012-06-03 12:40:46 PDT
(In reply to comment #5)
> PassOwnPtr is useful when you want to pass around ownership of an object (e.g., as a return value of a function).  Here you're passing around an l-value into which you're going to store the result.  Another idiom you could use is the following:
> 
> m_scriptSrc = createDirective(m_scriptSrc.get(), ...,  ...)
> 
> where the m_scriptSrc argument would be purely an in-parameter and the result would be returned as a return value.  What you've done instead is to have an in/out parameter, which can be trickier to read but removes the need to repeat m_scriptSrc twice (which can lead to an error if the two aren't the same).
> 
> Given that I'd expect folks to copy/paste this code when adding new directives, using the in/out parameter makes sense so we don't have the error case of not editing both m_blah values when copy/pasting.

an alternative would be to return nullptr when you don't create an object to return
Comment 7 Mike West 2012-06-03 13:16:16 PDT
Created attachment 145492 [details]
Patch
Comment 8 Mike West 2012-06-03 13:18:41 PDT
(In reply to comment #5)
> Given that I'd expect folks to copy/paste this code when adding new directives, using the in/out parameter makes sense so we don't have the error case of not editing both m_blah values when copy/pasting.

Makes sense. That was certainly the idiom I was going for, but I'd originally tried to pass a pointer to the pointer (which would have made it slightly more clear what was going on, or at least that *something* interesting was happening). That ran afoul of the style bot, which is understandable, as it was ugly. :)

I've addressed the style nits, and uploaded a new patch. Thanks for the detailed feedback.
Comment 9 Adam Barth 2012-06-03 15:15:37 PDT
Comment on attachment 145492 [details]
Patch

Thanks.  Let's give Jochen a chance to provide feedback before landing this patch.
Comment 10 jochen 2012-06-04 01:09:56 PDT
Comment on attachment 145492 [details]
Patch

To prove that I also read the patch, here's a nit

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

> LayoutTests/http/tests/security/contentSecurityPolicy/duplicate-directive.html:3
> +  <head>

can you please also indent 4 spaces in html/js
Comment 11 Mike West 2012-06-04 01:32:45 PDT
Created attachment 145537 [details]
Patch
Comment 12 Mike West 2012-06-04 01:34:03 PDT
Comment on attachment 145537 [details]
Patch

Thanks for the nits. What are the odds that I can convince the entire webkit community to use two spaces instead of four? :)
Comment 13 WebKit Review Bot 2012-06-04 03:10:14 PDT
Comment on attachment 145537 [details]
Patch

Clearing flags on attachment: 145537

Committed r119380: <http://trac.webkit.org/changeset/119380>
Comment 14 WebKit Review Bot 2012-06-04 03:10:20 PDT
All reviewed patches have been landed.  Closing bug.
Comment 15 Adam Barth 2012-06-04 11:13:15 PDT
> What are the odds that I can convince the entire webkit community to use two spaces instead of four? :)

Similar to the odds of convincing the community to abandon ChangeLogs.  ;)