• (cs)

    ULRDecode  ... gasp .... and this is a "how-to" article !!???  No wonder we have so much WTF code out there !!!

    I am curious to see what all of the VB-bashers out there will say about the code posted above, though.  Probably stuff like "This is clearly ported over from VB! stupid VB programmers!"...

    It really is amazing -- and sad -- that people do stuff like this.  and scary, too.


  • (unregistered)

    Eep!

  • (cs)

    So now I have to audit my code for Y2K7 issues?

  • (cs) in reply to logistix

    Sweet Enola Gay!

  • (unregistered)

    The real WTF is that there can be no hour 24.  Or minute 60... or second 60... Besides that, he doesn't do any "magix hex number" for minute 0 and second 0.

  • (cs)

    Yeah- second the yk7 issue since the rest would be so easy to fix once you set him right during the code review.

    But that kind of year handling is inexcusable. The coder knows when they write that kind of thing that it's wrong and they're just hoping it won't get caught and that it'll be someone else's problem by then.

    This sort of attitude needs to be destroyed very quickly.

    I inherited an app once (BUNCHES of apps really, all with either the default project names or stupid names like "birthday.exe") that hard-coded the year and so every year they had to be changed.

    The guy got laid off eventually, but was nice enough to help the only user who used these apps and fix them every year. Since these apps were developed outside the development groups, no one knew about them until a couple years later when they were run without having been changed and a wad of data was messed up.

  • (unregistered)

    This doesn't make much sense. Computers handle numbers in binary, not in hex.

  • (unregistered) in reply to

    Agreed, except for "second 60". There are leap seconds (because years don't actually consist of convenient numbers of hours).

  • (unregistered)

    [B]

  • (unregistered)

    Another example why C programmers give the rest of us VB programmers a bad name...

  • (unregistered)

    The whole CClassname thing is another major WTF.

  • (cs)

    I found the UrlDecode atrocity while looking for information as to why the HttpUtility class has four overrides for UrlDecode, while HttpServerUtility has only two overrides, and doesn't allow you to specify the encoding. 

    Maybe that is a WTF also [:D]

  • (unregistered)

    There's some real bugs in the URLDecode procedure.
    First, he starts at %20... so tabs, carriage returns etc. won't be unencoded.  Oops!
    Second, he does both %20 and + decoding for spaces, which is good... and he also does

    str = Replace(str, "%2B", "+")
    which is also good... but the "oops" is that he replaces + w/ space AFTER replacing %2B w/ +!!!  Lost data...

  • (unregistered) in reply to

    CClassname is an MFC convention, it has nothing whatsoever to do with C++. Check out the STL, do you see any in there? Oh wait... as a VB programmer you probably dont know what the STL is.  [:P]

  • (unregistered) in reply to David Crowell
    David Crowell:
    I found the UrlDecode atrocity while looking for information as to why the HttpUtility class has four overrides for UrlDecode, while HttpServerUtility has only two overrides, and doesn't allow you to specify the encoding. 

    Maybe that is a WTF also Big Smile


    It makes perfect sense that HttpUtility is more generic and the HttpServerUtility is tied to the server itself. I'm sure that the HttpServerUtility method calls the HttpUtility method. You can use the reflector to confirm this.
  • (unregistered)

    "which is also good... but the "oops" is that he replaces + w/ space AFTER replacing %2B w/ +!!!  Lost data..."

    It's worse than that.  Note:

    str = Replace(str, "%25", "%")

    So what if the string is "%2530"?  Of course it'll become "0" instead of "%30."

    Totally ridiculous, man...this guy needs to be seriously chastised.

  • (unregistered)

    Maybe Amazon is trying to tell you something...

  • (cs)

    <font style="BACKGROUND-COLOR: #efefef">But don't hexadecimal numbers store more compactly?  This really could be a disk storage issue...[:P]</font>

  • (cs) in reply to

    There is some chicanery going on at Amazon. I had a similarly ‘off topic’ suggestion in my “Recommended” DVDs yesterday. I’m just curious if these are coming from the inside of the company or from external forces. Hmmm….<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

  • (unregistered) in reply to

    Oh, yes there can. From "Programming Ruby, A Pragmatic Programmer's Guide":

    "Yes, seconds really can range from zero to 60. This allows the system to inject leap seconds every now and then to correct for the fact that years are not really a convenient number of hours long."

  • (cs) in reply to

    <font size="2">It makes perfect sense that HttpUtility is more generic and the HttpServerUtility is tied to the server itself. I'm sure that the HttpServerUtility method calls the HttpUtility method. You can use the reflector to confirm this.</font>


    Okay, reflector turned up this, which does back up what you said.  It uses the current request's encoding (which didn't work in my case, as I'm making a request to a different server).  It defaults to UTF8.
    [code language="c#"]
    public string UrlDecode(string s)
    {
       Encoding encoding1 = (this._context != null)
          ? this._context.Request.ContentEncoding : Encoding.UTF8;
       
       return HttpUtility.UrlDecode(s, encoding1);
    }
    [/code]

    Blah...
  • (cs)
    case 58: m_TagTime.Minute = 0x3f;break; 
    case 59: m_TagTime.Minute = 0x3a;break;
    case 60: m_TagTime.Minute = 0x3b;break;
    I wonder whether there's a reason for these not to match or whether these are typos. At a guess, 0 might not need handling because m_TagTime.Minute is initialised to 0. More likely, though the programmer is just an idiot. After all, there are no leap minutes.
  • (cs)

    Looks alright to me... The only WTF is that the poor guy had to type all those break statements... maybe that is a WTF of the language design..[:#]

  • (cs) in reply to DanielMoth

    Daniel -- you're joking, right?  Please tell me you are ... 
    .

  • (cs)

    I don't see any better way of doing URLDecode. Oh wait a sec...

    Function URLDecode(tStr)
      splitStr = Split(tStr, "%")
      outStr = splitStr(0)

      For a = 1 to Ubound(splitStr)
        If Len(splitStr(a)) >= 2 Then
          tcharInt = (HexVal(Mid(splitStr(a), 1, 1)) * 16) + (HexVal(Mid(splitStr(a), 2, 1))
          outStr = outStr & Chr(tcharInt) & Mid(splitStr(a), 3)
        Else
          outStr = outStr & "%" & splitStr(a)
        End If
      Next
      URLDecode = outStr
    End Function

    Function HexVal(tVal)
      If Len(tval) = 0 Then
        HexVal = 0
        Exit Function
      End If

      tVal = UCase(Mid(tVal, 1, 1))

      Select Case tVal
        Case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
          HexVal = CInt(tVal)
        Case "A", "B", "C", "D", "E", "F"
          HexVal = 10 + Asc(tVal) - Asc("A")
        Case Else
          HexVal = 0
      End Select
    End Function


    I AR A VB PROGREMUR! I guess I wouldn't get paid much considering that reduces 200 lines down to 32.

  • (unregistered)

    [:S]  Gasp.....  Really bad programming style.

  • (cs) in reply to Manni

    hey mr. VB programmer -- would you mind adding some declarations and datatypes to the code? [:O]

  • (unregistered)

    Although I enjoy this site, I gotta point out that the stones ya'll throw are pretty close to your glass houses.  Examples:

    1)  Try the pound sign to the left of the dates on the main page. It's everyone's friend, the null reference exception!  It links here.

    2)  Perhaps the redirect listed in the article should work?  You know, the MSNBC article that clearly came from an OWA message link?

    <EDITOR: Fixed Link on #2. I'm surprised it took almost50 comments to point this out [:$]>

  • (unregistered)

    Yeah, that's pretty fucked up. If he had any brains, he'd know that you can take the address of a struct member. He could've done the whole thing in a loop, and reused the loop into the bargain:

    <font face="Courier New" size="2">void m_setTimeMember( int * pnMember, int nValue )
    {
    <font color="#808080">//  No reason to waste time initializing this again
    //  every time we're called</font>
    static int i = 0;
    <font color="#808080">//  Future-proof it with a big value.</font>
    static const int MAXVAL = 0x7fffffff;
    for ( ; i < MAXVAL; ++i ) {
    char buf[ 256 ];
    <font color="#808080">//  Convert to hex</font>
    sprintf( buf, "0x%x", i );
    if ( strtol( buf, NULL, 0 ) == nValue )
    *pnMember = strtol( buf, NULL, 0 );
    }
    }

    <font color="#808080">//  Now call this from the various public methods:
    </font>
    void m_SetSecond( CTime &Time )
    {
    m_setTimeMember( &(m_TagTime.Second), Time.GetSecond() );
    }

    <font color="#808080">//  etc.</font>

    </font>I feel really sorry for some of these poor clueless dweebs and I try to help any way I can. The above code is free to use if anybody's having trouble with a similar problem.

  • (cs) in reply to
    :
    Yeah, that's pretty f*cked up. If he had any brains, he'd know that you can take the address of a struct member. He could've done the whole thing in a loop, and reused the loop into the bargain:

    <font face="Courier New" size="2">void m_setTimeMember( int * pnMember, int nValue )
    {
    <font color="#808080">//  No reason to waste time initializing this again
    //  every time we're called</font>
    static int i = 0;
    <font color="#808080">//  Future-proof it with a big value.</font>
    static const int MAXVAL = 0x7fffffff;
    for ( ; i < MAXVAL; ++i ) {
    char buf[ 256 ];
    <font color="#808080">//  Convert to hex</font>
    sprintf( buf, "0x%x", i );
    if ( strtol( buf, NULL, 0 ) == nValue )
    *pnMember = strtol( buf, NULL, 0 );
    }
    }

    <font color="#808080">//  Now call this from the various public methods:
    </font>
    void m_SetSecond( CTime &Time )
    {
    m_setTimeMember( &(m_TagTime.Second), Time.GetSecond() );
    }

    <font color="#808080">//  etc.</font>

    </font>I feel really sorry for some of these poor clueless dweebs and I try to help any way I can. The above code is free to use if anybody's having trouble with a similar problem.



    LOL! You were joking, right?
  • (unregistered) in reply to

    <font face="Arial" size="3">The real WTF is that there can be no hour 24.  Or minute 60... or second 60... Besides that, he doesn't do any "magix hex number" for minute 0 and second 0.</font>

    Actually, there can be a second 60. Those would be the leap seconds (23:59:60) that international agencies insert into some of our days because the earth's day does not quite have a whole number of seconds and because the earth's day is getting slightly longer.

    The leap seconds have nothing to do with the earth year not having a whole number of earth days. That's what February 29th is all about.

  • (unregistered)
    Alex Papadimoulis:
    And speaking of the URLEncode function, Dave Crowell just pointed out that he found its compliment: URLDecode.


    Great WTF - but note that the above should be "complement" ;-)
  • (unregistered)

    Uhmm..  Daniele?  No wtf?  I think a proper implemenation will clarify, down to the size of the variables (2 bytes) that he uses..

    m_TagDate.Year = (short)(Time.GetYear() - 2000);
    m_TagDate.Month = (short)Time.GetMonth();
    m_TagDate.Day = (short)Time.GetDay();
    m_TagDate.Hour = (short)Time.GetHour();
    m_TagDate.Minute= (short)Time.GetMinute();
    m_TagDate.Second= (short)Time.GetSecond();

    I don' t get why he did what he did.  The above accomplishes the exact same thing, thats what makes it a WTF.

  • (cs) in reply to Jeff S

    Jeff: This is ASP, and with VBScript there's no need to declare variables. If it was full-on VB, my function declarations would be a bit more detailed:

    Private Function URLDecode(ByVal strURL as String) As String

    I wasn't making fun of VB programmers, it's basically the only thing I write in. I was making fun of how easy it is to create a function to do what you need and how the person who wrote up a tutorial that was actually published had hardcoded nearly the entire ASCII table.

    I'm surprised by the code I inherit (though it's not worthy of being a WTF) because VB programmers I encounter are stumped because there's no ready-made function to convert geographic coordinates from DMS to DD. They have no clue how to make a function actually WORK for them.

  • (unregistered) in reply to Jeff S

    So, if I read this correctly, except for the typos, the m_SetSecond() function basically does the same as typing:

    m_TagTime.Second = Time.GetSecond();

    Maybe the typos are actually data encryption.  And what's with the m_ prefix?  Does anyone else use hungarian notation for function names?

    - Joshua

  • (cs)

    That URLDecoder is actually much worse than the Encoder earlier, and was exactly what I was thinking would make the other worse: Reassigning on each and every test, whether or not it changed anything. At least the other used cases and only reallocated sanely.

    This is exactly why I test all code I copy from the internet or books.

    I bet IIS4/5 had a very similar bug where % was decoded first. (The infamous double-decode path traversal that Code Red exploits.)

  • (cs) in reply to David Crowell
    Okay, reflector turned up this, which does back up what you said. It uses the current request's encoding (which didn't work in my case, as I'm making a request to a different server). It defaults to UTF8.

    If you're making a request to a different server, why are you calling UrlDecode on this server's object? It looks like the only reason that function exists is to get access to the _context, which I assume is private. But you don't need that anyway, so, assuming you know the encoding to use, why not just use HttpUtility.UrlDecode directly?

  • (unregistered)

    ...one thing that keeps me regularly asking "WTF" are women. Maybe you can write about this topic, too [;)]

    Thanks
    Uwe

  • (cs) in reply to JoeNotCharles

    <font size="2">If you're making a request to a different server, why are you calling UrlDecode on this server's object? It looks like the only reason that function exists is to get access to the _context, which I assume is private. But you don't need that anyway, so, assuming you know the encoding to use, why not just use HttpUtility.UrlDecode directly?


    Because I didn't know about the "HttpUtility.UrlDecode" option when looking it up intially.  I guess I was just used to using HttpServerUtility.UrlDecode (as exposed by Server.UrlDecode) from my classic ASP days.  I'm still trying to get rid of those memories. [*-)]

    I did end up using HttpUtility.UrlDecode, and specifying the proper encoding type.  </font>
  • (unregistered) in reply to
    :
    Agreed, except for "second 60". There are leap seconds (because years don't actually consist of convenient numbers of hours).

    We use leap days for that purpose. (With complex rules for which years to assign them to to handle the fractions.)

    Leap seconds have to do with inconsistancies between the Earth's spin and what we consider a day.

    In any case. It's unlikely that the system this code is used on handles leap-seconds.  Since the Earth's spin is not exactly a constant there's no hard and fast rules for assigning leap-seconds.  You'd have to know when they were and set your clock back at the right moment.
  • (cs)
    :
    Yeah, that's pretty fucked up. If he had any brains, he'd know that you can take the address of a struct member. He could've done the whole thing in a loop, and reused the loop into the bargain:

    <font face="Courier New" size="2">void m_setTimeMember( int * pnMember, int nValue )
    {
    <font color="#808080">//  No reason to waste time initializing this again
    //  every time we're called</font>
    static int i = 0;
    <font color="#808080">//  Future-proof it with a big value.</font>
    static const int MAXVAL = 0x7fffffff;
    for ( ; i < MAXVAL; ++i ) {
    char buf[ 256 ];
    <font color="#808080">//  Convert to hex</font>
    sprintf( buf, "0x%x", i );
    if ( strtol( buf, NULL, 0 ) == nValue )
    *pnMember = strtol( buf, NULL, 0 );
    }
    }

    <font color="#808080">//  Now call this from the various public methods:
    </font>
    void m_SetSecond( CTime &Time )
    {
    m_setTimeMember( &(m_TagTime.Second), Time.GetSecond() );
    }

    <font color="#808080">//  etc.</font>

    </font>I feel really sorry for some of these poor clueless dweebs and I try to help any way I can. The above code is free to use if anybody's having trouble with a similar problem.

    Damn - I really hop you're joking... the original stunned me a bit - but this is really fucked up... The comment "No reason to waste time initializing this again every time we're called" really is the finishing touch... You're only wasting thousands and thousands of times the cpu-power necessary.... Oh boy...

  • (unregistered) in reply to
    :
    CClassname is an MFC convention, it has nothing whatsoever to do with C++. Check out the STL, do you see any in there? Oh wait... as a VB programmer you probably dont know what the STL is.  Stick out tongue
  • (cs)

    Look you dopes, it's eeezy, you just subtract one from everything before you use it...

    Voila, minutes have 59 seconds, days 23 hours and those other things, hours, have 59 minutes. I honestly don't think that this guy knew about leap seconds as he doesn't know how clocks work...

    You could then use it like:

    int hour = --m_TagTime.Hour;
    if(hour < 0) hour = 0; // Because hours CAN be 0 all ready

    int minute = --m_TagTime.Minute;
    int second = --m_TagTime.Second;

    if(hour == 0 && minute == 0 && second == 0) 
       launch_thermonuclear_projectile(designatedTarget);
    else
       Console.Writeline("Global Thermonuclear War averted, again...";

  • (cs) in reply to smudge

    No, look, before any of you clever-trousers pick up on it, it should be

    LaunchThermonuclearProjectile(designatedTarget);

    or

    LaunchThermoNuclearProjectile(designatedTarget);

    I knew that.

  • (cs) in reply to smudge

    I think I'd prefer the condition to be hour = 0 && minute = 0 && second = 0. (Think carefully before correcting this.)

  • (cs) in reply to Stan Rogers
    Stan Rogers:
    Sweet Enola Gay!


    I would have to agree with Stan. Ow. That's all I can say; is ow.






    Hexidecimal *shudders* [+o(]
  • (cs) in reply to Manni
    Manni:
    I AR A VB PROGREMUR! I guess I wouldn't get paid much considering that reduces 200 lines down to 32.


    Now if only you could reduce your spelling to efficient; you might get paid more.
  • (cs)
    Alex Papadimoulis:
    Note the elite use of hexidecimal.
    Everybody knows "real programmers code in binary".
  • (unregistered)
    [code language="vb"]
          case 57: m_TagTime.Second = 0x39;break;
          case 58: m_TagTime.Second = 0x3f;break;
          case 59: m_TagTime.Second = 0x3a;break;
          case 60: m_TagTime.Second = 0x3b;break;


    [/code]
    Shouldn't 58 = 0x3a, 59 = 0x3b, and 60 = 0x3c...?





  • (cs)

    Also, Alex, I think it would've been nice if you had posted URLDecode in a separate WTF instead of at the end of this one, so we would have had comments about the two separated and not jumbled together.

Leave a comment on “Stand Back, I've got Hexidecimal”

Log In or post as a guest

Replying to comment #:

« Return to Article