WebKit Bugzilla
Attachment 360904 Details for
Bug 194104
: Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194104-20190201142925.patch (text/plain), 18.55 KB, created by
John Wilander
on 2019-02-01 14:29:25 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
John Wilander
Created:
2019-02-01 14:29:25 PST
Size:
18.55 KB
patch
obsolete
>Subversion Revision: 240863 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 70ee09c777eef10d17ffcd8dba8e032466a3ba1e..2709e70ad24e0fdd967e21c31ee86ca0129d363a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,30 @@ >+2019-02-01 John Wilander <wilander@apple.com> >+ >+ Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick() >+ https://bugs.webkit.org/show_bug.cgi?id=194104 >+ <rdar://problem/47649991> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Test: http/tests/adClickAttribution/anchor-tag-attributes-validation.html >+ >+ This patch adds parsing and validation of the two new Ad Click Attribution >+ attributes in anchor elements: adcampaignid and addestination. The data is >+ not yet forwarded into the loader. >+ >+ * html/HTMLAnchorElement.cpp: >+ (WebCore::HTMLAnchorElement::parseAdClickAttribution const): >+ (WebCore::HTMLAnchorElement::handleClick): >+ Now calls HTMLAnchorElement::parseAdClickAttribution(). >+ * html/HTMLAnchorElement.h: >+ * loader/AdClickAttribution.cpp: >+ (WebCore::AdClickAttribution::convertToMaxEntropyValue): >+ Put here to have access to the right context including restrictions on >+ entropy. >+ * loader/AdClickAttribution.h: >+ Made WebCore::AdClickAttribution copyable since it's needed to have it be >+ WTF::Optional. >+ > 2019-02-01 Antti Koivisto <antti@apple.com> > > Don't use base layer() as the scroll layer in scrolling tree. >diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp >index e7e167c95b4177513432f96c6f41e385afb62e44..df74114e6cba908e1520fab86556a8eef5cfedd9 100644 >--- a/Source/WebCore/html/HTMLAnchorElement.cpp >+++ b/Source/WebCore/html/HTMLAnchorElement.cpp >@@ -24,6 +24,7 @@ > #include "config.h" > #include "HTMLAnchorElement.h" > >+#include "AdClickAttribution.h" > #include "DOMTokenList.h" > #include "ElementIterator.h" > #include "EventHandler.h" >@@ -50,6 +51,7 @@ > #include "SecurityPolicy.h" > #include "Settings.h" > #include "URLUtils.h" >+#include "UserGestureIndicator.h" > #include <wtf/IsoMallocInlines.h> > #include <wtf/text/StringBuilder.h> > >@@ -394,6 +396,48 @@ bool HTMLAnchorElement::isSystemPreviewLink() const > } > #endif > >+Optional<AdClickAttribution> HTMLAnchorElement::parseAdClickAttribution() const >+{ >+ using Campaign = AdClickAttribution::Campaign; >+ using Source = AdClickAttribution::Source; >+ using Destination = AdClickAttribution::Destination; >+ >+ if (!RuntimeEnabledFeatures::sharedFeatures().adClickAttributionEnabled() || !UserGestureIndicator::processingUserGesture()) >+ return WTF::nullopt; >+ >+ if (!hasAttributeWithoutSynchronization(adcampaignidAttr) && !hasAttributeWithoutSynchronization(addestinationAttr)) >+ return WTF::nullopt; >+ >+ auto adCampaignIDAttr = attributeWithoutSynchronization(adcampaignidAttr); >+ auto adDestinationAttr = attributeWithoutSynchronization(addestinationAttr); >+ >+ if (adCampaignIDAttr.isEmpty() || adDestinationAttr.isEmpty()) { >+ document().addConsoleMessage(MessageSource::Storage, MessageLevel::Warning, "Both the adcampaignid attribute and the addestination attribute need to be set for Ad Click Attribution to work."); >+ return WTF::nullopt; >+ } >+ >+ RefPtr<Frame> frame = document().frame(); >+ if (!frame || !frame->isMainFrame()) { >+ document().addConsoleMessage(MessageSource::Storage, MessageLevel::Warning, "Ad Click Attribution is only supported in the main frame."); >+ return WTF::nullopt; >+ } >+ >+ auto convertedAdCampaignID = AdClickAttribution::convertToMaxEntropyValue(adCampaignIDAttr); >+ if (convertedAdCampaignID.hasException()) { >+ document().addConsoleMessage(MessageSource::Storage, MessageLevel::Warning, convertedAdCampaignID.releaseException().message()); >+ return WTF::nullopt; >+ } >+ >+ auto adCampaignID = convertedAdCampaignID.releaseReturnValue(); >+ URL adDestinationURL { URL(), adDestinationAttr }; >+ if (!adDestinationURL.isValid() || !adDestinationURL.protocolIsInHTTPFamily()) { >+ document().addConsoleMessage(MessageSource::Storage, MessageLevel::Warning, "The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL."); >+ return WTF::nullopt; >+ } >+ >+ return AdClickAttribution { Campaign(adCampaignID), Source(document().domain()), Destination(adDestinationURL.host().toString()) }; >+} >+ > void HTMLAnchorElement::handleClick(Event& event) > { > event.setDefaultHandled(); >@@ -438,6 +482,11 @@ void HTMLAnchorElement::handleClick(Event& event) > else if (hasRel(Relation::NoOpener) || (RuntimeEnabledFeatures::sharedFeatures().blankAnchorTargetImpliesNoOpenerEnabled() && equalIgnoringASCIICase(effectiveTarget, "_blank"))) > newFrameOpenerPolicy = NewFrameOpenerPolicy::Suppress; > >+ auto adClickAttribution = parseAdClickAttribution(); >+ // FIXME: The adClickAttribution should be forwarded to the loader and handled down the pipe. See >+ // rdar://problem/47650118 >+ ASSERT_UNUSED(adClickAttribution, !adClickAttribution || adClickAttribution->url().string().isEmpty()); >+ > frame->loader().urlSelected(completedURL, effectiveTarget, &event, LockHistory::No, LockBackForwardList::No, shouldSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo); > > sendPings(completedURL); >diff --git a/Source/WebCore/html/HTMLAnchorElement.h b/Source/WebCore/html/HTMLAnchorElement.h >index 6b02c9ab4d462685036e170396e45b81e8d329e8..61315ced17fa4d6e06526cd90bb588aadfa2af97 100644 >--- a/Source/WebCore/html/HTMLAnchorElement.h >+++ b/Source/WebCore/html/HTMLAnchorElement.h >@@ -28,9 +28,11 @@ > #include "SharedStringHash.h" > #include "URLUtils.h" > #include <wtf/OptionSet.h> >+#include <wtf/Optional.h> > > namespace WebCore { > >+class AdClickAttribution; > class DOMTokenList; > > // Link relation bitmask values. >@@ -95,6 +97,8 @@ private: > > void sendPings(const URL& destinationURL); > >+ Optional<AdClickAttribution> parseAdClickAttribution() const; >+ > void handleClick(Event&); > > enum EventType { >diff --git a/Source/WebCore/loader/AdClickAttribution.cpp b/Source/WebCore/loader/AdClickAttribution.cpp >index bdc0639372e3dd3e44ba8567b303fdcb3c665359..054bbcdfceb87b6aea9d62fff3b242f63c84e811 100644 >--- a/Source/WebCore/loader/AdClickAttribution.cpp >+++ b/Source/WebCore/loader/AdClickAttribution.cpp >@@ -26,6 +26,8 @@ > #include "config.h" > #include "AdClickAttribution.h" > >+#include "Exception.h" >+#include <wtf/ASCIICType.h> > #include <wtf/RandomNumber.h> > #include <wtf/URL.h> > #include <wtf/text/StringBuilder.h> >@@ -90,4 +92,24 @@ URL AdClickAttribution::referrer() const > return URL(); > } > >+ExceptionOr<unsigned short> AdClickAttribution::convertToMaxEntropyValue(const String& toConvert) >+{ >+ if (toConvert.length() != 2) >+ return Exception { ConstraintError, makeString('\"', toConvert, "\" needs to be exactly two digits to be converted to a value allowed for Ad Click Attribution.") }; >+ >+ if (!isASCIIDigit(toConvert.characterAt(0)) || !isASCIIDigit(toConvert.characterAt(1))) >+ return Exception { ConstraintError, makeString('\"', toConvert, "\" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution.") }; >+ >+ bool ok = false; >+ auto unsignedResult = toConvert.toUIntStrict(&ok, 10); >+ if (!ok) >+ return Exception { ConstraintError, makeString('\"', toConvert, "\" can not be converted to an unsigned integer which is required for Ad Click Attribution.") }; >+ >+ unsigned short result = static_cast<unsigned short>(unsignedResult); >+ if (result >= maxEntropy) >+ return Exception { ConstraintError, makeString('\"', toConvert, "\" is greater than or equal to ", String::number(maxEntropy), " and is not allowed for Ad Click Attribution.") }; >+ >+ return result; >+} >+ > } >diff --git a/Source/WebCore/loader/AdClickAttribution.h b/Source/WebCore/loader/AdClickAttribution.h >index 7df05ee5eb3ea87f9f9a2640538196e610d54733..4634995c2ed583a1542c1b5178636480193a4e1f 100644 >--- a/Source/WebCore/loader/AdClickAttribution.h >+++ b/Source/WebCore/loader/AdClickAttribution.h >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "ExceptionOr.h" > #include "PublicSuffix.h" > #include <wtf/Noncopyable.h> > #include <wtf/Optional.h> >@@ -40,7 +41,6 @@ namespace WebCore { > constexpr unsigned short maxEntropy = 64; > > class AdClickAttribution { >- WTF_MAKE_NONCOPYABLE(AdClickAttribution); > public: > using CampaignId = unsigned short; > using ConversionData = unsigned short; >@@ -124,6 +124,8 @@ public: > WEBCORE_EXPORT URL referrer() const; > Optional<WallTime> earliestTimeToSend() const { return m_earliestTimeToSend; }; > >+ static ExceptionOr<unsigned short> convertToMaxEntropyValue(const String& toConvert); >+ > private: > bool isValid() const; > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 8495db83da9758f0ddf774402a52ffe46bb8abe5..51c87cd1a8af7251f429743aa626b519191b9784 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,18 @@ >+2019-02-01 John Wilander <wilander@apple.com> >+ >+ Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick() >+ https://bugs.webkit.org/show_bug.cgi?id=194104 >+ <rdar://problem/47649991> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This test case makes sure invalid data triggers console warnings. >+ >+ * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Added. >+ * http/tests/adClickAttribution/anchor-tag-attributes-validation.html: Added. >+ * platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Added. >+ Console line numbers are not emitted when running iOS tests so this -expected.txt file doesn't have them. >+ > 2019-02-01 Carlos Garcia Campos <cgarcia@igalia.com> > > REGRESSION(r239915): css3/font-feature-font-face-local.html failing on WPE >diff --git a/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt b/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4aed7ebd2b9ceeff1f710a597187b5c257fe89cd >--- /dev/null >+++ b/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt >@@ -0,0 +1,36 @@ >+CONSOLE MESSAGE: line 107: "100" needs to be exactly two digits to be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "1" needs to be exactly two digits to be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "98" is greater than or equal to 64 and is not allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "-1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "ab" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: " 1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: "1 " contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: line 107: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: line 107: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: line 107: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: line 107: Both the adcampaignid attribute and the addestination attribute need to be set for Ad Click Attribution to work. >+CONSOLE MESSAGE: line 107: Both the adcampaignid attribute and the addestination attribute need to be set for Ad Click Attribution to work. >+Test for validity of ad click attribution attributes on anchor tags. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+Link1 >+Link2 >+Link3 >+Link4 >+Link5 >+Link6 >+Link7 >+Link8 >+Link9 >+Link10 >+Link11 >+Link12 >+Link13 >+Link14 >+ >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html b/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1da45788c7d0c41e02e7224e2e2d9828f0852d13 >--- /dev/null >+++ b/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html >@@ -0,0 +1,79 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true, internal:AdClickAttributionEnabled=true ] --> >+<html lang="en"> >+<head> >+ <meta charset="UTF-8"> >+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> >+ <script src="/js-test-resources/js-test.js"></script> >+ <script src="/js-test-resources/ui-helper.js"></script> >+</head> >+<body onload="runAllTests()"> >+<div id="description"></div> >+<div id="output"></div><br> >+<div id="console"></div> >+<script> >+ description("Test for validity of ad click attribution attributes on anchor tags."); >+ jsTestIsAsync = true; >+ >+ function createAdClickAttributionAnchorElement(elementID, adCampaignID, adDestination) { >+ let anchorElement = document.createElement("a"); >+ anchorElement.id = elementID; >+ anchorElement.adcampaignid = adCampaignID; >+ anchorElement.addestination = adDestination; >+ anchorElement.href = "#"; >+ anchorElement.innerText = "Link" + currentTest; >+ return anchorElement; >+ } >+ >+ function activateElement(elementID, callback) { >+ var element = document.getElementById(elementID); >+ var centerX = element.offsetLeft + element.offsetWidth / 2; >+ var centerY = element.offsetTop + element.offsetHeight / 2; >+ UIHelper.activateAt(centerX, centerY).then( >+ function () { >+ callback(); >+ }, >+ function () { >+ testFailed("Promise rejected."); >+ finishJSTest(); >+ } >+ ); >+ } >+ >+ let currentTest = 0; >+ function runOneTest(adCampaignID, adDestination, callback) { >+ const currentElementID = "test" + currentTest++; >+ const anchorElement = createAdClickAttributionAnchorElement(currentElementID, adCampaignID, adDestination); >+ output.appendChild(anchorElement); >+ const brElement = document.createElement("br"); >+ output.appendChild(brElement); >+ activateElement(currentElementID, callback); >+ } >+ >+ const validAdCampaignID = "03"; >+ const validAdDestination = "http://webkit.org"; >+ const testCases = [ >+ [ validAdCampaignID, validAdDestination ], >+ [ "100", validAdDestination ], // Too many characters. >+ [ "1", validAdDestination ], // Too few characters. >+ [ "98", validAdDestination ], // Too high value. >+ [ "-1", validAdDestination ], // Negative value. >+ [ "ab", validAdDestination ], // Non-digits. >+ [ "1", validAdDestination ], // Non-ASCII. >+ [ " 1", validAdDestination ], // Leading space. >+ [ "1 ", validAdDestination ], // Trailing space. >+ [ validAdCampaignID, "webkit.org" ], // Missing protocol. >+ [ validAdCampaignID, "://webkit.org" ], // Partially missing protocol. >+ [ validAdCampaignID, "" ], // Non-ASCII characters as destination. >+ [ "", validAdDestination ], // Empty campaign ID. >+ [ validAdCampaignID, "" ] // Empty destination. >+ ]; >+ >+ function runAllTests() { >+ if (currentTest < testCases.length) >+ runOneTest(testCases[currentTest][0], testCases[currentTest][1], runAllTests); >+ else >+ finishJSTest(); >+ } >+</script> >+</body> >+</html> >diff --git a/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt b/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..466ee647b1b33c8e8e42e4b8863ccfd478abf34e >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt >@@ -0,0 +1,36 @@ >+CONSOLE MESSAGE: "100" needs to be exactly two digits to be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "1" needs to be exactly two digits to be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "98" is greater than or equal to 64 and is not allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "-1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "ab" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: " 1" contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: "1 " contains at least one non-digit character and can not be converted to a value allowed for Ad Click Attribution. >+CONSOLE MESSAGE: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: The addestination attribute for Ad Click Attribution could not be converted to a valid HTTP-family URL. >+CONSOLE MESSAGE: Both the adcampaignid attribute and the addestination attribute need to be set for Ad Click Attribution to work. >+CONSOLE MESSAGE: Both the adcampaignid attribute and the addestination attribute need to be set for Ad Click Attribution to work. >+Test for validity of ad click attribution attributes on anchor tags. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+Link1 >+Link2 >+Link3 >+Link4 >+Link5 >+Link6 >+Link7 >+Link8 >+Link9 >+Link10 >+Link11 >+Link12 >+Link13 >+Link14 >+ >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194104
:
360752
|
360754
|
360783
|
360790
|
360803
|
360816
|
360820
|
360894
|
360900
|
360904
|
361029
|
361031