Safari JS bug

From Hexten

Jump to: navigation, search

See "Yet another safari bug" on Tobie Langel's blog for the context to this. My response follows --AndyArmstrong 14:52, 19 April 2007 (BST)


OK, managed to reproduce it now. Of course it only happens with valid JSON. Sorry about that.

I think you can work around the problem by making the clause that checks for valid string characters loop over runs of valid characters like this:

 
  /^(?:"(?:\.|[^"\\n\r]+)*"|[,:{}[]0-9.\-+Eaeflnr-u \n\r\t])+$/
  

I've made a few changes to the RE but the crucial one is

 
  [^"\\n\r] --> [^"\\n\r]+
  

which make the subpattern that matches valid string characters other than backslashed escapes loop over multiple characters.

The bug’s still there of course – this just makes it less likely to bite with typical JSON data.

Here's a complete test script which crashes Safari using the current RE but works fine with the new RE:

 
  <html>
      <head>
          <script>
              var str = 'frible ';
              while (str.length < 20000) {
                  str = str + str;
              }
              str = '"' + str + '"';
            
              function testCapture(str) {
                  if (/^("(\.|[^"\\n\r])*?"|[,:{}[]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(str)) {
                      alert('Capture:Matches!');
                  }
                  else {
                      alert('Capture:No match!');
                  }
              }
            
              function testNoCapture(str) {
                  if (/^(?:"(?:\.|[^"\\n\r]+)*"|[,:{}[]0-9.\-+Eaeflnr-u \n\r\t])+$/.test(str)) {
                      alert('NoCapture:Matches!');
                  }
                  else {
                      alert('NoCapture:No match!');
                  }
              }
          </script>
      </head>
      <body>
          <h1>JS RE Test</h1>
          <a href="#" onclick="javascript:testCapture(str)">With capture</a><br />
          <a href="#" onclick="javascript:testNoCapture(str)">Without capture</a><br />
          <h2>Test string</h2>
          <script>
              document.write(str);
          </script>
      </body>
  </html>
  

It's probably worth using non-capturing parentheses anyway - for performance reasons if nothing else - but the whole capturing / non-capturing distinction is unrelated to the fix. It's just a relic of my first attempt to solve the problem.

Personal tools
Mongers