Why does the following produce an infinite loop?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Tabatha

    #1

    Why does the following produce an infinite loop?

    Code:
    string url = Request.Url.AbsoluteUri.ToLower();
    
    //not logged in code path snippet
    
    if (!url.Contains("default.aspx") | !url.Contains("cookietest.aspx") | !url.Contains("nondisclosure.aspx") | !url.Contains("errorpage.aspx"))
                {
                    //only redirect if user is not on the default, nondisclosure or cookie page..
                   Response.Redirect("default.aspx", false);
                    
                }

    If I attempt to go to the default.aspx page, it causes an infinite loop. It's almost like the code is not seeing the ! in front of the url.contains..

    So basically i'm saying.. If NOT URL.CONTAINS... OR... If NOT URL.CONTAINS..

    So.. I've debugged and the URL DOES contain default.aspx.. yet it still redirects..
  • Atli
    Recognized Expert Expert
    • Nov 2006
    • 5062

    #2
    The | symbol is an OR operator. So your IF clause will be triggered if ANY of the tests are true. - Which means that if any of the four pages are NOT in the URL, the redirect happens.

    You probably meant to use the AND operator, &.

    Comment

    • Curtis Rutland
      Recognized Expert Specialist
      • Apr 2008
      • 3264

      #3
      And instead of the bitwise operators, you probably wanted to use the logical operators:

      Logical And: &&
      Logical Or: ||

      In this case, it's not a big deal, but if you ever applied these single character operators to integers, you'd be surprised by the result.

      Now, on to your logic. Read De Morgan's Laws. It basically states:

      NOT (P AND Q) = (NOT P) OR (NOT Q)
      NOT (P OR Q) = (NOT P) AND (NOT Q)

      The logic you're going for:

      If my page contains "A" or "B" or "C" or "D", don't redirect.

      Which can be rewritten as
      Code:
      IF(A OR B OR C OR D) 
        {do nothing} 
      ELSE 
        {do something}
      Which again, can be rewritten as:
      Code:
      IF NOT (A OR B OR C OR D) 
        {do something}
      Now, by De Morgan's law (the second one), we can re-write this:
      Code:
      IF((NOT A) AND (NOT B) AND (NOT C) AND (NOT D)) 
        {do something}
      So you see, you have to swap your ORs for ANDs.
      Last edited by Curtis Rutland; Oct 14 '10, 06:58 PM.

      Comment

      • Curtis Rutland
        Recognized Expert Specialist
        • Apr 2008
        • 3264

        #4
        To explain it a bit less theoretically, walk yourself through this.
        Here's your conditional:
        Code:
        if(!url.Contains("default.aspx") | !url.Contains("cookietest.aspx") | !url.Contains("nondisclosure.aspx") | !url.Contains("errorpage.aspx"))
        So let's assign each to an imaginary variable:
        a = url.Contains("d efault.aspx")
        b = url.Contains("c ookietest.aspx" )
        c = url.Contains("n ondisclosure.as px")
        d = url.Contains("e rrorpage.aspx") )

        And rewrite your conditional as:
        Code:
        if(!a || !b || !c || !d)
        So, let's pretend that url = "default.as px";
        a = T
        b = F
        c = F
        d = F

        So then:
        !a = F
        !b = T
        !c = T
        !d = T

        Now replace the variables in the conditional with truth values:

        Code:
        if(F || T || T || T)
        Since every operator is OR, and at least one operand is true, the entire statement evaluates to True.

        In case you can't tell, I like boolean logic.

        If my explanation seems like overkill or insulting, it was not intended that way. I like to thoroughly explain things like this because lots of people struggle with these concepts. Hope it has helped.

        Comment

        • Atli
          Recognized Expert Expert
          • Nov 2006
          • 5062

          #5
          Originally posted by Curtis Rutland
          And instead of the bitwise operators, you probably wanted to use the logical operators:
          Good point. Totally missed that one.

          My C# skills are apparently getting rusty! :)

          Comment

          Working...