In the past C++/C era, it was very easy to crash AutoCAD or even the whole Operating System. Now in the .NET time, it is harder, much harder than before, but we still can find various ways to crash AutoCAD using its .NET API, from the easiest or most common to quite hard or very creative.
Previously, we demonstrated manipulating various XData types such as string, binary chunk, integer, point and vector in various ways such as reading, writing, deleting, replacing and copying. In fact, we can easily crash AutoCAD too with the XData .NET API. Here is one way.
[CommandMethod("Crash14")]
public static void Crash14_Method()
{
const string TestAppName = "BinaryChunkXDataLimit_TestApp";
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptEntityResult prEntRes = ed.GetEntity("Select an Entity to do the test");
if (prEntRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
RegAppTable regAppTable = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!regAppTable.Has(TestAppName))
{
using (RegAppTableRecord regAppRecord = new RegAppTableRecord())
{
regAppRecord.Name = TestAppName;
regAppTable.UpgradeOpen();
regAppTable.Add(regAppRecord);
tr.AddNewlyCreatedDBObject(regAppRecord, true);
}
}
string str = string.Empty;
for (int i = 0; i < 1000; i++)
{
try
{
using (Transaction subTr = db.TransactionManager.StartTransaction())
{
str += "A";
Entity ent = (Entity)subTr.GetObject(prEntRes.ObjectId, OpenMode.ForWrite);
ent.XData = new ResultBuffer
(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, TestAppName),
new TypedValue((int)DxfCode.ExtendedDataBinaryChunk, Encoding.ASCII.GetBytes(str))
);
subTr.Commit();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\nThe maximum length of XData binary chunk is: {0}", i);
ed.WriteMessage("\n{0} will occur if the limit is exceeded.", ex.ErrorStatus);
break;
}
}
tr.Commit(); //We commit the outter transaction here to try something else next such as the Audit command.
//tr.Abort(); //We'd better abort the transaction to avoid database mess up if the test is done in a DB in use.
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
After the assembly is loaded, an entity such as a circle is drawn, the Crash14 command is run, the entity is selected, and the MOVE command is run afterwards, the circle will disappear and the following fatal error come up.
“INTERNAL ERROR: !xd.cpp@403: eInvalidInput”
If we run the Audit and Regen commands for example in between the Crash14 and Move, AutoCAD looks fine.
So, it seems the XData binary chunk is too large in the case, but the bad part is that no hints at all indicate the problem before the crash. By the way, if a lot of other code follows the simple XData binary chunk operation and a few other people are in the same development team, it’s likely that the trouble-shooting bucket will be passed round and round.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides project wizards in C#, VB.NET and CLI/Managed C++, and various item wizards such as Event Handlers, Command/LispFunction Definers, and Entity/Draw Jiggers in both C# and VB.NET, to help program AutoCAD addins.
Posted by: |