|
|
/*
* V A L I D A T E . C * * Functions used to validate parameters on standard MAPI object methods. * * Used in conjunction with macros found in VALIDATE.H. * * Copyright 1992-93 Microsoft Corporation. All Rights Reserved. */
#include <_apipch.h>
/*
* FBadRgPropVal() * * Purpose: * Routine to attempt to validate all of the ptrs contained in an input * property value array, LPSPropVal */ /*
*BOOL *FBadPropVal( LPSPropValue lpPropVal) *{ * ULONG ulPropType; * BOOL fLongMVProp = FALSE; * ULONG cbItemType = 0; * ULONG cMVVals; * LPVOID FAR *lppvMVArray; * * switch (ulPropType = PROP_TYPE(lpPropVal->ulPropTag)) * { * case PT_STRING8: * * if (IsBadStringPtrA( lpPropVal->Value.lpszA, (UINT)-1 )) * { * return TRUE; * } * * break; * * *#ifdef WIN32 * case PT_UNICODE: * * if (IsBadStringPtrW( lpPropVal->Value.lpszW, (UINT)-1 )) * { * return TRUE; * } * break; *#endif * * * case PT_BINARY: * * if (IsBadReadPtr( lpPropVal->Value.bin.lpb * , (UINT) lpPropVal->Value.bin.cb)) * { * return TRUE; * } * * break; * * case PT_MV_I2: // 16 bit quantities
* * cbItemType = sizeof(lpPropVal->Value.i); * break; * * * case PT_MV_UNICODE: // Arrays of strings
* case PT_MV_STRING8: * * fLongMVProp = TRUE; * * // Now fall thru to the 32 bit quantity code below to size the
* // top level array of ptrs
* * * case PT_MV_LONG: // 32 bit quantities
* case PT_MV_R4: * * cbItemType = sizeof(long); * break; * * * case PT_MV_BINARY: // Arrays of counted binary data
* * fLongMVProp = TRUE; * * // Now fall thru to the 64 bit quantity code below to size the array
* // of ULONG lengths / ULONG ptrs that comprise the top level stream
* * * case PT_MV_DOUBLE: // 64 bit quantities
* case PT_MV_CURRENCY: * case PT_MV_APPTIME: * case PT_MV_SYSTIME: * case PT_MV_I8: * * // Assert that all array elements for this case are the same size.
* Assert( sizeof( double ) == sizeof( LARGE_INTEGER )); * cbItemType = sizeof( double ); * break; * * * case PT_MV_CLSID: // 128 bit quantity
* * cbItemType = sizeof( GUID ); * break; * * * case PT_OBJECT: * case PT_NULL: * default: * if (ulPropType & MV_FLAG) * { * return TRUE; // Unknown multivalue prop is bad
* } * * break; * } * * if (!(ulPropType & MV_FLAG)) * { * return FALSE; * } * * // Try to validate the multivalue props
* * // This code assumes that the count and ptr of every multivalue
* // property are in the same place.
* // Asserts check that the sizes of the grouped types above are
* // matched
* * cMVVals = lpPropVal->Value.MVl.cValues; * lppvMVArray = (LPVOID FAR *) (lpPropVal->Value.MVl.lpl); * * if (IsBadReadPtr( lppvMVArray, (UINT) (cMVVals * cbItemType))) * { * return TRUE; * } * * if (fLongMVProp) * { * // Go verify the array of pointers.
* for ( ; cMVVals; cMVVals--, lppvMVArray++) * { * switch (ulPropType) * { *#ifdef WIN32 * case PT_MV_UNICODE: * * if (IsBadStringPtrW( (LPCWSTR) (*lppvMVArray), (UINT) -1)) * { * return TRUE; * } * * break; *#endif * case PT_MV_STRING8: * * if (IsBadStringPtrA( (LPCSTR) (*lppvMVArray), (UINT) -1)) * { * return TRUE; * } * * break; * * case PT_MV_BINARY: * * if (IsBadReadPtr( ((SBinary FAR *)(*lppvMVArray))->lpb * , (UINT) * ((SBinary FAR *)(*lppvMVArray))->cb)) * { * return TRUE; * } * break; * } * } * } * * return FALSE; *} */
/*
* FBadRgPropVal() * * Purpose: * Routine to attempt to validate all of the ptrs contained in an input * property value array, LPSPropVal */ /*BOOL
*FBadRgPropVal( LPSPropValue lpPropVal, * ULONG cValues) *{ * * if (IsBadReadPtr( lpPropVal, sizeof(SPropValue) * (UINT) cValues)) * { * return TRUE; * } * * // Warning! Modifies the function parameters (NOT what they point to!).
* //
* for ( ; cValues ; cValues--, lpPropVal++) * { * if (FBadPropVal( lpPropVal)) * { * return TRUE; * } * } * * return FALSE; *} */
/*
* FBadRglpszA() * * Purpose: * Routine to attempt to validate all of the ptrs contained in an input * array of string8 pointers, LPSTR FAR *. */ STDAPI_(BOOL) FBadRglpszA( LPSTR FAR *lppszA, ULONG cStrings) { if (IsBadReadPtr( lppszA, (UINT) (cStrings * sizeof(LPSTR FAR *)))) { return TRUE; }
/* Check for readability of each string in the array.
* * WARNING! * Function pointers and counts are modified (NOT what they point to). */ for (; cStrings; cStrings--, lppszA++) { if (IsBadStringPtrA( *lppszA, (UINT)-1 )) { return TRUE; } }
return FALSE; }
/*
* FBadRglpszW() * * Purpose: * Routine to attempt to validate all of the ptrs contained in an input * array of UNICODE string pointers, LPSTR FAR *. */ STDAPI_(BOOL) FBadRglpszW( LPWSTR FAR *lppszW, ULONG cStrings) { if (IsBadReadPtr( lppszW, (UINT) (cStrings * sizeof(LPWSTR FAR *)))) { return TRUE; }
// Check for readability of each string in the array.
//
// WARNING!
// Function pointers and counts are modified (NOT what they point to).
//
for (; cStrings; cStrings--, lppszW++) { #ifdef MAC
if (IsBadStringPtr( *lppszW, (UINT)-1 )) #else
if (IsBadStringPtrW( *lppszW, (UINT)-1 )) #endif
{ return TRUE; } }
return FALSE; }
/*
* FBadRowSet() * * Purpose: * Routine to validate all rows of properties in a row set. * * NOTE! A NULL row pointer is assumed to be a VALID entry in a row set. * A NULL row set pointer is assumed to be INVALID. */ STDAPI_(BOOL) FBadRowSet( LPSRowSet lpRowSet) { LPSRow lpRow; ULONG cRows;
if (IsBadReadPtr( lpRowSet, CbNewSRowSet(0))) return TRUE; if (IsBadWritePtr( lpRowSet, CbSRowSet(lpRowSet))) return TRUE;
// Short cut
if (!lpRowSet->cRows) return FALSE;
// Check each row in the set.
// cValues == 0 is valid if and only if lpProps == NULL
//
for ( lpRow = lpRowSet->aRow, cRows = lpRowSet->cRows ; cRows ; lpRow++, cRows--) { if ( IsBadReadPtr( lpRow, sizeof(*lpRow)) #ifndef _WIN64
|| FBadRgPropVal( lpRow->lpProps, (int) (lpRow->cValues)) #endif // _WIN64
) { return TRUE; } }
return FALSE; }
/*
* FBadRglpNameID() * * Purpose: * Routine to attempt to validate all of the ptrs contained in an input * array of MAPINAMEID pointers, LPMAPINAMEID FAR *. */ STDAPI_(BOOL) FBadRglpNameID( LPMAPINAMEID FAR * lppNameId, ULONG cNames) { if (IsBadReadPtr( lppNameId, (UINT) (cNames * sizeof(LPMAPINAMEID FAR *)))) { return TRUE; }
// Check for readability of each string in the array.
//
for (; cNames; cNames--, lppNameId++) { LPMAPINAMEID lpName = *lppNameId;
if (IsBadReadPtr(lpName, sizeof(MAPINAMEID))) { return TRUE; }
if (IsBadReadPtr(lpName->lpguid, sizeof(GUID))) { return TRUE; }
if (lpName->ulKind != MNID_ID && lpName->ulKind != MNID_STRING) { return TRUE; }
if (lpName->ulKind == MNID_STRING) { if (IsBadStringPtrW( lpName->Kind.lpwstrName, (UINT)-1 )) { return TRUE; } }
} return FALSE; }
/* FBadEntryList moved to src\lo\msvalid. */
/*============================================================================
* The following functions are used to determine the validity of various * table-related structures. These functions should most definitely * be moved to proputil when it becomes a lib (or DLL). */
/*============================================================================
- FBadPropTag() - * Returns TRUE if the specified prop tag isn't one of the known * MAPI property types, FALSE otherwise. * * * Parameter: * ulPropTag in Proptag to validate. */
STDAPI_(ULONG) FBadPropTag( ULONG ulPropTag ) { // Just check the type
switch ( PROP_TYPE(ulPropTag) & ~MV_FLAG ) { default: return TRUE;
case PT_UNSPECIFIED: case PT_NULL: case PT_I2: case PT_LONG: case PT_R4: case PT_DOUBLE: case PT_CURRENCY: case PT_APPTIME: case PT_ERROR: case PT_BOOLEAN: case PT_OBJECT: case PT_I8: case PT_STRING8: case PT_UNICODE: case PT_SYSTIME: case PT_CLSID: case PT_BINARY: return FALSE; } }
/*============================================================================
- FBadRow() - * Returns TRUE if the specified row contains invalid (PT_ERROR or * PT_NULL) columns or if any of those columns are invalid. * * * Parameter: * lprow in Row to validate. */
STDAPI_(ULONG) FBadRow( LPSRow lprow ) { LPSPropValue lpprop; LPSPropValue lppropT;
if ( IsBadReadPtr(lprow, sizeof(SRow)) || IsBadReadPtr(lprow->lpProps, (size_t)(lprow->cValues * sizeof(SPropValue))) ) return TRUE;
lpprop = lprow->lpProps + lprow->cValues; while ( lpprop-- > lprow->lpProps ) { if ( FBadProp(lpprop) ) return TRUE;
lppropT = lpprop; while ( lppropT-- > lprow->lpProps ) if ( lppropT->ulPropTag == lpprop->ulPropTag && PROP_TYPE(lppropT->ulPropTag) != PT_ERROR && PROP_TYPE(lppropT->ulPropTag) != PT_NULL ) { DebugTrace( TEXT("FBadRow() - Row has multiple columns with same proptag!\n") ); return TRUE; } }
return FALSE; }
/*============================================================================
- FBadProp() - * Returns TRUE if the specified property is invalid. * * * Parameters: * lpprop in Property to validate. */
STDAPI_(ULONG) FBadProp( LPSPropValue lpprop ) { ULONG ulcb; LPVOID lpv;
if ( IsBadReadPtr(lpprop, sizeof(SPropValue)) || FBadPropTag(lpprop->ulPropTag) ) return TRUE;
switch ( PROP_TYPE(lpprop->ulPropTag) ) { default: return FALSE;
case PT_BINARY: ulcb = lpprop->Value.bin.cb; lpv = lpprop->Value.bin.lpb; break;
case PT_STRING8: ulcb = sizeof(CHAR); lpv = lpprop->Value.lpszA; break;
#ifndef WIN16
case PT_UNICODE: ulcb = sizeof(WCHAR); lpv = lpprop->Value.lpszW; break; #endif
case PT_CLSID: ulcb = sizeof(GUID); lpv = lpprop->Value.lpguid; break;
case PT_MV_I2: case PT_MV_LONG: case PT_MV_R4: case PT_MV_DOUBLE: case PT_MV_CURRENCY: case PT_MV_I8: ulcb = UlPropSize(lpprop); lpv = lpprop->Value.MVi.lpi; break;
case PT_MV_BINARY: { LPSBinary lpbin; if ( IsBadReadPtr(lpprop->Value.MVbin.lpbin, (size_t)(lpprop->Value.MVbin.cValues * sizeof(SBinary))) ) return TRUE;
lpbin = lpprop->Value.MVbin.lpbin + lpprop->Value.MVbin.cValues; while ( lpprop->Value.MVbin.lpbin < lpbin-- ) if ( IsBadReadPtr(lpbin->lpb, (size_t)(lpbin->cb) )) return TRUE;
return FALSE; }
case PT_MV_STRING8: { LPCSTR FAR * lppsz; if ( IsBadReadPtr(lpprop->Value.MVszA.lppszA, (size_t)(lpprop->Value.MVszA.cValues * sizeof(LPSTR))) ) return TRUE;
lppsz = lpprop->Value.MVszA.lppszA + lpprop->Value.MVszA.cValues; while ( lpprop->Value.MVszA.lppszA < lppsz-- ) // Need to break the code up this way for the Mac version
if ( IsBadReadPtr(*lppsz, sizeof(CHAR))) return TRUE; return FALSE; }
case PT_MV_UNICODE: { UNALIGNED LPWSTR FAR * lppsz; if ( IsBadReadPtr(lpprop->Value.MVszW.lppszW, (size_t)(lpprop->Value.MVszW.cValues * sizeof(LPWSTR))) ) return TRUE;
lppsz = lpprop->Value.MVszW.lppszW + lpprop->Value.MVszW.cValues; while ( lpprop->Value.MVszW.lppszW < lppsz-- ) if ( IsBadReadPtr(*lppsz, sizeof(WCHAR))) return TRUE; return FALSE; } }
return IsBadReadPtr(lpv, (size_t) ulcb); }
/* FBadSortOrderSet moved to src\lo\MSVALID.C */
/*============================================================================
- FBadColumnSet() - * Returns TRUE if the specified column set is invalid. For use * with IMAPITable::SetColumns(), this function treats PT_ERROR columns * as invalid and PT_NULL columns as valid. * * * Parameter: * lpptaCols in Column set to validate. */
STDAPI_(ULONG) FBadColumnSet( LPSPropTagArray lpptaCols ) { UNALIGNED ULONG FAR * pulPropTag; if ( IsBadReadPtr(lpptaCols,CbNewSPropTagArray(0)) || IsBadReadPtr(lpptaCols,CbSPropTagArray(lpptaCols))) { DebugTrace( TEXT("FBadColumnSet() - Bad column set structure\n") ); return TRUE; }
// maximum number of proptags we can calculate size for. raid 4460
if ( lpptaCols->cValues > ((INT_MAX - offsetof( SPropTagArray, aulPropTag )) / sizeof( ULONG ))) { DebugTrace( TEXT("FBadColumnSet(): Exceeded maximum number of tags\n") ); return TRUE; }
pulPropTag = lpptaCols->aulPropTag + lpptaCols->cValues; while ( pulPropTag-- > lpptaCols->aulPropTag ) { // DCR 978: Disallow PT_ERROR columns.
// DCR 715: Ignore PT_NULL columns and only allow columns
// from initial column set.
if ( PROP_TYPE(*pulPropTag) != PT_NULL && (PROP_TYPE(*pulPropTag) == PT_ERROR || FBadPropTag(*pulPropTag)) ) { DebugTrace( TEXT("FBadColumnSet() - Bad column 0x%08lX\n"), *pulPropTag ); return TRUE; } }
return FALSE; }
|