254 lines
7.2 KiB
HTML
254 lines
7.2 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<meta name="timeout" content="long">
|
|
<title>Crash tests PaymentRequest Constructor</title>
|
|
<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script>
|
|
|
|
"use strict";
|
|
const ABUSIVE_AMOUNT = 100000;
|
|
|
|
const applePay = {
|
|
supportedMethods: "https://apple.com/apple-pay",
|
|
data: {
|
|
version: 3,
|
|
merchantIdentifier: "merchant.com.example",
|
|
countryCode: "US",
|
|
merchantCapabilities: ["supports3DS"],
|
|
supportedNetworks: ["visa"],
|
|
}
|
|
};
|
|
|
|
const basicCard = Object.freeze({
|
|
supportedMethods: "basic-card",
|
|
});
|
|
|
|
const defaultAmount = Object.freeze({
|
|
currency: "USD",
|
|
value: "1.00",
|
|
});
|
|
|
|
const evilAmount = Object.freeze({
|
|
currency: "USD",
|
|
value: "1".repeat(ABUSIVE_AMOUNT),
|
|
});
|
|
|
|
const defaultMethods = Object.freeze([basicCard, applePay]);
|
|
|
|
const defaultTotal = Object.freeze({
|
|
label: "label",
|
|
amount: defaultAmount,
|
|
});
|
|
|
|
const evilTotal = Object.freeze({
|
|
label: "a".repeat(ABUSIVE_AMOUNT),
|
|
amount: evilAmount,
|
|
});
|
|
|
|
const defaultDetails = Object.freeze({
|
|
total: defaultTotal,
|
|
get id() {
|
|
return Math.random();
|
|
},
|
|
});
|
|
|
|
const defaultPaymentItem = Object.freeze({
|
|
label: "label",
|
|
amount: defaultAmount,
|
|
});
|
|
|
|
const defaultShippingOption = {
|
|
get id() {
|
|
return "shipping option " + Math.random();
|
|
},
|
|
amount: defaultAmount,
|
|
label: "shipping option label",
|
|
};
|
|
|
|
// First argument is sequence<PaymentMethodData> methodData
|
|
test(() => {
|
|
let evilMethods = [Object.assign({}, basicCard)];
|
|
// smoke test
|
|
try {
|
|
new PaymentRequest(evilMethods, defaultDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, let's add an abusive amount of methods.
|
|
while (evilMethods.length < ABUSIVE_AMOUNT) {
|
|
evilMethods.push({supportedMethods: "evil-method" + evilMethods.length});
|
|
}
|
|
try {
|
|
new PaymentRequest(evilMethods, defaultDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if there is an abusive number of payment methods in the methodData sequence");
|
|
|
|
// PaymentMethodData.supportedMethods
|
|
test(() => {
|
|
const supportedMethods = "basic-card";
|
|
// Smoke test
|
|
try {
|
|
new PaymentRequest([{ supportedMethods }], defaultDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make supportedMethods super large
|
|
const evilMethodData = [
|
|
{
|
|
supportedMethods: supportedMethods.repeat(ABUSIVE_AMOUNT),
|
|
},
|
|
];
|
|
try {
|
|
new PaymentRequest(evilMethodData, defaultDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if PaymentMethodData.supportedMethods is an abusive length");
|
|
|
|
// PaymentDetailsInit.id
|
|
test(() => {
|
|
const id = "abc";
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(
|
|
defaultMethods,
|
|
Object.assign({}, defaultDetails, { id })
|
|
);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make the id super large;
|
|
const evilDetails = Object.assign({}, defaultDetails, {
|
|
id: id.repeat(ABUSIVE_AMOUNT),
|
|
});
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if the request id has an abusive length");
|
|
|
|
// PaymentDetailsInit.total.label
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make the label super large;
|
|
evilDetails.total = {
|
|
label: "l".repeat(ABUSIVE_AMOUNT),
|
|
amount: defaultAmount,
|
|
};
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if PaymentDetailsInit.total.label is an abusive length");
|
|
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we can use evilAmount
|
|
evilDetails.total = evilAmount;
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if total.amount.value is an abusive length");
|
|
|
|
for (const [prop, defaultValue] of [
|
|
["displayItems", defaultPaymentItem],
|
|
["shippingOptions", defaultShippingOption],
|
|
]) {
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
evilDetails[prop] = [defaultValue];
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
while (evilDetails[prop].length < ABUSIVE_AMOUNT) {
|
|
evilDetails[prop] = evilDetails[prop].concat(evilDetails[prop]);
|
|
}
|
|
// Now, construct with evil items!
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, `Don't crash if details.${prop} has an abusive number of items`);
|
|
}
|
|
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
const evilShippingOption = Object.assign({}, defaultShippingOption);
|
|
evilDetails.shippingOptions = [evilShippingOption];
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make the label super large;
|
|
evilShippingOption.label = "l".repeat(ABUSIVE_AMOUNT);
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if PaymentShippingOptions.label is an abusive length");
|
|
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
const evilShippingOption = Object.assign({}, defaultShippingOption);
|
|
evilDetails.shippingOptions = [evilShippingOption];
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make use of evilAmount;
|
|
evilShippingOption.amount = evilAmount;
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if the PaymentShippingOptions.amount.value is an abusive length");
|
|
|
|
test(() => {
|
|
const evilDetails = Object.assign({}, defaultDetails);
|
|
const evilDisplayItem = Object.assign({}, defaultPaymentItem);
|
|
evilDetails.displayItems = [evilDisplayItem];
|
|
// Smoke Test
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_unreached("failed smoke test: " + err.stack);
|
|
}
|
|
// Now, we make the label super large;
|
|
evilDisplayItem.label = "l".repeat(ABUSIVE_AMOUNT);
|
|
try {
|
|
new PaymentRequest(defaultMethods, evilDetails);
|
|
} catch (err) {
|
|
assert_equals(err.name, "TypeError", "must be a TypeError");
|
|
}
|
|
}, "Don't crash if PaymentItem.label is an abusive length");
|
|
</script>
|