You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
557 lines
18 KiB
557 lines
18 KiB
#include "stdafx.h"
|
|
#include "sxsplugMap.h"
|
|
|
|
#define PRAGMA_UNSAFE_DELIMITER_DEFAULT ' '
|
|
#define PRAGMA_UNSAFE_DELIMITER_BETWEEN_STATEMENT ';'
|
|
#define PRAGMA_UNSAFE_DELIMITER_BETWEEN_VALUESTR ','
|
|
#define PRAGMA_UNSAFE_DELIMITER_BETWEEN_KEYWORD_AND_VALUESTR ':'
|
|
|
|
#define PRAGMA_UNSAFE_KEYWORD_UNSAFE "unsafe"
|
|
#define PRAGMA_UNSAFE_KEYWORD_UNSAFE_PUSH "push"
|
|
#define PRAGMA_UNSAFE_KEYWORD_UNSAFE_DISABLE "disable"
|
|
#define PRAGMA_UNSAFE_KEYWORD_UNSAFE_ENABLE "enable"
|
|
#define PRAGMA_UNSAFE_KEYWORD_UNSAFE_POP "pop"
|
|
|
|
#define PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_ENABLE 0
|
|
#define PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_DISABLE 1
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::ReInitialize()
|
|
{
|
|
m_UnsafeFuncs.clear(); // void function
|
|
m_fInitialized = FALSE;
|
|
|
|
return this->Initialize();
|
|
}
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::Initialize()
|
|
{
|
|
ASSERT(m_fInitialized == FALSE);
|
|
m_index = 0;
|
|
BOOL fSuccess = AddFunctionIntoStack(POINTER_ARITHMATIC_FUNC);
|
|
if (fSuccess)
|
|
m_fInitialized = TRUE;
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::IsFunctionNotUnsafe(const char * strFuncName)
|
|
{
|
|
BOOL fSafe = TRUE; // defaultly all function are SAFE
|
|
PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::iterator pIter;
|
|
|
|
if (true == m_UnsafeFuncs.empty())
|
|
return TRUE;
|
|
|
|
DWORD CurrentIndex = m_index - 1;
|
|
for (pIter = m_UnsafeFuncs.begin(); pIter != m_UnsafeFuncs.end(); pIter ++)
|
|
{
|
|
if (pIter->first.compare(strFuncName) == 0)
|
|
{
|
|
PragmaUnsafe_FUNCTION_STATUS & FuncStatusRecord = pIter->second;
|
|
//
|
|
// get current status : enabled or not
|
|
//
|
|
BYTE x = (FuncStatusRecord[CurrentIndex / sizeof(BYTE)] & (1 << (CurrentIndex % sizeof(BYTE)))) >> (CurrentIndex % sizeof(BYTE));
|
|
// duplicate last status
|
|
if (x == 0){
|
|
fSafe = FALSE;
|
|
}
|
|
break; // find a result already
|
|
}
|
|
}
|
|
|
|
return fSafe;
|
|
}
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::OnUnsafeDisable(const char * strFuncNameGroups)
|
|
{
|
|
if (FALSE == IsInitialized())
|
|
{
|
|
PragmaUnsafe_ReportError("Not Initialized !!!\n");
|
|
return FALSE;
|
|
}
|
|
if (IsStackFull())
|
|
{
|
|
PragmaUnsafe_ReportError("Stack is Full Sized now!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
return ResetStack(strFuncNameGroups, false);
|
|
}
|
|
|
|
VOID CPragmaUnsafe_UnsafeFunctionStateStack::PackStack()
|
|
{
|
|
if ( m_index == 0)
|
|
return;
|
|
|
|
BYTE AllEnabledStatus[8];
|
|
for ( DWORD i = 0; i < (m_index - 1) / sizeof(BYTE); i++)
|
|
AllEnabledStatus[i] = 0xFF;
|
|
AllEnabledStatus[(m_index - 1) / sizeof(BYTE)] = ((1 << (((m_index - 1)% sizeof(BYTE)) + 1)) - 1) & 0xFF;
|
|
|
|
//
|
|
// if from 0..m_index - 1, all state is enabled: just delete this function from the map
|
|
//
|
|
for (PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::iterator pIter = m_UnsafeFuncs.begin(); pIter != m_UnsafeFuncs.end(); pIter ++)
|
|
{
|
|
if (memcmp((PVOID)(&pIter->second[0]), AllEnabledStatus, PragmaUnsafe_STACK_SIZE_IN_BYTE) == 0)
|
|
m_UnsafeFuncs.erase(pIter->first);
|
|
}
|
|
|
|
//
|
|
// no func in the stack, clean the map and reset m_index == 0;
|
|
//
|
|
if (m_UnsafeFuncs.empty())
|
|
{
|
|
m_UnsafeFuncs.clear();
|
|
m_index = 0;
|
|
}
|
|
}
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::OnUnsafePop()
|
|
{
|
|
if (FALSE == IsInitialized())
|
|
{
|
|
PragmaUnsafe_ReportError("Not Initialized !!!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
ASSERT(m_index > 0);
|
|
|
|
if (IsStackEmpty())
|
|
{
|
|
PragmaUnsafe_ReportError("Stack is current empty!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
m_index--;
|
|
if (m_index == 0)
|
|
{
|
|
m_UnsafeFuncs.clear(); // delete the map
|
|
}
|
|
|
|
PackStack(); // void function
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::OnUnsafePush()
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::iterator pIter, qIter;
|
|
string strFuncName;
|
|
DWORD CurrentIndex;
|
|
if (FALSE == IsInitialized())
|
|
{
|
|
PragmaUnsafe_ReportError("Not Initialized !!!\n");
|
|
goto Exit;
|
|
}
|
|
|
|
if (IsStackFull())
|
|
{
|
|
PragmaUnsafe_ReportError("Stack is Full Sized now!\n");
|
|
goto Exit;
|
|
}
|
|
|
|
CurrentIndex = (m_index - 1);
|
|
ASSERT(CurrentIndex >= 0); //because we have check that the stack is not empty
|
|
|
|
for (pIter = m_UnsafeFuncs.begin(); pIter != m_UnsafeFuncs.end(); pIter ++)
|
|
{
|
|
PragmaUnsafe_FUNCTION_STATUS & FuncStatusRecord = pIter->second; // ref is return...
|
|
|
|
//
|
|
// get current status of each function
|
|
//
|
|
|
|
BYTE x = (FuncStatusRecord[CurrentIndex / sizeof(BYTE)] & (1 << (CurrentIndex % sizeof(BYTE)))) >> (CurrentIndex % sizeof(BYTE));
|
|
ASSERT((x == 0) || (x == 1));
|
|
|
|
// duplicate last status
|
|
if ( x == 1)
|
|
FuncStatusRecord[m_index / sizeof(BYTE)] |= ((1 << (m_index % sizeof(BYTE))) & 0x00ff);
|
|
else
|
|
FuncStatusRecord[m_index / sizeof(BYTE)] &= (~((1 << (m_index % sizeof(BYTE))) & 0x00ff) & 0x00ff);
|
|
}
|
|
|
|
m_index ++;
|
|
fSuccess = TRUE;
|
|
|
|
Exit:
|
|
return fSuccess;
|
|
}
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::OnUnsafeEnable(const char * strFuncNameGroups)
|
|
{
|
|
if (FALSE == IsInitialized())
|
|
{
|
|
PragmaUnsafe_ReportError("Not Initialized !!!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (IsStackEmpty())
|
|
{
|
|
PragmaUnsafe_ReportError("Stack is Empty now!\n");
|
|
return TRUE;
|
|
}
|
|
|
|
return ResetStack(strFuncNameGroups, true);
|
|
}
|
|
|
|
// if a function is already in the stack, change current status
|
|
// if a function is not in the stack:
|
|
// if you try to disable it : add it to the stack and would disfunction after pop is done
|
|
// if you try to enable it : we cannot igore it in case that it go with a push and later a pop, so
|
|
// just add it to the stack and would disfunction after pop is done
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::ResetStack(const char * strFuncNameGroups, bool fEnable)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::iterator pIter, qIter;
|
|
string strFuncName;
|
|
istrstream streamFuncNameStream(strFuncNameGroups);
|
|
DWORD CurIndex;
|
|
|
|
//
|
|
// suppose that the func names are delimited using ;
|
|
// for each function which reset status
|
|
//
|
|
for (; getline(streamFuncNameStream, strFuncName, PRAGMA_UNSAFE_DELIMITER_BETWEEN_VALUESTR); )
|
|
{
|
|
if (strFuncName.empty())
|
|
break;
|
|
|
|
qIter = m_UnsafeFuncs.find(strFuncName);
|
|
//
|
|
// this function is not on map currently,
|
|
//
|
|
if (qIter == m_UnsafeFuncs.end())
|
|
{
|
|
//
|
|
// adding into the stack as a disabled function, see the comments at the function declaration
|
|
//
|
|
if ( FALSE == AddFunctionIntoStack(strFuncName.c_str(), fEnable))
|
|
{
|
|
PragmaUnsafe_ReportError("AddFunctionIntoStack for %s failed\n", strFuncName.c_str());
|
|
}
|
|
continue;
|
|
}
|
|
ASSERT(m_index > 0);
|
|
CurIndex = m_index - 1;
|
|
|
|
PragmaUnsafe_FUNCTION_STATUS & FuncStatusRecord = qIter->second;
|
|
|
|
// overwrite the current status
|
|
if (fEnable == true)
|
|
FuncStatusRecord[CurIndex / sizeof(BYTE)] |= ((1 << (CurIndex % sizeof(BYTE))) & 0xff);
|
|
else
|
|
FuncStatusRecord[CurIndex / sizeof(BYTE)] &= (~((1 << (CurIndex % sizeof(BYTE))) & 0xff) & 0xff);
|
|
}
|
|
|
|
fSuccess = TRUE;
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
void TrimString(string & strFuncName, DWORD dwFlag = STRING_TRIM_FLAG_LEFT | STRING_TRIM_FLAG_RIGHT)
|
|
{
|
|
int i;
|
|
|
|
if (dwFlag & STRING_TRIM_FLAG_LEFT)
|
|
{
|
|
// left trim
|
|
i = 0;
|
|
while ((strFuncName[i] == ' ') && (i < strFuncName.length())) i++;
|
|
if ( i > 0)
|
|
strFuncName.erase(0,i);
|
|
}
|
|
|
|
if (dwFlag & STRING_TRIM_FLAG_RIGHT)
|
|
{
|
|
// right trim
|
|
i = strFuncName.length() - 1;
|
|
while ((strFuncName[i] == ' ') && (i >= 0 )) i--;
|
|
if ( i != strFuncName.length() - 1)
|
|
strFuncName.erase(i, (strFuncName.length() - i));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// when this function is called, this func must not in the current stack
|
|
//
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::AddFunctionIntoStack(const char * strFuncNameGroups, bool fEnabled)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
|
|
string strFuncName;
|
|
istrstream streamFuncNameStream(strFuncNameGroups);
|
|
PragmaUnsafe_FUNCTION_STATUS new_func_status;
|
|
DWORD CurrentIndex;
|
|
|
|
if (m_index == 0)
|
|
m_index ++;
|
|
|
|
//
|
|
// suppose that the func names are delimited using ;
|
|
//
|
|
CurrentIndex = m_index -1 ;
|
|
|
|
for (; getline(streamFuncNameStream, strFuncName, PRAGMA_UNSAFE_DELIMITER_BETWEEN_VALUESTR); )
|
|
{
|
|
if (strFuncName.empty())
|
|
break;
|
|
|
|
TrimString(strFuncName); // left-trim and right-trim
|
|
|
|
if (strFuncName.empty())
|
|
break;
|
|
|
|
if (m_UnsafeFuncs.find(strFuncName) != m_UnsafeFuncs.end())
|
|
{
|
|
//
|
|
// If the function has already in the map, we just ignore it.
|
|
// This would deal with a header file with "#pragam unsafe(disable: func1)" is included multiple times.
|
|
// that is, if the sequence is
|
|
// #pragam unsafe(disable: func1)
|
|
// #pragam unsafe(push, enable:func1)
|
|
// #pragam unsafe(disable:func1) ---> would be ignored, and func1 is still enabled at this moment
|
|
// #pragam unsafe(pop)
|
|
//
|
|
// in this case, a warning message would be issued
|
|
|
|
//PragmaUnsafe_ReportWarning(PragmaUnsafe_PLUGIN_WARNING_MSG_PREFIX, "%s has already been disabled\n", strFuncName);
|
|
PragmaUnsafe_ReportError("%s has already been disabled\n", strFuncName.c_str());
|
|
continue;
|
|
}
|
|
|
|
ZeroMemory(&new_func_status, sizeof(new_func_status)); // grow to the same size as all other functions
|
|
|
|
|
|
// set to be "1" for the range of 0..CurrentIndex-1
|
|
if (CurrentIndex > sizeof(BYTE) + 1)
|
|
{
|
|
for (int i = 0 ; i < ((CurrentIndex - 1) / sizeof(BYTE)); i++)
|
|
new_func_status[i] = 0xFF;
|
|
}
|
|
|
|
if (fEnabled == true)
|
|
{
|
|
new_func_status[CurrentIndex / sizeof(BYTE)] = ((1 << ((CurrentIndex % sizeof(BYTE)) + 1)) - 1) & 0xFF;
|
|
}
|
|
else
|
|
{
|
|
new_func_status[CurrentIndex / sizeof(BYTE)] = ((1 << (CurrentIndex % sizeof(BYTE))) - 1) & 0xFF;
|
|
}
|
|
|
|
m_UnsafeFuncs.insert(PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::value_type(strFuncName, new_func_status));
|
|
}
|
|
|
|
fSuccess = TRUE;
|
|
//Exit:
|
|
return fSuccess;
|
|
}
|
|
VOID CPragmaUnsafe_UnsafeFunctionStateStack::PrintFunctionCurrentStatus(int level)
|
|
{
|
|
PragmaUnsafe_PRAGMA_UNSAFE_FUNCTIONS::iterator pIter, qIter;
|
|
cout << endl << endl << "CurrentStack:" << endl;
|
|
cout << "m_index = " << m_index << endl;
|
|
|
|
//
|
|
// for each current item in map, push to preserve its current status
|
|
//
|
|
if (m_index == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DWORD CurrentIndex = (m_index - 1);
|
|
BYTE x;
|
|
for (pIter = m_UnsafeFuncs.begin(); pIter != m_UnsafeFuncs.end(); pIter ++)
|
|
{
|
|
PragmaUnsafe_FUNCTION_STATUS & FuncStatusRecord = pIter->second; // ref is return...
|
|
|
|
//
|
|
// get current status of each function
|
|
//
|
|
|
|
x = (FuncStatusRecord[CurrentIndex / sizeof(BYTE)] & (1 << (CurrentIndex % sizeof(BYTE)))) >> (CurrentIndex % sizeof(BYTE));
|
|
for ( int j = 0 ; j < level; j++)
|
|
cout << " ";
|
|
cout << pIter->first << ":"<< ((x == 0) ? "Disabled" : "Enabled") << endl;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// this function is only called when the end of file is reached
|
|
//
|
|
BOOL CPragmaUnsafe_UnsafeFunctionStateStack::CheckIntegrityAtEndOfFile()
|
|
{
|
|
if (m_index == 1) // should always be 1 since pointer_arithmatic is default
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
at each file beginning: reset the pragma stack because of its file-range
|
|
*/
|
|
BOOL PragmaUnsafe_OnFileStart()
|
|
{
|
|
//
|
|
// initalize the map structure everytime when prefast start to parse
|
|
//
|
|
return Sxs_PragmaUnsafedFunctions.ReInitialize();
|
|
}
|
|
|
|
/*
|
|
at each file end: verify integrity of the stake
|
|
*/
|
|
BOOL PragmaUnsafe_OnFileEnd()
|
|
{
|
|
//Sxs_PragmaUnsafedFunctions.PrintFunctionCurrentStatus(0);
|
|
return Sxs_PragmaUnsafedFunctions.CheckIntegrityAtEndOfFile();
|
|
}
|
|
|
|
VOID PragmaUnsafe_GetUsafeOperParameters(DWORD dwFlag, const string & strPragmaUnsafeSingleStatement, string & strFuncNameList)
|
|
{
|
|
// initialize
|
|
strFuncNameList.erase();
|
|
|
|
int iPrefix = 0;
|
|
if ( dwFlag == PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_ENABLE)
|
|
iPrefix = strlen(PRAGMA_UNSAFE_KEYWORD_UNSAFE_ENABLE);
|
|
else if ( dwFlag == PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_DISABLE)
|
|
iPrefix = strlen(PRAGMA_UNSAFE_KEYWORD_UNSAFE_DISABLE);
|
|
|
|
if (iPrefix == 0) // error case
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
strFuncNameList.assign(strPragmaUnsafeSingleStatement);
|
|
strFuncNameList.erase(0, iPrefix);
|
|
|
|
TrimString(strFuncNameList);
|
|
// should be in the format of [enable|disbale]: func1, func2, func3
|
|
if (strFuncNameList[0] != PRAGMA_UNSAFE_DELIMITER_BETWEEN_KEYWORD_AND_VALUESTR)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
strFuncNameList.erase(0, 1); // get rid :
|
|
TrimString(strFuncNameList);
|
|
goto Exit;
|
|
|
|
ErrorExit:
|
|
if (!strFuncNameList.empty())
|
|
strFuncNameList.erase();
|
|
Exit:
|
|
return;
|
|
}
|
|
|
|
BOOL PragmaUnsafe_OnPragma(char * str, PRAGMA_STATEMENT & ePragmaUnsafe)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
istrstream streamParagmaString(str);
|
|
string strPragmaUnsafeSingleStatement;
|
|
string strFuncNameList;
|
|
|
|
ePragmaUnsafe = PRAGMA_NOT_UNSAFE_STATEMENT;
|
|
|
|
//
|
|
// check whether it begins with "unsafe", that is, its prefix is "unsafe:"
|
|
// get the first string which is sperate from the left using ' '
|
|
//
|
|
getline(streamParagmaString, strPragmaUnsafeSingleStatement, ':');
|
|
TrimString(strPragmaUnsafeSingleStatement); // void func
|
|
if (true == strPragmaUnsafeSingleStatement.empty())
|
|
{
|
|
ePragmaUnsafe = PRAGMA_NOT_UNSAFE_STATEMENT;
|
|
fSuccess = TRUE;
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// pragam unsafe keyword comparsion is case-sensitive
|
|
//
|
|
if (strncmp(strPragmaUnsafeSingleStatement.c_str(), PRAGMA_UNSAFE_KEYWORD_UNSAFE, strlen(PRAGMA_UNSAFE_KEYWORD_UNSAFE)) != 0)
|
|
{
|
|
// not start with Keyword "unsafe"
|
|
ePragmaUnsafe = PRAGMA_NOT_UNSAFE_STATEMENT;
|
|
fSuccess = TRUE;
|
|
goto Exit;
|
|
}
|
|
|
|
// so far, the statement is valid
|
|
ePragmaUnsafe = PRAGMA_UNSAFE_STATEMENT_VALID;
|
|
|
|
for (; getline(streamParagmaString, strPragmaUnsafeSingleStatement, PRAGMA_UNSAFE_DELIMITER_BETWEEN_STATEMENT); )
|
|
{
|
|
//
|
|
// to get a statement begin with "push", or "enable", or "disable", or "pop",
|
|
// we deal with push/pop first because they are non-parameter statements
|
|
//
|
|
TrimString(strPragmaUnsafeSingleStatement);
|
|
if (strPragmaUnsafeSingleStatement.compare(PRAGMA_UNSAFE_KEYWORD_UNSAFE_PUSH) == 0)
|
|
{
|
|
Sxs_PragmaUnsafedFunctions.OnUnsafePush();
|
|
}
|
|
else
|
|
if (strPragmaUnsafeSingleStatement.compare(PRAGMA_UNSAFE_KEYWORD_UNSAFE_POP) == 0)
|
|
{
|
|
Sxs_PragmaUnsafedFunctions.OnUnsafePop();
|
|
}
|
|
else
|
|
if (strncmp(strPragmaUnsafeSingleStatement.c_str(), PRAGMA_UNSAFE_KEYWORD_UNSAFE_ENABLE, strlen(PRAGMA_UNSAFE_KEYWORD_UNSAFE_ENABLE)) == 0)
|
|
{
|
|
PragmaUnsafe_GetUsafeOperParameters(PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_ENABLE, strPragmaUnsafeSingleStatement, strFuncNameList);
|
|
if (strFuncNameList.empty())
|
|
{
|
|
PragmaUnsafe_ReportError("Invalid string for pragma unsafe: %s\n", strPragmaUnsafeSingleStatement.c_str());
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
Sxs_PragmaUnsafedFunctions.OnUnsafeEnable(strFuncNameList.c_str());
|
|
}
|
|
}
|
|
else
|
|
if (strncmp(strPragmaUnsafeSingleStatement.c_str(), PRAGMA_UNSAFE_KEYWORD_UNSAFE_DISABLE, strlen(PRAGMA_UNSAFE_KEYWORD_UNSAFE_DISABLE)) == 0)
|
|
{
|
|
PragmaUnsafe_GetUsafeOperParameters(PRAGMA_UNSAFE_GETUSAFEOPERPARAMETERS_DWFLAG_UNSAFE_DISABLE, strPragmaUnsafeSingleStatement, strFuncNameList);
|
|
if (strFuncNameList.empty())
|
|
{
|
|
PragmaUnsafe_ReportError("Invalid string for pragma unsafe: %s\n", strPragmaUnsafeSingleStatement.c_str());
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
Sxs_PragmaUnsafedFunctions.OnUnsafeDisable(strFuncNameList.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// invalid string in pragma beginning with "unsafe"
|
|
ePragmaUnsafe = PRAGMA_UNSAFE_STATEMENT_INVALID;
|
|
PragmaUnsafe_ReportError("Invalid string for pragma unsafe: %s\n", strPragmaUnsafeSingleStatement.c_str());
|
|
goto Exit;
|
|
}
|
|
}
|
|
//Sxs_PragmaUnsafedFunctions.PrintFunctionCurrentStatus(0);
|
|
fSuccess = TRUE;
|
|
Exit:
|
|
return fSuccess;
|
|
}
|
|
|
|
BOOL PragmaUnsafe_IsPointerArithmaticEnabled()
|
|
{
|
|
return Sxs_PragmaUnsafedFunctions.IsFunctionNotUnsafe(POINTER_ARITHMATIC_FUNC);
|
|
}
|
|
|
|
int ReportInternalError(int nLine)
|
|
{
|
|
_tprintf(TEXT("%hs(%d) : Internal Error Occurred\n"),
|
|
__FILE__, nLine);
|
|
|
|
return 0;
|
|
}
|