home *** CD-ROM | disk | FTP | other *** search
- /*________________________________________________________________________________
-
- BadErrors.c
-
- Copyright © 1993-1995 Onyx Technology - All rights reserved
-
- This file contains the routines that performs the errors for BadAPPL.
-
- There is use of a routine called ‘OutputString’ in every routine. This routine simply
- outputs string resources to the status window during each test. If you are trying to
- follow what the code is doing, you can ignore calls to this routine.
-
- Also note that heavy use of the QC API is done in this file. Each routine makes
- sure that the QC test it will be testing is active by setting the threshold to the
- activation level of that test. This is done with code similar to:
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcValidateHandlePointers, true); // make sure validate handle/ptrs is on
-
- If you are not familiar with the API routines, please refer to ‘Section 5 - Inside QC’
- of the QC User Manual.
-
- Like all other files related to BadAPPL, intentional errors are marked like:
- // •-> BAD - This is an intentional error
-
- ________________________________________________________________________________*/
-
- #ifndef _H_BadAPPL
- #include "BadAPPL.h"
- #endif
- #ifndef _H_BadWindows
- #include "BadWindows.h"
- #endif
- #ifndef _H_BadUtils
- #include "BadUtils.h"
- #endif
- #ifndef _H_BadMacros
- #include "BadMacros.h"
- #endif
- #ifndef _H_BadErrors
- #include "BadErrors.h"
- #endif
- #ifndef _H_BadGlobs
- #include "BadGlobs.h"
- #endif
- #ifndef _H_QCAPI
- #include "QCAPI.h"
- #endif
-
- static short gQCDetectedErr;
-
- // QC error handler installation routines
- Boolean MyErrorHandler(QCPBPtr paramBlock);
-
- /*________________________________________________________________________________
-
- DoHandleExistance()
-
- info: This routine performs the create/dispose test on Handles or Pointers
- depending on the value passed in onHandle.
-
- entry: onHandle - true if we are testing Handles, false if we are testing Pointers
-
- ________________________________________________________________________________*/
- void DoHandlePtrExistance(Boolean onHandle)
- {
- QCStateHandle saveStateH;
- Handle testHnd = 0L;
- Ptr testPtr = 0L;
- short stringsID;
-
- if (onHandle)
- stringsID = kHndStringsID; // we are performing a handle test
- else
- stringsID = kPtrStringsID; // we are performing a Ptr test
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcValidateHandlePointers, true); // make sure validate handle/ptrs is on
- gQCDetectedErr = kQCNoErr;
-
- OutputString( stringsID, kHndPtr1, 0L);
-
- if (onHandle) // are we testing Handles or Pointers?
- testHnd = NewHandle(12800); // create a handle
- else
- testPtr = NewPtr(12800); // create a pointer
-
- if ((onHandle && (!testHnd)) || (!onHandle && (!testPtr)))
- OutputString(stringsID, kHndPtr2, 0L);
- else
- {
- if (onHandle) // are we testing Handles or Pointers?
- OutputString(stringsID, kHndPtr3, (long) *testHnd);
- else
- OutputString(stringsID, kHndPtr3, (long) testPtr);
-
- if (onHandle) // are we testing Handles or Pointers?
- DisposHandle(testHnd); // this is okay, disposing the Handle here
- else
- DisposPtr(testPtr); // this is okay, disposing the Ptr here
-
- OutputString(stringsID, kHndPtr4, 0L);
-
- OutputString(stringsID, kHndPtr5, 0L);
-
- if (onHandle) // are we testing Handles or Pointers?
- DisposHandle(testHnd); //•-> BAD - the Handle is already disposed!
- else
- DisposPtr(testPtr); //•-> BAD - the Ptr is already disposed!
-
- DetectedMsgs();
- }
-
- OutputString( stringsID, kHndPtr6, 0L);
-
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
-
-
-
- /*________________________________________________________________________________
-
- DoHandlePtrResize()
-
- info: This routine performs the resize tests on Handles or Pointers
- depending on the value passed in onHandle.
-
- entry: onHandle - true if we are testing Handles, false if we are testing Pointers
-
- ________________________________________________________________________________*/
- void DoHandlePtrResize(Boolean onHandle)
- {
- QCStateHandle saveStateH;
- Handle testHnd = 0L;
- Ptr testPtr = 0L;
- short stringsID;
-
- if (onHandle)
- stringsID = kHndStringsID; // we are performing a handle test
- else
- stringsID = kPtrStringsID; // we are performing a Ptr test
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcValidateHandlePointers, true); // make sure validate handle/ptrs is on
- gQCDetectedErr = kQCNoErr;
-
- OutputString( stringsID, kHndPtr11, 0L);
-
- if (onHandle) // are we testing Handles or Pointers?
- testHnd = NewHandle(128); // create a handle
- else
- testPtr = NewPtr(128); // create a pointer
-
- if ((onHandle && (!testHnd)) || (!onHandle && (!testPtr)))
- OutputString(stringsID, kHndPtr12, 0L);
- else
- {
- if (onHandle) // are we testing Handles or Pointers?
- OutputString(stringsID, kHndPtr13, (long) *testHnd);
- else
- OutputString(stringsID, kHndPtr13, (long) testPtr);
-
- OutputString(stringsID, kHndPtr14, 0L);
-
- if (onHandle) // are we testing Handles or Pointers?
- DisposHandle(testHnd); // this is okay, disposing the Handle here
- else
- {
- DisposPtr(testPtr); // this is okay, disposing the Ptr here
- }
-
- OutputString(stringsID, kHndPtr15, 0L);
-
- if (onHandle) // are we testing Handles or Pointers?
- SetHandleSize(testHnd, 256); //•-> BAD - the Handle is already disposed!
- else
- {
- // Important note!
- // A call to resize a disposed pointer can result in a out of memory error!
- // QC will detect this call, but because program execution continues, the
- // app may crash with a SysErr 25 in the SetPtrSize call.
-
- SetPtrSize(testPtr, 256); //•-> BAD - the Ptr is already disposed!
- }
- }
-
- DetectedMsgs();
- OutputString( stringsID, kHndPtr16, 0L);
-
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
-
- /*________________________________________________________________________________
-
- DoHandlePtrVerify()
-
- info: This routine performs a handle or pointer verification using
- the API calls QCVerifyHandle or QCVerifyPtr
-
- entry: onHandle - true if we are testing Handles, false if we are testing Pointers
-
- ________________________________________________________________________________*/
- void DoHandlePtrVerify(Boolean onHandle)
- {
- long value; // blocks with.
-
- if (onHandle)
- OutputString( kVerifyStringsID, kVerify2, 0L);
- else
- OutputString( kVerifyStringsID, kVerify1, 0L);
-
- QCGetTestState(qcDebugBreaks, &value); // are debug breaks turned on?
- if (!value)
- OutputString(kVerifyStringsID, kVerify11, 0L);
-
- if (QCIsActive())
- {
- QCStateHandle saveStateH;
- Handle testHnd = (Handle) 0x52FF8001; // Some bogus values: these are the
- Ptr testPtr = (Ptr) 0x52FF8001; // values QC invalidates free memory
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcValidateHandlePointers, true); // make sure validate handle/ptrs is on
- gQCDetectedErr = kQCNoErr;
-
- if (onHandle) // are we testing Handles or Pointers?
- {
- OutputString(kVerifyStringsID, kVerify5, 0L);
- if (QCVerifyHandle(testHnd))
- OutputString(kVerifyStringsID, kVerify9, 0L);
- else
- OutputString(kVerifyStringsID, kVerify8, 0L);
- }
- else
- {
- OutputString(kVerifyStringsID, kVerify4, 0L);
- if (QCVerifyPtr(testPtr))
- OutputString(kVerifyStringsID, kVerify7, 0L);
- else
- OutputString(kVerifyStringsID, kVerify6, 0L);
- }
-
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
- else
- OutputString(kVerifyStringsID, kVerify10, 0L);
-
- DetectedMsgs();
-
- OutputString( kVerifyStringsID, kVerify12, 0L);
- }
-
-
- /*________________________________________________________________________________
- WriteToZeroTest()
-
- info: This routine does the write to zero test by performing a common error
- in use of the Dialog Manager. This routine executes a GetDItem call
- by passing 0L in the VAR Handle parameter specified in Inside Mac I.
- The Dialog Manager writes the handle to the dialog item (in this case a
- button) in the expected VAR handle passed in. Because 0L was passed in,
- the Dialog Manager writes the button handle to address zero instead.
-
- ________________________________________________________________________________*/
- void WriteToZeroTest(void)
- {
- DialogPtr my_dialog;
- Point dlgOrigin;
-
- if (!gAtleastSys7) // if we are pre 7.0, we need to
- CenterDialog('DLOG', badDLOG, &dlgOrigin); // center it ourselves
-
- if ((my_dialog = GetNewDialog(badDLOG, 0, (WindowPtr)-1L))) // intentional assignment
- {
- QCStateHandle savedStateH;
- GrafPtr savePort;
- Rect boxT;
- short type, item_hit = 0;
-
- ShowWindow(my_dialog); // because we have it initially
- // inivisible in the DLOG tmpl
- GetPort( &savePort);
- SetPort(my_dialog);
-
- if (QCIsActive())
- {
- savedStateH = QCGetState(); // save the current state
- QCSetTestState(qcDetectWriteToZero, true); // ensure this is on
- }
-
- GetDItem(my_dialog, iOkay, &type, 0L, &boxT); //•-->BAD should pass &temp_H not 0L
- FrameDefault( &boxT);
-
- ModalDialog(0L, &item_hit);
-
- DisposDialog(my_dialog);
-
- if (savedStateH)
- {
- if (savedStateH)
- {
- QCSetState(savedStateH); // if successful, we don't dispose of it
- QCDisposeState(savedStateH);
- }
- }
-
- SetPort(savePort);
- }
- }
-
-
- /*________________________________________________________________________________
-
- DerefZeroTest()
-
- info: This routine performs the Dereferencing Zero Test. This test is performed
- by creating a purgeable handle, making sure it is purged through the
- use of QC’s purge memory option, then attempting to the use the
- purged handle.
-
- Note that this routine is almost identical to DoPurgeTest with the exception
- that we attempt to use the purged handle here.
-
- ________________________________________________________________________________*/
- void DerefZeroTest(void)
- {
- QCStateHandle saveStateH;
- dummyDataH testHandle1 = 0L;
- Handle testHandle2 = 0L;
- Ptr testPtr1 = 0L;
- Ptr testPtr; // this is what we use to cause the err
- long testLong; // this is what we use to cause the err
-
- saveStateH = QCGetState();
- QCSetTestState(qcPurgeHeap, true); // make sure this is turned on
- QCSetTestState(qcDerefZeroCheck, true); // make sure this is turned on
-
- OutputString( kZeroStringsID, kZero1, 0L); // report the first indicator string
-
- testHandle1 = (dummyDataH) NewHandle(1024); // lets create a handle
-
- if (testHandle1) // did we get the handle?
- {
- OutputString( kZeroStringsID, kZero3, (long) testHandle1); // show the handle address
-
- OutputString( kZeroStringsID, kZero4, 0L);
-
- if (QCIsActive())
- OutputString( kZeroStringsID, kZero5, 0L);
- else
- OutputString( kZeroStringsID, kZero6, 0L);
-
- HPurge((Handle) testHandle1); // mark him purgeable
- testHandle2 = NewHandle(1024); // and create another 1k handle
-
- if (!*testHandle1) // have we been purged?
- OutputString( kZeroStringsID, kZero7, 0L);
- else
- OutputString( kZeroStringsID, kZero8, 0L);
-
- if (testHandle1) // it is still a handle in memory even
- { // though its contents have been purged
- OutputString( kZeroStringsID, kZero9, 0L);
-
- if (QCIsActive()) // is QC active?
- OutputString( kZeroStringsID, kZero10, 0L);
- else
- OutputString( kZeroStringsID, kZero11, 0L);
-
- testPtr = (**testHandle1).theData; // •-> BAD the handle was purged!!
- // this is now invalid data from addr Zero.
- testLong = (long) *testPtr; // now we try to pull some data out of this
- // purged handle.
- DisposHandle((Handle) testHandle1);
- }
-
- if (testHandle2) // get rid of the trouble maker
- DisposHandle(testHandle2);
-
- }
- else
- OutputString( kZeroStringsID, kZero2, 0L);
-
- DetectedMsgs();
- OutputString( kZeroStringsID, kZero12, 0L);
-
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
-
-
- /*________________________________________________________________________________
-
- DoPurgeTest()
-
- info: This routine performs the purge memory test. The test involves reading
- in a given resource, marking it as purgeable, then causing memory to be
- purged by creating a big Handle, then trying to access the resource again.
-
- ________________________________________________________________________________*/
- void DoPurgeTest(void)
- {
- QCStateHandle saveStateH;
- Handle testHandle1 = 0L;
- Handle testHandle2 = 0L;
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcPurgeHeap, true); // make sure this is turned on
- QCSetTestState(qcScrambleHeap, true); // make sure this is turned on
- gQCDetectedErr = kQCNoErr;
-
- OutputString( kPurgeStringsID, kPurge1, 0L); // report the first indicator string
-
- testHandle1 = NewHandle(1024); // lets create a handle
-
- if (testHandle1) // did we get the handle?
- {
- OutputString( kPurgeStringsID, kPurge3, (long) testHandle1); // show the handle address
-
- OutputString( kPurgeStringsID, kPurge4, 0L);
-
- if (QCIsActive())
- OutputString( kPurgeStringsID, kPurge5, 0L);
- else
- OutputString( kPurgeStringsID, kPurge6, 0L);
-
- HPurge(testHandle1); // mark him purgeable
- testHandle2 = NewHandle(1024); // and create another 1k handle
-
- if (!*testHandle1) // have we been purged?
- OutputString( kPurgeStringsID, kPurge7, 0L);
- else
- OutputString( kPurgeStringsID, kPurge8, 0L);
-
- if (testHandle1) // it is still a handle in memory even
- DisposHandle(testHandle1); // though its contents have been purged
-
- if (testHandle2) // get rid of the trouble maker
- DisposHandle(testHandle2);
-
- }
- else
- OutputString( kPurgeStringsID, kPurge2, 0L);
-
- DetectedMsgs();
- OutputString( kPurgeStringsID, kPurge9, 0L);
-
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
-
-
- #define kArrayMax 9
- /*________________________________________________________________________________
-
- DoBlockOverwrite()
-
- info: This routine performs a block overwrite off data in a handle by
- creating a handle of longs and incorrectly looping one past the end
- of the array. Please notice that the error is detected on the next
- memory related call (the _DisposeHandle).
- ________________________________________________________________________________*/
- void DoBlockOverwrite(void)
- {
- QCStateHandle saveStateH;
- shortHandle testH;
- Handle spareH;
- short loop;
- Boolean active = QCIsActive();
-
- gQCDetectedErr = kQCNoErr;
-
- OutputString( kBkOverwriteStringsID, kOverwrite1, 0L); // report the first indicator string
-
- saveStateH = QCGetState(); // save the current testing state
- QCSetTestState(qcBlockBoundsChecking, true); // make sure block bounds is on
-
- if (!active)
- OutputString( kBkOverwriteStringsID, kPurge2, 0L);
-
- OutputString( kBkOverwriteStringsID, kOverwrite3, 0L);
-
- testH = (shortHandle)NewHandle(kArrayMax * sizeof(short));
- spareH = NewHandle(20); // lets try and be safe by putting
- // another handle beyond the first
- OutputString( kBkOverwriteStringsID, kOverwrite4, 0L);
- for (loop = 0; loop < kArrayMax+1; loop++)
- (*testH)[loop] = (loop + 25);
-
- if (active)
- OutputString( kBkOverwriteStringsID, kOverwrite5, 0L);
-
- DisposeHandle((Handle) spareH);
- DisposeHandle((Handle) testH);
-
- DetectedMsgs();
-
- OutputString( kBkOverwriteStringsID, kOverwrite8, 0L);
- if (saveStateH)
- {
- QCSetState(saveStateH); // if successful, we don't dispose of it
- QCDisposeState(saveStateH);
- }
- }
-
- /*________________________________________________________________________________
-
- DetectedMsgs()
-
- info: Display the appropriate error detection msg (Common to all tests)
-
- ________________________________________________________________________________*/
- void DetectedMsgs(void)
- {
- if (gQCDetectedErr)
- OutputString( kStringsID, kDetected, 0L); // the error was detected
- else
- OutputString( kStringsID, kDetectionOff, 0L); // nope, nothing was caught
- }
-
- #pragma mark -
-
- /*________________________________________________________________________________
- InstallHandler()
-
- info: Routine to install a QC error handler. This routine does the right thing
- for PowerPC or 68k code installing an error handler. In the case of PPC
- code, the UPP created is passed back and is to be given to RemoveHandler()
- when the error handler is to be removed.
- ________________________________________________________________________________*/
- QCCallBackUPP InstallHandler(void)
- {
- QCCallBackUPP procP;
-
- procP = NewQCCallBackProc(MyErrorHandler);
-
- QCInstallHandler( procP, SetCurrentA5());
-
- return (procP);
- }
-
- /*________________________________________________________________________________
- RemoveHandler()
-
- info: Routine to install a QC error handler. This routine does the right thing
- for PowerPC or 68k code installing an error handler. In the case of PPC
- code, the UPP created is passed back and is to be given to RemoveHandler()
- when the error handler is to be removed.
-
- NOTE: You're going to get an 'unused variable' warning on 'procP' if building
- for 68k. We could put something in to reference 'procP' for 68k builds
- but that'd just be added code. So please ignore the warning.
- ________________________________________________________________________________*/
- void RemoveHandler(QCCallBackUPP procP)
- {
- #pragma unused (procP)
-
- QCRemoveHandler(procP);
- #ifdef __powerc
- if (procP)
- DisposeRoutineDescriptor(procP);
- #endif
- }
-
- /*________________________________________________________________________________
- MyErrorHandler()
-
- info: Sample QC Error Handler called by QC when an error has been detected.
- ________________________________________________________________________________*/
- Boolean MyErrorHandler(QCPBPtr paramBlock)
- {
- long oldA5;
-
- oldA5 = SetA5( paramBlock->data);
-
- gQCDetectedErr = paramBlock->error;
-
- SetA5(oldA5);
-
- // If we return true here QC will assume we handled the error ourselves and it
- // will not report anything errors to the user itself (beep or debug break).
-
- return(false);
- }
-