Take care when you use RegExp constructor in javascript

I’m not a javascript guru when it is time to write regular expressions, but this morning I have a bug on a piece of code, and the bug was related to a regex declared in this way.

var noMatchRegex = new RegExp("[\r\n\s;,$]+");

 

This regex basically should match a carriage return or a space or ; char, etc, but it appears not working sometimes. After a quick test I confirmed that the problem happens when I have string that contains the character ‘s’. This sounds me strange, but a quick look in Chrome Watch Expression gave me this results

 

image

Figure 1: Regex view from Watch Expression of chrome.

This suggested me that the regular expression has something strange and quickly realized that the problem happens because the person who wrote the code, used a regex taken from the literal notation, but passed inside RegExp constructor, that accepts a string. There is a subtle difference in using the literal notation or passing the regex as string to RegExp constructor. The second alternative requires you to escape the \ character. If you declare the regex with new RegExp(“[\s]”), you are creating a regex that has a \s charater in it and is not valid. You should declare the above regex in this way

var noMatchRegex = new RegExp("[\\r\\n\\s;,$]+");

 

Escaping the character \ produces the expected result, as you can verify from Watch Expression

image

Figure 2: Correct declaration of the regex

Now you can see that the literal notation of the regex is /[\r\n\s;,$+/ and it is correct.

Gian Maria.

Disable Javascript error in WPF WebBrowser control

I work with WebBrowser control in WPF, and one of the most annoying problem I have with it, is that sometimes you browse sites that raise a lot of javascript errors and the control become unusable. Thanks to my friend Marco Campi, yesterday I solved the problem. Marco pointed me a link that does not deal with WebBrowser control, but uses a simple javascript script to disable error handling in a web page.

   1: <script type="text/javascript">
   1:  

   2:  

   3: function noError(){return true;}

   4: window.onerror = noError;

   5:  

</script>

This solution is really simple, and seems to me the right way to solve the problem. The key to the solution is handle the Navigated event raised from the WebBrowser control. First of all I have my WebBrowser control wrapped in a custom class to add functionalities, in that class I declare this constant

   1: private const string DisableScriptError =

   2:    @"function noError() {

   3:          return true;

   4:       }

   5:        

   6:       window.onerror = noError;";

This is the very same script of the previous article, then I handle the Navigated event

   1: void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)

   2: {

   3:    InjectDisableScript();

Actually I’m doing a lot of other things inside the Navigated event handler, but the very first one is injecting into the page the script that disable javascript error.

   1: private void InjectDisableScript()

   2: {

   3:    HTMLDocumentClass doc = Browser.Document as HTMLDocumentClass;

   4:    HTMLDocument doc2 = Browser.Document as HTMLDocument;

   5:  

   6:  

   7:    //Questo crea lo script per la soprressione degli errori

   8:    IHTMLScriptElement scriptErrorSuppressed = (IHTMLScriptElement)doc2.createElement("SCRIPT");

   9:    scriptErrorSuppressed.type = "text/javascript";

  10:    scriptErrorSuppressed.text = DisableScriptError;

  11:  

  12:    IHTMLElementCollection nodes = doc.getElementsByTagName("head");

  13:  

  14:    foreach (IHTMLElement elem in nodes)

  15:    {

  16:       //Appendo lo script all'head cosi è attivo

  17:  

  18:       HTMLHeadElementClass head = (HTMLHeadElementClass)elem;

  19:       head.appendChild((IHTMLDOMNode)scriptErrorSuppressed);

  20:    }

  21: }

This is the code that really solves the problem, the key is creating a IHTMLScriptElement with the script and injecting into the Head of the page, this effectively disables the javascript errors. I’ve not fully tested with a lot of sites to verify that is able to intercept all errors, but it seems to work very well with a lot of links that gave us a lot of problems in the past.

Alk.

Tags:

Tags: