Friday, July 23, 2010

Fun with Javascript Dates - II

1. Javascript Date object has many differences from .Net DateTime type. Some of the prominent differences are:
  • Month is zero based integer (0 to 11) - this can be a source of many a bug.
  • Weekday (getDay) returns 0-6 for Sunday-Saturday

    To get descriptive weekday, you can extend the date object's functionality like so:

    Date.prototype.getDayShort=function(){
    return ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][this.getDay()];
    }
    //Test it:
    alert((new Date(2010,1,1)).getDayShort())

    This will popup "Mon". Some of you are looking up the calendar and thinking "shouldn't 1st Jan be a Friday". No Siree, the date is 1st Feb -- did you already forget my month's tip above? I will leave it up to you to implement a getLongDay() function.

    The cool trick above is declare a lookup array on the fly. It saves a line of code, and an additional variable, and can be useful for small, one-time-use lookups. You can use the same trick with JSON objects. For example:

    alert({black:"#000000", blue:"0000ff", red:"#ff0000"}["blue"]);

    2. One biggie is the Y2K bug. Javascript and .Net have methods to create date objects from numbers. Javascript's Date(yy,mm,dd) constructor will treat all 2 digit year to be 19th century, while .Net has DateTime.Parse method which assumes years "0" to "29) to be 20th century. To mimic .Net's behavior check for date under 30, and add 2000, as shown below:

    for(var i=0;i<102;i++)
    console.log(new Date(i<30?i+2000:i,1,1));
  • Thursday, July 22, 2010

    Fun with Javascript Dates

    I'm going to start a series on Javascript. I'm gonna post some cool and useful solutions that are not currently available on the internet (as far as I know).

    Let's start small. Here is a function that will truncate the Time component from a date object. This can be useful when doing date comparisons, inadvertent bugs are introduced because of the time component.


    <script type="text/javascript">
    function removeTimeFromDate(inDate){ //i.e. set date to Midnight
    return new Date(Date.parse(inDate.toDateString()));
    }
    //Test it out:
    var now = new Date();
    alert(now);
    alert(removeTimeFromDate(now));
    //Results:
    //Thu Jul 22 2010 23:37:50 GMT-0400 (Eastern Daylight Time)
    //Thu Jul 22 2010 00:00:00 GMT-0400 (Eastern Daylight Time)
    </script>


    Pretty simple, once you see it, yet most people write a ton of code to achieve this functionality. Another way is to return a new Date(inDate.getFullYear(), inDate.getMonth(), inDate.getDate())

    You can add this functionality to the Date object itself, thereby extending it. I will show you how to do this in the next post.

    Saturday, May 22, 2010

    Substring Extension Method that does not give exception

    One of the limitations of the .Net Substring(start,[length]) method is it expects the arguments to be within range otherwise we get ArgumentOutOfRange. This is by design as strings are immutable, a member function doesn't exist. String manipulation is one of the most common activity, and it becomes huge annoyance when your truncate or some other method fails at runtime. You may have to write additional code to guard against range "overreach".

    Here is a wonderful extension method (IMHO) that solves your substring overreach issue once for all -- instead of runtime exception, it instead returns the most logical substring based on parameters and substitutes nulls for anything beyond that range -- including an empty string if the whole thing is beyond the range.

    Substring(startIndex, handleIndexException)
    and Substring(startIndex, length, handleIndexException)

    "startIndex" and "length" work just like the original substring. But with handleIndexException enabled(set to TRUE) is where the behavior gets interesting:


  • "startIndex" can be negative or can exceed length of string.
  • "length": when negative is interpreted as take characters from the left. Therefore, Substring(2,-1,true) means start from third position (remember C# count is zero-based), and take one character from the left. See extensive examples below.

    Note, I created another extension method to show nulls. Also I tested it with all possible boundary conditions. Attached are the test results.

         /// 
         /// String Extension for Substring with startIndex, that intelligently handles out of bounds without returning exception
         /// see http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html
         /// 
         /// 
         /// 
         /// 
         /// if set to "true" handles intelligently handles the exception, otherwise works like regular Substring
         public static String Substring(this String val, int startIndex, bool handleIndexException)
         {
             if (handleIndexException)
             {
                 if (string.IsNullOrEmpty(val))
                 {
                     return val;
                 }
                 int instrlength = val.Length;
                 return val.Substring(startIndex < 0 ? 0 : startIndex > (instrlength - 1) ? instrlength : startIndex);
             }
             // ELSE handleIndexException is false so call the base method
             return val.Substring(startIndex);
         }
    
    
    
    /// /// String Extension for Substring with startIndex and Length, that intelligently handles out of bounds without returning exception /// see http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html /// /// /// /// /// /// if set to "true" handles intelligently handles the exception, otherwise works like regular Substring public static String Substring(this String val, int startIndex, int length, bool handleIndexException) { if (handleIndexException) { if (string.IsNullOrEmpty(val)) { return val; } int newfrom, newlth, instrlength = val.Length; if (length < 0) //length is negative { newfrom = startIndex + length; newlth = -1 * length; } else //length is positive { newfrom = startIndex; newlth = length; } if (newfrom + newlth < 0 || newfrom > instrlength - 1) { return string.Empty; } if (newfrom < 0) { newlth = newfrom + newlth; newfrom = 0; } return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom)); } // ELSE handleIndexException is false so call the base method return val.Substring(startIndex, length); } //TEST IT: //Console.WriteLine("-1,3 : " + "abcde".Substring(-1, 3, true).ShowNull()); //....etc... RESULTS from a suite of tests for the string "abcde":
    start,length:result
    ===================
    -1 : abcde
    -0 : abcde
    2 : cde
    4 : e
    5 : <<null>>
    12 : <<null>>
    -1,-1: <<null>>
    -1, 0: <<null>>
    -1, 1: <<null>>
    -1, 3: ab
    -1, 9: abcde
    0,-1: <<null>>
    0,-0: <<null>>
    0, 3: abc
    0, 9: abcde
    2,-3: ab
    2,-2: ab
    2,-1: b
    2,-0: <<null>>
    2, 2: cd
    2, 6: cde
    4,-9: abcd
    4,-4: abcd
    4,-0: <<null>>
    4, 1: e
    4, 4: e
    5,-9: abcde
    5,-5: abcde
    5,-4: bcde
    5,-0: <<null>>
    5, 1: <<null>>
    I hope this helps. I spent several hours first browsing the web, then writing/testing the code. This can be a great time saver!
  • Tuesday, April 27, 2010

    Clickjacking and (i)frame-based attacks, and how to fight them.

    The web is so choke full of malicious sites, that I have become extremely paranoid. If I suspect even a hint of malicious code on a site I am visiting (such as unwanted popups), I rush to the Alt-F4 key close it and consciously avoid any mouseovers/mouseclicks. If that does not work, I will kill the browser session from the task manager. Firefox has an annoying habit of trying to reload the same site after a crash-recovery. You can change that behavior from going into the about:config and changing the browser.sessionstore.resume_from_crash setting to false.

    Clickjacking is one way the baddies can hijack your clicks or keystrokes by craftily positioning their own content obscure/hide legitimate content you are browsing, and deceive the user into clicking on hidden element. So when you click or type, it gets passed on to the hidden layer beneath which could be the hijacker's form to capture personal information.

    The root of this attack is the bad guy placing your web page in a frame or iframe. He can now manipulate the layers and what is visible to the user since he controls the top level or outer frame.

    The classic way to prevent your content from being framed is to put a "frame-buster" javascript at the top of your page:
    <script>if (top!=self) top.location.href=self.location.href</script>

    Unfortunately, the bad guys can defeat this method in a number of ways:

    1. The attacker can interrogate the onbeforeunload event and redirect the top.location and have their own server respond with a 204. The Wikipedia framekiller article describes this technique so I won't go into the details.
    2. Override the location.href setter (__definesetter__) in webkit family of browsers. Therefore even if your frame busting script runs, the location.href will not do the job.
    3. IE has SECURITY="RESTRICTED" option which can allow the attacker to turn off scripting in the inner frame (where they will put your content, and obviously the frame busting script will not run)

    OK, so how do we combat these "anti-busting" techniques? The best way I have worked out is implementing any one or both of these methods:

    (a) This will thwart the first anti-busting attack, but will fail with 2 and 3.

    <script>if(top!=self){var s=self.location;setInterval(function(){top.location.replace(s);s=null},1)}</script>

    (b). Style the <body> to hide content. Then later unhide with scripting after verifying you are not framed. That way even if the attacker thwarts your frame busting efforts, your content is hidden (as well as the clickjacking content) until you successfully bust out of the frame.

    <body style="visibility:hidden"><script>if(top==self)document.body.style.visibility='visible'</script>

    This method(b) doesn't really stop the attack, But hides the content of the page when framed, so a blank page is displayed, therefore the intent of the attacker is defeated! The downside here is that it will show blank page when scripting is turned off, or security(zone) setting is high. This should not be too much of a concern, as in today's world Javascript is so ubiquitous, that turning off scripting will virtually render virtually every site crippled.

    UPDATE(June 9, 2010): Another solution: All major browsers (latest releases) except FF now support the "X-FRAME-OPTIONS" meta tag. Check out Eric law's post. However, since Firefox does not support it as well as all older browsers (IE 6,7 etc),this is not a very effective solution - instead I would use the above (a) and (b) anti-busting countermeasures.

    Sunday, April 4, 2010

    ASP.net MVC 2.0 Attribute-based Validations using metadata

    I have been meaning to publish this for a while. This is a terrific shortcut to quickly create the metadata scaffolding from the Data Access Layer (DAL) created from LINQ2SQL. You will need to download and install Expresso, and be a little familiar with the tool, as well as it will help if you know a bit about regular expressions.

    1. Regenerate DAL (I recommend you use SQLMetal).
    2. Copy required tables from designer.cs into Expresso regex editor (Test Mode) "test area"
    3. Simple find "public (?!e|E|.*\().*" (without the quotes). Then Run Match
    (this gets rid of all junk except class name and properties)
    4. Take the Match Results and copy-to-clipboard, them paste back into the "sample text" area (REPLACING the existing text from step 2).

    5. Now we do a regex find/replace in Expresso.
    Go into Design Mode:
    Search String: "public (?!partial)[^ ]+ (.+)"
    Replace String: (copy the entire string without the quotes, but include the carriage return at the end)
    "public object $1 { get; set; }
    "
    Back to Test Mode and click "Replace"

    6. Copy the replaced-text area back into the sample-text (same as step 4)

    7. Finally decorate the class and add braces:
    Go into Design Mode:
    Search String: "public partial class (\w+).*"
    Replace String: (copy and paste the entire block below exactly as shown, without the quotes, and including the carriage return at the end.
    "}
    [Bind(Exclude = "Id")]
    [MetadataType(typeof($1MetaData))]
    public partial class $1{}
    public class $1MetaData
    {
    "
    Back to Test Mode and click "Replace"

    8. That's it! copy the final text into a new visual studio "metadata.cs" in the models. You have nice clean scaffolding to add your validation attributes. The [Bind] attribute is a placeholder.

    Monday, November 16, 2009

    c# LinQ SelectMany

    I was brushing up on my Linq and reading up on "SelectMany", and created an example that I thought I'd share with you. This uses all the 3.5 new features: Lambda expressions, LINQ, implicitly typed arrays and anon types - declared, instantiated and populated on the fly! It can make for an amazingly compact code!
    
    static void Main(string[] args)
    {
        // declare products array which includes categories for each product
        var products = new[] {
                new {name="salon shampoo", price=15.99d, categories = new[]{
                                                     new {name="bath"},
                                                     new {name="luxury"}
                                                    }
                    },
                new {name="soap", price=1.33d, categories = new[]{
                                                     new {name="bath"}
                                                    }
                    },
                new {name="asiago bread", price=5.99d, categories = new[]{
                                                     new {name="luxury"},
                                                     new {name="grocery"}
                                                    }
                    },
                new {name="sugar 1kg", price=1.99d, categories = new[]{
                                                     new {name="grocery"}
                                                    }
                    }
            };
    
    
        // linq query to extract products less than $10 and of category "grocery"
        var groceries = from p in products
                     where p.price < 10D && p.categories.Any(c => c.name == "grocery")
                     select p;
        // Alternatively: "Fluent" syntax is more condensed:
        // var groceries = products.Where(p => p.price < 10D && 
           p.categories.Any(c => c.name == "grocery"));
    
        //now iterate the result to display the selected product    foreach (var product in result)
        {
            Console.Write(string.Format("\r\nProd:{0}, Price:{1} Categories:", product.name, product.price));
            foreach (var category in product.categories)
            {
                Console.Write(category.name + " ");
            }
        }
    
        //however SELECTMANY, can show the collection in a "flattened" list, while repeating parent items
        var allProducts = products.SelectMany(p => p.categories, (p, c) =>
                p.name + ", $" + p.price.ToString() + ", cat=" + c.name);
        Console.WriteLine("All Products:" + string.Join("\r\n", allProducts.ToArray()));
        var grocFlattened = groceries.SelectMany(p=>
          p.categories,(p,c)=>p.name + ", $" + p.price.ToString() + ", cat=" + c.name);
        Console.WriteLine("Groceries:" + string.Join("\r\n", grocFlattened.ToArray()));
      //Groceries:
      // asiago bread, $5.99, cat=luxury
      // asiago bread, $5.99, cat=grocery
      // sugar 1kg, $1.99, cat=grocery
    }
    

    SelectMany is very powerful and cool as it can "flatten" a collection, but otherwise works just like a Select statement.

    Friday, August 22, 2008

    Bookmarklets

    Bookmarklets is a little javascript code you can put directly into your firefox/IE "bookmarks(favorites)". So when you select the bookmark, it will execute the code and enhance your functionality of the browser. Bookmarklets have been around since IE4, and I find them quite handy. There are bookmarklets to autofill forms, to cut-and-paste, to select text and bring up a search engine and several other uses. I recently created a bookmarklet to rid myself of the annoyance when some sites use redirects, which causes either the form to appear as illustrated, or the firewall to block the site entirely.


    The link appears as:
    Notice that the actual link I want to read is a URL parameter and is percent encoded. Now I have to fill out this form every time I need to read an article on LSJ. Clicking on the Bookmarklet helps me grab the actual link which is:

    For IE the easiest to create this bookmarklet is by adding a dummy bookmark (like this web page), then edit its properties:
    Click on "Favorites", then RIGHT-CLICK on the link you added and select "properties" from the context menu.
    In the "properties" window, click on "General" Tab. Now change the name of the bookmark to "UNESCAPE". Next, click on the "Web Document" tab and paste the following code for URL:
    javascript:void(pos=location.href.search("=http%253A"));
    if(pos=-1)void(pos=location.href.search("=http%"));
    if(pos>-1)location.href=
    unescape(unescape(location.href.slice(pos+1)))
    Note the entire code is the url address, so it should be in a single line and without any spaces in between it. Now click on "Apply" and you will see a message:
    "The protocol javascript does not have a registered program".
    Click "Yes" to keep it anyway. Click OK, and then "Yes" again. Congratulations, you just made your first bookmarklet.