Everything I know is wrong!



  • So apparently someone here thought it was a good idea to change the execute function in Lua. In any other situation running os.execute('cd') (under Win32) would run cd, directing its output through stdout, and return its status code (zero). Now instead, someone overwrote it with a custom implementation that yields no output and returns null and 2 for some reason. It takes up to 5 parameters in some places that it is used, and there's no way to go back and use the standard version! On top of that we don't have the code for our own product, so I can't poke around and figure out why nothing works right now! WTF?!?!?!?

    Brillant.



  • @djork said:

    we don't have the code for our own product
    Sometimes I feel my job sucks, but then I visit thedailywtf.com and suddenly I feel so fortunate...



  • @djork said:

    So apparently someone here thought it was a good idea to change the execute function in Lua.

    How...

    we don't have the code for our own product

    But I thought...

    No.  For the love of God, and all that is holy, no.  How do you make changes?  How did you lose the code in the first place?



  • Did you know that you actually need to execute

    %CMDSPEC% /c cd

    CreateProcess doesn't understand cmd.exe commands. It understands if you give it batch file name, though.



  • @alegr said:

    Did you know that you actually need to execute

    %CMDSPEC% /c cd

    CreateProcess doesn't understand cmd.exe commands. It understands if you give it batch file name, though.

    I'm not sure what you're talking about. The built-in Lua 4.0 and 5.1 execute functions work just fine with a simple command string.



  • @Justice said:

    @djork said:

    So apparently someone here thought it was a good idea to change the execute function in Lua.

    How...

    we don't have the code for our own product

    But I thought...

    No.  For the love of God, and all that is holy, no.  How do you make changes?  How did you lose the code in the first place?

    A) Because you can change anything in Lua. You can change the builtin global functions.

    B) Because some guy wrote the runtime and many core functions in C, and we license the executable from him.



  • @DOA said:

    Sometimes I feel my job sucks, but then I visit thedailywtf.com and suddenly I feel so fortunate...

     

    Sometimes I feel my job sucks, but then I visit thedailywtf.com and suddenly realize I can't expect much better.



  •  I remember having this before and the solution I found was to hex edit the files. The custom function changes to xxecute, and so execute is back to being a normal function again. 

     Simples! :-)



  • @Mole said:

     I remember having this before and the solution I found was to hex edit the files. The custom function changes to xxecute, and so execute is back to being a normal function again. 

     Simples! :-)

    How elegant... and with no chance of unintended side-effects!



  • @djork said:

    So apparently someone here thought it was a good idea to change the execute function in Lua. In any other situation running os.execute('cd') (under Win32) would run cd, directing its output through stdout, and return its status code (zero). Now instead, someone overwrote it with a custom implementation that yields no output and returns null and 2 for some reason.

    You've forgotten that 2 is our favourite errno of all time round here?

    @djork said:

    It takes up to 5 parameters in some places that it is used, and there's no way to go back and use the standard version! On top of that we don't have the code for our own product, so I can't poke around and figure out why nothing works right now! WTF?!?!?!?

    Brillant.

    Argh.  I'm guessing that some genius decided to make the API more CreateProcess-alike, meaning you do indeed now have to use a %COMSPEC% /c prefix after all.  You should be able to deduce something about the new API from the 5 parameters that you see used?


  • @djork said:

    @alegr said:

    Did you know that you actually need to execute

    %CMDSPEC% /c cd

    CreateProcess doesn't understand cmd.exe commands. It understands if you give it batch file name, though.

    I'm not sure what you're talking about. The built-in Lua 4.0 and 5.1 execute functions work just fine with a simple command string.

     

    Yep, the lua builtins use the 'system' function from the MSVCRT library.  The most logical explanation for what you're seeing is that the new implementation is based instead on the 'CreateProcess' API from the underlying system libraries; MSVCRT builds on top of them to handle invoking cmd.exe (or other command interpreter) for you.  If you're really stuck with this override, you'll need to get a good handle the differences between those two functions to deal with it.

    Of course getting rid of it altogether would be preferable, but if half the codebase is already moved over to the new interface, you're gonna meet with resistance. :-(



  • Can you not do something like TheSupplierIsAMoron = execute before the function gets changed, at the very first line of code? Or is even that too late?



  • @djork said:

    A) Because you can change *anything* in Lua. You can change the builtin global functions.

    B) Because some guy wrote the runtime and many core functions in C, and we license the executable from him.

     

    In Vax Pascal, you can change *constants*. Apparently, it's faster to point to a constant already in memory than load it into a register on a Vax (since the load would be an extra operation and the operation can work on memory directly). So they keep 'key' constants in memory, 0, 1, 2, -1, and a few others. So if you add 5 to something that's already in a register, it uses add immediate. If you add 2, it uses add from the memory that holds the constant 2.

    Well, Pascal has pass by reference. And you're not supposed to pass a constant by reference. But it will let you do. And if you do, and the function changes the reference, and you pass one of the magic constants, it will change the value of the constant.

    I have long since forgotten Pascal syntax, but the C++ equivalent would be:

    void Dec(int &i) { i--; }

     

    Dec(&2);

    if(2==1)

    {

     // Yes, 2 is now equivalent to 1

    }

     



  • @DaveK said:

    Argh.  I'm guessing that some genius decided to make the API more CreateProcess-alike, meaning you do indeed now have to use a %COMSPEC% /c prefix after all.  You should be able to deduce something about the new API from the 5 parameters that you see used?

    Well, I've managed to make it work without adding that prefix, but thanks for the clues! It looks like this version of execute does indeed match up to CreateProcess in some way.


    BOOL WINAPI CreateProcess(
    __in_opt LPCTSTR lpApplicationName,
    __inout_opt LPTSTR lpCommandLine,
    __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
    __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in BOOL bInheritHandles,
    __in DWORD dwCreationFlags,
    __in_opt LPVOID lpEnvironment,
    __in_opt LPCTSTR lpCurrentDirectory,
    __in LPSTARTUPINFO lpStartupInfo,
    __out LPPROCESS_INFORMATION lpProcessInformation
    );

    Out of all of those parameters, I can at least tell that we're doing something along the lines of execute(lpApplicationName, lpCommandLine, ???, lpCurrentDirectory).



  • @djork said:

    It looks like this version of execute does indeed match up to CreateProcess in some way.

            [ . . . ]

    Out of all of those parameters, I can at least tell that we're doing something along the lines of execute(lpApplicationName, lpCommandLine, ???, lpCurrentDirectory).

    BTW, are you allowed to deploy binary Lua plug-ins in this project?  I reckon you could easily arrange to re-import the system() function from the MSVCRT dll if you really did want to get the original one back!  OTOH maybe there actually was some sound reason behind this poorly-documented change... I could imagine maybe the lower-level interface worked better with unicode, or maybe with arbitrary stdio redirections, or something.



  • @joelkatz said:

    void Dec(int &i) { i--; }
    // Dec(&2);
    Dec(2); // The function takes a reference, don't pass in an address
    if(2==1)
    {
    // Yes, 2 is now equivalent to 1
    }

    FTFY.

    Python does the same thing with some common constants (integers from 0 to 100 for example IIRC), but objects holding basic data types are not mutable from Python code (you can only bind a new object to a name, not modify the existing one).  However, when writing extensions in C, it is possible to modify these constants.  I believe you need to use that rather forcibly with typecasts and such, so it's not likely to happen by accident. 



  • @DaveK said:

    BTW, are you allowed to deploy binary Lua plug-ins in this project?

    Nope. It's a complete and utter black-box situation. The only way to extend it is with Lua (4.0) code. No source code, no documentation, no clues.



  • @joelkatz said:

    In Vax Pascal, you can change constants. (SNIP)



    Funny, when i heard that story last time it was about some (IBM i think, but might be DEC) FORTRAN compiler.



  •  Crap, you're right! I'm remembering incorrectly. It was definitely Fortran, not Pascal. And Vax's are DEC machines.



  • @joelkatz said:

     Crap, you're right! I'm remembering incorrectly. It was definitely Fortran, not Pascal. And Vax's are DEC machines.


    I know what a VAX is. I was saying that i think that those modifiable constants were a "feature" of some IBM FORTRAN compiler.



  • @joelkatz said:

    Vax's

    The invented plural "vaxen" exists to avoid just this problem :-)


  • @djork said:

    @DaveK said:
    BTW, are you allowed to deploy binary Lua plug-ins in this project?

    Nope. It's a complete and utter black-box situation. The only way to extend it is with Lua (4.0) code. No source code, no documentation, no clues.

    Well, the source code for Lua is of course available, but maybe I shouldn't recommend taking a chainsaw to the language interpreter just to work around a problem in the application!



  • @DaveK said:

    @djork said:

    @DaveK said:
    BTW, are you allowed to deploy binary Lua plug-ins in this project?

    Nope. It's a complete and utter black-box situation. The only way to extend it is with Lua (4.0) code. No source code, no documentation, no clues.

    Well, the source code for Lua is of course available, but maybe I shouldn't recommend taking a chainsaw to the language interpreter just to work around a problem in the application!

    Starting with the source is exactly what I'm doing now. That's kind of the whole point of Lua: it's just a library and it's up to you to implement the application that loads and runs the code. They do provide a standalone command-line interpreter, though. That's a good starting point for a lot of cases.



  • @djork said:

    @DaveK said:

    @djork said:

    @DaveK said:
    BTW, are you allowed to deploy binary Lua plug-ins in this project?

    Nope. It's a complete and utter black-box situation. The only way to extend it is with Lua (4.0) code. No source code, no documentation, no clues.

    Well, the source code for Lua is of course available, but maybe I shouldn't recommend taking a chainsaw to the language interpreter just to work around a problem in the application!

    Starting with the source is exactly what I'm doing now. That's kind of the whole point of Lua: it's just a library and it's up to you to implement the application that loads and runs the code. They do provide a standalone command-line interpreter, though. That's a good starting point for a lot of cases.

    Well, if you've really lost the source to the original app and adding lua code is now the only way to modify its functionality, I think you could make a good argument for adding a binary extension plugin that could be your get-out-of-jail-free card in a lot of possible future situations where you need to do something that the lua implementation in the application doesn't support.  Depends if you're planning to maintain this long term and do a lot of customer support on it.

    Also, maybe, just maybe the original coder didn't override the execute function but renamed it in the lua source and added his own separately?  You could run 'strings' over the executable and try and find this command table and see if the name's been changed:

    @lua-5.1.4/src/loslib.c said:

    [code]

    static const luaL_Reg syslib[] = {
      {"clock",     os_clock},
      {"date",      os_date},
      {"difftime",  os_difftime},
      {"execute",   os_execute},
      {"exit",      os_exit},
      {"getenv",    os_getenv},
      {"remove",    os_remove},
      {"rename",    os_rename},
      {"setlocale", os_setlocale},
      {"time",      os_time},
      {"tmpname",   os_tmpname},
      {NULL, NULL}
    };
    [/code]

    LOL.  Ah, there's TRWTF, as usual!



  • @Justice said:

    @djork said:

    we don't have the code for our own product

    But I thought...

    No.  <snip>  How did you lose the code in the first place?

    When I encountered that situation, the code was lost because some twit felt restricting access to the code was his route to job security.  When management decided to force the issue, he bulk-erased his system to thwart their force.  Of course, being the clueless git he was, he also managed to bulk-erase his backup disk, and his off-site backup was something like revision 0.2, rather than something similar to 4.140.12

    Fun note: ancient1 Sparc workstations don't boot very well after all of the nvram chips2 (both those on the motherboard itself and those on various expansion cards) have been bulk-erased.

    Just as a historical note, this strategy did *not* save his job.  Instead, it cost him his severance pay and unemployment benefits, and gained him a threat of legal counter claims if he ever had any thought of trying any legal action to get either back.  (Well, at least, that's what I was told - but I came in after all the excitement, so I only know what I was told.)

    1 Modern at the time, but this was over a decade ago.

    2 Technically, I believe these were actually battery-backed RAM, but I'm not certain.



  • @DaveK said:

    Well, if you've really lost the source to the original app and adding lua code is now the only way to modify its functionality, I think you could make a good argument for adding a binary extension plugin ...

    I can't add anything to the existing executable that isn't straight-up Lua 4 code. I can't load C libraries dynamically or anything like that because Lua 4 doesn't support that. The only way to add the ability to load binary C libraries at runtime would be to throw the whole thing out and rewrite the application again, which is what I'm doing.

    Unless I'm misunderstanding you (or Lua 4's abilities)?



  • @djork said:

    @DaveK said:
    Well, if you've really lost the source to the original app and adding lua code is now the only way to modify its functionality, I think you could make a good argument for adding a binary extension plugin ...

    I can't add anything to the existing executable that isn't straight-up Lua 4 code. I can't load C libraries dynamically or anything like that because Lua 4 doesn't support that. The only way to add the ability to load binary C libraries at runtime would be to throw the whole thing out and rewrite the application again, which is what I'm doing.

    Unless I'm misunderstanding you (or Lua 4's abilities)?

    Nope, just that I forgot you'd mentioned the version.  Yep, loadlib was added in v5.

Log in to reply