Mikhus/domurl

TypeError thrown when used inside a srcdoc iframe

Closed this issue · 5 comments

Hi,

I've found an issue when one of our scripts that use domurl was injected inside a srcdoc iframe.

That is an strange case, but I though It may be worth mentioning it.

Here there is a minimal example:

<!doctype html>
<html>
<body>
<iframe srcdoc='<script src="https://cdn.jsdelivr.net/npm/domurl@2.3.0/url.js" integrity="sha256-4NOatzFOPdRvADrRwu+TbGMS2LQNQ0ZEseTjM1sdFj4=" crossorigin="anonymous"></script><script>var url = new Url("/robots.txt");</script>'></iframe>
</body>
</html>

Output:

TypeError: getCurrUrl(...).match(...) is null

What do you think? It feels like something that should be "gracefully" handled? A bit difficult may be.

Thanks

Thanks for filing, @esroyo!

Apparently this is a problem with the branch of constructor that falls back to window.location (second argument to construct() is not provided, or is false).

Here's a more elaborate test, showing the problem:

<!doctype html>
<html>
<body>

  <script
    src="https://cdn.jsdelivr.net/npm/domurl@2.3.0/url.js"
    integrity="sha256-4NOatzFOPdRvADrRwu+TbGMS2LQNQ0ZEseTjM1sdFj4="
    crossorigin="anonymous"
  ></script>
  <script>
    console.log(`body: window.location: ${window.location}`);
    console.log(`body: window.location.href: ${window.location.href}`);

    var url1 = new Url("/robots.txt", true);
    console.log(`body: url1: ${url1}`);

    var url2 = new Url("/robots.txt");
    console.log(`body: url2: ${url2}`);

  </script>

  Hello from body.
  <iframe srcdoc='

    <script
      src="https://cdn.jsdelivr.net/npm/domurl@2.3.0/url.js"
      integrity="sha256-4NOatzFOPdRvADrRwu+TbGMS2LQNQ0ZEseTjM1sdFj4="
      crossorigin="anonymous"
    ></script>
    <script>
      console.log(`iframe: window.location: ${window.location}`);
      console.log(`iframe: window.location.href: ${window.location.href}`);

      var url1 = new Url("/robots.txt", true);
      console.log(`body: url1: ${url1}`);

      var url2 = new Url("/robots.txt");
      console.log(`body: url2: ${url2}`);

    </script>
    Hello from iframe.

    '
  ></iframe>
</body>
</html>

We can see that new Url() breaks only on the second instance of it inside the iframe.

image

Apparently window.location has the value about:srcdoc when srcdoc is used.

From my pov, I don't have any clear expectation about the Url behavior in this case. If anyone relies on the construction-with-fallback behavior, would love to hear from you what you would expect to happen in this case.

Hi @besfahbod, thanks for elaborating on this.

In my opinion, a srcdoc iframe is inherently a privileged special kind of iframe that must share domain with the container document. It contains an isolated HTML, but still kind of shares location with the parent (we could say it is a same-domain++ ? xD ) Being that the case, for me makes sense to use the parent location self.parent.location.href. I can't imagine what else could be done " to resolve given URL to an absolute form".

It makes sense to me, @esroyo. Would love to hear from @Mikhus, too.

I think the minimum bar is that it shouldn't raise exception.

Do you think you can send a PR to address the issue?

Sure! :)

Many thanks @Mikhus @besfahbod 😃