Diff
Modified: trunk/LayoutTests/ChangeLog (240910 => 240911)
--- trunk/LayoutTests/ChangeLog 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/LayoutTests/ChangeLog 2019-02-04 00:44:07 UTC (rev 240911)
@@ -1,3 +1,18 @@
+2019-02-03 John Wilander <[email protected]>
+
+ Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick()
+ https://bugs.webkit.org/show_bug.cgi?id=194104
+ <rdar://problem/47649991>
+
+ Reviewed by Chris Dumez, Daniel Bates, and Darin Adler.
+
+ 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-03 Wenson Hsieh <[email protected]>
Unable to move selection into editable roots with 0 height
Added: trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt (0 => 240911)
--- trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt 2019-02-04 00:44:07 UTC (rev 240911)
@@ -0,0 +1,33 @@
+CONSOLE MESSAGE: line 107: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.
+CONSOLE MESSAGE: line 107: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.
+CONSOLE MESSAGE: line 107: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: line 107: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: line 107: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: line 107: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: line 107: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: line 107: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: line 107: Both adcampaignid and addestination need to be set for Ad Click Attribution to work.
+CONSOLE MESSAGE: line 107: Both adcampaignid and addestination 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
+
Added: trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html (0 => 240911)
--- trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html (rev 0)
+++ trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation.html 2019-02-04 00:44:07 UTC (rev 240911)
@@ -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=""
+ <script src=""
+</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>
Added: trunk/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt (0 => 240911)
--- trunk/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt 2019-02-04 00:44:07 UTC (rev 240911)
@@ -0,0 +1,33 @@
+CONSOLE MESSAGE: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.
+CONSOLE MESSAGE: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.
+CONSOLE MESSAGE: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.
+CONSOLE MESSAGE: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: adddestination could not be converted to a valid HTTP-family URL.
+CONSOLE MESSAGE: Both adcampaignid and addestination need to be set for Ad Click Attribution to work.
+CONSOLE MESSAGE: Both adcampaignid and addestination 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
+
Modified: trunk/Source/WebCore/ChangeLog (240910 => 240911)
--- trunk/Source/WebCore/ChangeLog 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Source/WebCore/ChangeLog 2019-02-04 00:44:07 UTC (rev 240911)
@@ -1,3 +1,29 @@
+2019-02-03 John Wilander <[email protected]>
+
+ Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick()
+ https://bugs.webkit.org/show_bug.cgi?id=194104
+ <rdar://problem/47649991>
+
+ Reviewed by Chris Dumez, Daniel Bates, and Darin Adler.
+
+ 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.h:
+ Made WebCore::AdClickAttribution copyable since it's needed to have it be
+ WTF::Optional. Also made AdClickAttribution::MaxEntropy public. Changed
+ numeric types from unsigned short to uint32_t.
+ (WebCore::AdClickAttribution::Campaign::isValid const):
+ (WebCore::AdClickAttribution::Conversion::isValid const):
+
2019-02-03 Ryosuke Niwa <[email protected]>
Validate navigation policy decisions to avoid crashes in continueLoadAfterNavigationPolicy
Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (240910 => 240911)
--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2019-02-04 00:44:07 UTC (rev 240911)
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLAnchorElement.h"
+#include "AdClickAttribution.h"
#include "DOMTokenList.h"
#include "ElementIterator.h"
#include "EventHandler.h"
@@ -50,8 +51,10 @@
#include "SecurityPolicy.h"
#include "Settings.h"
#include "URLUtils.h"
+#include "UserGestureIndicator.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
namespace WebCore {
@@ -394,6 +397,52 @@
}
#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::Other, MessageLevel::Warning, "Both adcampaignid and addestination need to be set for Ad Click Attribution to work."_s);
+ return WTF::nullopt;
+ }
+
+ RefPtr<Frame> frame = document().frame();
+ if (!frame || !frame->isMainFrame()) {
+ document().addConsoleMessage(MessageSource::Other, MessageLevel::Warning, "Ad Click Attribution is only supported in the main frame."_s);
+ return WTF::nullopt;
+ }
+
+ auto adCampaignID = parseHTMLNonNegativeInteger(adCampaignIDAttr);
+ if (!adCampaignID) {
+ document().addConsoleMessage(MessageSource::Other, MessageLevel::Warning, "adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution."_s);
+ return WTF::nullopt;
+ }
+
+ if (adCampaignID.value() >= AdClickAttribution::MaxEntropy) {
+ document().addConsoleMessage(MessageSource::Other, MessageLevel::Warning, makeString("adcampaignid must have a non-negative value less than ", AdClickAttribution::MaxEntropy, " for Ad Click Attribution."));
+ return WTF::nullopt;
+ }
+
+ URL adDestinationURL { URL(), adDestinationAttr };
+ if (!adDestinationURL.isValid() || !adDestinationURL.protocolIsInHTTPFamily()) {
+ document().addConsoleMessage(MessageSource::Other, MessageLevel::Warning, "adddestination could not be converted to a valid HTTP-family URL."_s);
+ return WTF::nullopt;
+ }
+
+ return AdClickAttribution { Campaign(adCampaignID.value()), Source(document().domain()), Destination(adDestinationURL.host().toString()) };
+}
+
void HTMLAnchorElement::handleClick(Event& event)
{
event.setDefaultHandled();
@@ -438,6 +487,13 @@
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
+ // A matching conversion event needs to happen before the complete ad click attributionURL can be
+ // created. Thus, it should be empty for now.
+ ASSERT_UNUSED(adClickAttribution, !adClickAttribution || adClickAttribution->url().isNull());
+
frame->loader().urlSelected(completedURL, effectiveTarget, &event, LockHistory::No, LockBackForwardList::No, shouldSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo);
sendPings(completedURL);
Modified: trunk/Source/WebCore/html/HTMLAnchorElement.h (240910 => 240911)
--- trunk/Source/WebCore/html/HTMLAnchorElement.h 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.h 2019-02-04 00:44:07 UTC (rev 240911)
@@ -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 @@
void sendPings(const URL& destinationURL);
+ Optional<AdClickAttribution> parseAdClickAttribution() const;
+
void handleClick(Event&);
enum EventType {
Modified: trunk/Source/WebCore/loader/AdClickAttribution.h (240910 => 240911)
--- trunk/Source/WebCore/loader/AdClickAttribution.h 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Source/WebCore/loader/AdClickAttribution.h 2019-02-04 00:44:07 UTC (rev 240911)
@@ -37,15 +37,14 @@
namespace WebCore {
-constexpr unsigned short maxEntropy = 64;
-
class AdClickAttribution {
- WTF_MAKE_NONCOPYABLE(AdClickAttribution);
public:
- using CampaignId = unsigned short;
- using ConversionData = unsigned short;
- using PriorityValue = unsigned short;
+ using CampaignId = uint32_t;
+ using ConversionData = uint32_t;
+ using PriorityValue = uint32_t;
+ static constexpr uint32_t MaxEntropy = 64;
+
struct Campaign {
explicit Campaign(CampaignId id)
: id { id }
@@ -54,7 +53,7 @@
bool isValid() const
{
- return id < maxEntropy;
+ return id < MaxEntropy;
}
CampaignId id;
@@ -104,7 +103,7 @@
bool isValid() const
{
- return data < maxEntropy && priority < maxEntropy;
+ return data < MaxEntropy && priority < MaxEntropy;
}
ConversionData data;
Modified: trunk/Tools/ChangeLog (240910 => 240911)
--- trunk/Tools/ChangeLog 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Tools/ChangeLog 2019-02-04 00:44:07 UTC (rev 240911)
@@ -1,3 +1,15 @@
+2019-02-03 John Wilander <[email protected]>
+
+ Parse and handle Ad Click Attribution attributes in HTMLAnchorElement::handleClick()
+ https://bugs.webkit.org/show_bug.cgi?id=194104
+ <rdar://problem/47649991>
+
+ Reviewed by Chris Dumez, Daniel Bates, and Darin Adler.
+
+ * TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp:
+ (TestWebKitAPI::TEST):
+ Changed numeric types from unsigned short to uint32_t.
+
2019-02-02 David Kilzer <[email protected]>
Leak of NSArray (4.25 Kbytes) in com.apple.WebKit.WebContent running WebKit layout tests on iOS Simulator
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp (240910 => 240911)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp 2019-02-03 23:43:02 UTC (rev 240910)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp 2019-02-04 00:44:07 UTC (rev 240911)
@@ -33,8 +33,8 @@
namespace TestWebKitAPI {
-constexpr unsigned short min6BitValue { 0 };
-constexpr unsigned short max6BitValue { 63 };
+constexpr uint32_t min6BitValue { 0 };
+constexpr uint32_t max6BitValue { 63 };
// Positive test cases.
@@ -52,8 +52,8 @@
TEST(AdClickAttribution, ValidMidValues)
{
- AdClickAttribution attribution(AdClickAttribution::Campaign((unsigned short)12), AdClickAttribution::Source("webkit.org"), AdClickAttribution::Destination("example.com"));
- attribution.setConversion(AdClickAttribution::Conversion((unsigned short)44, AdClickAttribution::Priority((unsigned short)22)));
+ AdClickAttribution attribution(AdClickAttribution::Campaign((uint32_t)12), AdClickAttribution::Source("webkit.org"), AdClickAttribution::Destination("example.com"));
+ attribution.setConversion(AdClickAttribution::Conversion((uint32_t)44, AdClickAttribution::Priority((uint32_t)22)));
auto attributionURL = attribution.url();
auto referrerURL = attribution.referrer();