File: reporting-navigation.https.window.js

package info (click to toggle)
firefox-esr 140.5.0esr-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie-proposed-updates
  • size: 4,539,036 kB
  • sloc: cpp: 7,381,527; javascript: 6,388,905; ansic: 3,710,087; python: 1,393,776; xml: 628,165; asm: 426,918; java: 184,004; sh: 65,744; makefile: 19,302; objc: 13,059; perl: 12,912; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,226; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (139 lines) | stat: -rw-r--r-- 4,916 bytes parent folder | download | duplicates (21)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// META: timeout=long
// META: script=/common/get-host-info.sub.js
// META: script=./resources/common.js
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const COEP = '|header(cross-origin-embedder-policy,credentialless)';
const COEP_RO =
  '|header(cross-origin-embedder-policy-report-only,credentialless)';
const CORP_CROSS_ORIGIN =
  '|header(cross-origin-resource-policy,cross-origin)';
const FRAME_URL = `${ORIGIN}/common/blank.html?pipe=`;
const REMOTE_FRAME_URL = `${REMOTE_ORIGIN}/common/blank.html?pipe=`;

function checkCorpReport(report, contextUrl, blockedUrl, disposition) {
  assert_equals(report.type, 'coep');
  assert_equals(report.url, contextUrl);
  assert_equals(report.body.type, 'corp');
  assert_equals(report.body.blockedURL, blockedUrl);
  assert_equals(report.body.disposition, disposition);
  assert_equals(report.body.destination, 'iframe');
}

function checkCoepMismatchReport(report, contextUrl, blockedUrl, disposition) {
  assert_equals(report.type, 'coep');
  assert_equals(report.url, contextUrl);
  assert_equals(report.body.type, 'navigation');
  assert_equals(report.body.blockedURL, blockedUrl);
  assert_equals(report.body.disposition, disposition);
}

function loadFrame(document, url) {
  return new Promise((resolve, reject) => {
    const frame = document.createElement('iframe');
    frame.src = url;
    frame.onload = () => resolve(frame);
    frame.onerror = reject;
    document.body.appendChild(frame);
  });
}

// |parentSuffix| is a suffix for the parent frame URL.
// |targetUrl| is a URL for the target frame.
async function loadFrames(test, parentSuffix, targetUrl) {
  const frame = await loadFrame(document, FRAME_URL + parentSuffix);
  test.add_cleanup(() => frame.remove());
  // Here we don't need "await". This loading may or may not succeed, and
  // we're not interested in the result.
  loadFrame(frame.contentDocument, targetUrl);

  return frame;
}

async function observeReports(global, expected_count) {
  const reports = [];
  const receivedEveryReports = new Promise(resolve => {
    if (expected_count == 0)
      resolve();

    const observer = new global.ReportingObserver((rs) => {
      for (const r of rs) {
        reports.push(r.toJSON());
      }
      if (expected_count <= reports.length)
        resolve();
    });
    observer.observe();

  });

  // Wait 500ms more to catch additionnal unexpected reports.
  await receivedEveryReports;
  await new Promise(r => step_timeout(r, 500));
  return reports;
}

function desc(headers) {
  return headers === '' ? '(none)' : headers;
}

// CASES is a list of test case. Each test case consists of:
//   parent_headers: the suffix of the URL of the parent frame.
//   target_headers: the suffix of the URL of the target frame.
//   expected_reports: one of:
//     'CORP':    CORP violation
//     'CORP-RO': CORP violation (report only)
//     'NAV':     COEP mismatch between the frames.
//     'NAV-RO':  COEP mismatch between the frames (report only).
const reportingTest = function(
  parent_headers, target_headers, expected_reports) {
  // These tests are very slow, so they must be run in parallel using
  // async_test.
  promise_test_parallel(async t => {
    const targetUrl = REMOTE_FRAME_URL + target_headers;
    const parent = await loadFrames(t, parent_headers, targetUrl);
    const contextUrl = parent.src ? parent.src : 'about:blank';
    const reports = await observeReports(
        parent.contentWindow,
        expected_reports.length
      );
    assert_equals(reports.length, expected_reports.length);
    for (let i = 0; i < reports.length; i += 1) {
      const report = reports[i];
      switch (expected_reports[i]) {
        case 'CORP':
          checkCorpReport(report, contextUrl, targetUrl, 'enforce');
          break;
        case 'CORP-RO':
          checkCorpReport(report, contextUrl, targetUrl, 'reporting');
          break;
        case 'NAV':
          checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce');
          break;
        case 'NAV-RO':
          checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting');
          break;
        default:
          assert_unreached(
            'Unexpected report exception: ' + expected_reports[i]);
      }
    }
  }, `parent: ${desc(parent_headers)}, target: ${desc(target_headers)}, `);
}

reportingTest('', '', []);
reportingTest('', COEP, []);
reportingTest(COEP, COEP, ['CORP']);
reportingTest(COEP, '', ['CORP']);

reportingTest('', CORP_CROSS_ORIGIN, []);
reportingTest(COEP, CORP_CROSS_ORIGIN, ['NAV']);

reportingTest('', COEP + CORP_CROSS_ORIGIN, []);
reportingTest(COEP, COEP + CORP_CROSS_ORIGIN, []);

reportingTest(COEP_RO, COEP, ['CORP-RO']);
reportingTest(COEP_RO, '', ['CORP-RO', 'NAV-RO']);
reportingTest(COEP_RO, CORP_CROSS_ORIGIN, ['NAV-RO']);
reportingTest(COEP_RO, COEP + CORP_CROSS_ORIGIN, []);

reportingTest(COEP, COEP_RO + CORP_CROSS_ORIGIN, ['NAV']);