TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: alanjt on November 17, 2011, 10:54:58 AM

Title: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: alanjt on November 17, 2011, 10:54:58 AM
I was playing around with the vlax-add-cmd function (have used it many times before), but I tried it on a LISP routine that had a command call in it and everything went crazy. Seems the issue stems from having while check to the cmdactive system variable to continue providing a pause.
Here's a sample code to break AutoCAD (a restart fixes everything, so don't worry):

Code: [Select]
(defun _tester (a b)
  (vl-cmdf "_.line")
  (while (eq (logand (getvar 'CMDACTIVE) 1) 1) (vl-cmdf PAUSE))
  (princ)
)

(defun woo nil (_tester nil nil) (princ))

(vlax-add-cmd "woo" 'woo "woo" 1)


and here's what happens (if I remove the while statement, everything is fine):

Code: [Select]
Command:
WOO _.line Specify first point:
Invalid point.
Specify first point: *Cancel*

Command:
WOO _.line Specify first point:
Specify next point or [Undo]:
Specify next point or [Undo]:
Specify next point or [Close/Undo]: *Cancel*

Command: *Cancel*

Command: e ERASE
Select objects: 0 found
Select objects: 0 found
Select objects:

Command: *Cancel*

Command: e ERASE
Select objects: 0 found
Select objects: 1 found

Select objects: 1 found, 2 total

Select objects:

Command:
WOO _.line
Commands may not be nested more than 4 deepUnknown command "LINE".  Press F1
for help.

Command: *Cancel*

Command: *Cancel*

Command: *Cancel*

Command: *Cancel*

Command: *Cancel*

Command: *Cancel*

Command: e
ERASE
Commands may not be nested more than 4 deepUnknown command "ERASE".  Press F1
for help.


Command: e ERASE
Commands may not be nested more than 4 deepUnknown command "ERASE".  Press F1
for help.

Command:  WOO
Commands may not be nested more than 4 deepUnknown command "WOO".  Press F1 for
help.

Command:  WOO
Commands may not be nested more than 4 deepUnknown command "WOO".  Press F1 for
help.

Command:  WOO
Commands may not be nested more than 4 deepUnknown command "WOO".  Press F1 for
help.

Command:  WOO
Commands may not be nested more than 4 deepUnknown command "WOO".  Press F1 for
help.

I'm not trying to provide information on how to break someone's AutoCAD, I just though this was interesting and valuable information to provide for fellow coders to avoid.
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: alanjt on November 17, 2011, 10:59:05 AM
After I did this, I couldn't even close out of the drawing. I had to crash AutoCAD.
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: Jeff H on November 17, 2011, 11:05:36 AM
Is this 2012?
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: alanjt on November 17, 2011, 11:06:29 AM
Is this 2012?
Only tested in 2011 (civil 3d).
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: mjfarrell on November 17, 2011, 11:17:39 AM
Is this 2012?
Only tested in 2011 (civil 3d).
One can BREAK Civil 3D without use of any code easy enough.  Ask me....I know
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: alanjt on November 17, 2011, 11:18:24 AM
Is this 2012?
Only tested in 2011 (civil 3d).
One can BREAK Civil 3D without use of any code easy enough.  Ask me....I know
lol, sad but true.
Title: Re: I think I figured out how to break AutoCAD with a bit of LISP...
Post by: irneb on November 17, 2011, 10:25:09 PM
lol, sad but true.
:lmao: ... Yep, many a time I crash ACad (2005 - 2012) by simply opening a DWG file which was exported from Revit as a 3D model.  :ugly: Doesn't matter which acad, Vanilla / ACA. As long as the model is anything worthwhile, acad can't handle it.

Back to your scenario: I think it's due to the vlax-add-cmd which actually turns the lisp defun into an ACad internal command. Now we all know that ALisp is not in the least thread based, but most of ACad's internal commands use some form of threading - especially transaction based. You notice in some cases when making commands in DotNet that you need to use transactions in order to avoid crashes.

This is especially prevalent when there's a lot of user interaction in the command itself. And that loop is thus causing some large quantities of waiting for user input. Perhaps it's due to the way the lisp thread is actually the same thread which is reading any user input. If called normally with a c:defun the lisp runs syncronously, but may be started and stopped when it's an internal command. This might cause the lisp interpreter to fail, have seen this happen in VLIDE while debugging.

Just guessing of course. But, it's an "educated" guess  :angel: