author Andrew Sutherland <>
Thu, 22 Mar 2018 11:33:13 -0400
changeset 462850 49448fdb2c96b17a290395110f3492870ccfebd5
parent 456061 5cbdc4e31b0f42029113f1f4bde8d8a6d31a6475
child 555809 3b3c5e0e1bc4a58d8a7d5718745cc41153e06a76
permissions -rw-r--r--
Bug 1446225 - Ensure client id's are consistently {}-less UUIDs. r=catalinb, a=jcristau Our values were being normalized from "{uuid}" to "uuid", but not our FetchEvent.clientId values. Because nsID::Parse accepts both forms, this was not being caught by any tests. Although there are ServiceWorker WPT tests that verify consistency of returned values across multiple matchAll invocations (ex: client-id.https.html), there are no tests that compare with FetchEvent.clientId. All the tests largely use Clients.get() to verify correctness/round-tripping. I looked into adding WPT tests, but we quickly run into the test logistics problem where it's preferable to avoid adding tests that involve effectively global state. So, this patch: - Changes Clients::Get() to explicitly treat client id's that start with a "{" as invalid. This causes existing FetchEvent.clientId-related WPT tests to fail, as we would hope. - Duplicates the client id normalization logic that strips {} for the FetchEvent.clientId to its point of origin in ContinueDispatchFetchEventRunnable::Run. - Augments our dom/serviceworkers/test/test_match_all_client_properties.html test, which has been enforcing {}-less UUIDs for a while, to also test FetchEvent.clientId to verify it conforms. I added some comments to the test files too.

  Any copyright is dedicated to the Public Domain.
  <title>Bug 1058311 - controlled page</title>
<script class="testbody" type="text/javascript">
  var re = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
  var frameType = "none";
  var testWindow = parent;

  if (parent != window) {
    frameType = "nested";
  } else if (opener) {
    frameType = "auxiliary";
    testWindow = opener;
  } else if (parent != window) {
    frameType = "top-level";
  } else {
    postResult(false, "Unexpected frameType");

  window.onload = function() {
    navigator.serviceWorker.ready.then(function(swr) {
        // Send a message to our SW that will cause it to do clients.matchAll()
        // and send a message *to each client about themselves* (rather than
        // replying directly to us with all the clients it finds)."Start");

  function postResult(result, msg) {
    response = {
      result: result,
      message: msg

    testWindow.postMessage(response, "*");

  navigator.serviceWorker.onmessage = async function(msg) {
    // ## Verify the contents of the SW's serialized rep of our client info.
    // Clients are opaque identifiers at a spec level, but we want to verify
    // that they are UUID's *without wrapping "{}" characters*.
    result = re.test(;
    postResult(result, "Client id test");

    result = == window.location;
    postResult(result, "Client url test");

    result = === document.visibilityState;
    postResult(result, "Client visibility test. expected=" +document.visibilityState);

    result = === document.hasFocus();
    postResult(result, "Client focus test. expected=" + document.hasFocus());

    result = === frameType;
    postResult(result, "Client frameType test. expected=" + frameType);

    result = === "window";
    postResult(result, "Client type test. expected=window");

    // ## Verify the FetchEvent.clientId
    // In bug 1446225 it turned out we provided UUID's wrapped with {}'s.  We
    // now also get coverage by forcing our clients.get() to forbid UUIDs
    // with that form.

    const clientIdResp = await fetch('clientId');
    const fetchClientId = await clientIdResp.text();
    result = re.test(fetchClientId);
    postResult(result, "Fetch clientId test");

    postResult(true, "DONE");