📄 fortify.c
字号:
*/
void *FORTIFY_STORAGE
Fortify_malloc(size_t size, const char *file, DWORD line)
{
return Fortify_Allocate(size, Fortify_Allocator_malloc, file, line);
}
/*
* Fortify_realloc - Fortify's replacement realloc()
*/
void *
Fortify_realloc(void *uptr, size_t new_size, const char *file, DWORD line)
{
BYTE *ptr = (BYTE *)uptr - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;
struct Header *h = (struct Header *)ptr;
void *new_ptr;
/*
* If Fortify is disabled, we gotta do this a little
* differently.
*/
if (!st_Disabled)
{
if (!uptr)
return (Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line));
if (!st_IsOnAllocatedList(h))
{
#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
if (st_IsOnDeallocatedList(h))
{
sprintf(st_Buffer, "\nFortify: Deallocated memory block passed to \"%s\" at %s.%lu\n",
st_AllocatorName[Fortify_Allocator_realloc], file, line);
st_Output(st_Buffer);
sprintf(st_Buffer, " Memory block %s was deallocated by \"%s\" at %s.%lu\n",
st_MemoryBlockString(h),
st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
st_Output(st_Buffer);
return 0;
}
#endif
sprintf (st_Buffer, "\nFortify: Invalid pointer (%08lX) passed to realloc at %s.%lu\n",
(DWORD)ptr, file, line);
st_Output(st_Buffer);
return 0;
}
if (!st_CheckBlock(h, file, line))
return 0;
new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line);
if (!new_ptr)
{
return (0);
}
if (h->Size < new_size)
memcpy(new_ptr, uptr, h->Size);
else
memcpy(new_ptr, uptr, new_size);
Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line);
return (new_ptr);
}
else
{
/*
* If the old block was fortified, we can't use normal realloc.
*/
if (st_IsOnAllocatedList(h))
{
new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line);
if (!new_ptr)
return (0);
if (h->Size < new_size)
memcpy(new_ptr, uptr, h->Size);
else
memcpy(new_ptr, uptr, new_size);
Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line);
return (new_ptr);
}
else /* easy */
{
return realloc(uptr, new_size);
}
}
}
/*
* Fortify_calloc - Fortify's replacement calloc
*/
void *
Fortify_calloc(size_t num, size_t size, const char *file, DWORD line)
{
if (!st_Disabled)
{
void *ptr = Fortify_Allocate(size * num, Fortify_Allocator_calloc, file, line);
if (ptr)
{
memset(ptr, 0, size*num);
}
return ptr;
}
else
{
return calloc(num, size);
}
}
/*
* Fortify_free - Fortify's replacement free
*/
void
Fortify_free(void *uptr, const char *file, DWORD line)
{
/* it is defined to be safe to free(0) */
if (uptr == 0)
return;
Fortify_Deallocate(uptr, Fortify_Deallocator_free, file, line);
}
/*
* Fortify_strdup - Fortify's replacement strdup. Since strdup isn't
* ANSI, it is only provided if FORTIFY_STRDUP is defined.
*/
#ifdef FORTIFY_STRDUP
char *FORTIFY_STORAGE
Fortify_strdup(const char *oldStr, const char *file, DWORD line)
{
if (!st_Disabled)
{
char *newStr = Fortify_Allocate(strlen(oldStr)+1, Fortify_Allocator_strdup, file, line);
if (newStr)
{
strcpy(newStr, oldStr);
}
return newStr;
}
else
{
return strdup(oldStr);
}
}
#endif /* FORTIFY_STRDUP */
STATIC void st_OutputDeleteTrace (void)
{
#ifdef __cplusplus
if (st_DeleteStackTop > 1)
{
sprintf(st_Buffer, "Delete Trace: %s.%lu\n", st_DeleteFile[st_DeleteStackTop-1],
st_DeleteLine[st_DeleteStackTop-1]);
st_Output(st_Buffer);
for(int c = st_DeleteStackTop-2; c >= 0; c--)
{
sprintf(st_Buffer, " %s.%lu\n", st_DeleteFile[c],
st_DeleteLine[c]);
st_Output(st_Buffer);
}
}
#endif
}
#ifdef __cplusplus
/*
* st_NewHandler() - there is no easy way to get
* the new handler function. And isn't it great
* how the new handler doesn't take a parameter
* giving the size of the request that failed.
* Thanks Bjarne!
*/
Fortify_NewHandlerFunc
st_NewHandler()
{
/* get the current handler */
Fortify_NewHandlerFunc handler = set_new_handler(0);
/* and set it back (since we cant
* get it without changing it)
*/
set_new_handler(handler);
return handler;
}
/*
* operator new - Fortify's replacement new,
* without source-code information.
*/
void *FORTIFY_STORAGE
operator new(size_t size)
{
void *p;
while ((p = Fortify_Allocate(size, Fortify_Allocator_new,
st_AllocatorName[Fortify_Allocator_new], 0)) == 0)
{
if (st_NewHandler())
(*st_NewHandler())();
else
return 0;
}
return p;
}
/*
* operator new - Fortify's replacement new,
* with source-code information
*/
void *FORTIFY_STORAGE
operator new(size_t size, const char *file, DWORD line)
{
void *p;
while ((p = Fortify_Allocate(size, Fortify_Allocator_new, file, line)) == 0)
{
if (st_NewHandler())
(*st_NewHandler())();
else
return 0;
}
return p;
}
#ifdef FORTIFY_PROVIDE_ARRAY_NEW
/*
* operator new[], without source-code info
*/
void *FORTIFY_STORAGE
operator new[](size_t size)
{
void *p;
while ((p = Fortify_Allocate(size, Fortify_Allocator_array_new,
st_AllocatorName[Fortify_Allocator_array_new], 0)) == 0)
{
if (st_NewHandler())
(*st_NewHandler())();
else
return 0;
}
return p;
}
/*
* operator new[], with source-code info
*/
void *FORTIFY_STORAGE
operator new[](size_t size, const char *file, DWORD line)
{
void *p;
while ((p = Fortify_Allocate(size, Fortify_Allocator_array_new, file, line)) == 0)
{
if (st_NewHandler())
(*st_NewHandler())();
else
return 0;
}
return p;
}
#endif /* FORTIFY_PROVIDE_ARRAY_NEW */
/*
* Fortify_PreDelete - C++ does not allow overloading
* of delete, so the delete macro calls Fortify_PreDelete
* with the source-code info, and then calls delete.
*/
void FORTIFY_STORAGE
Fortify_PreDelete(const char *file, DWORD line)
{
FORTIFY_LOCK();
/*
* Push the source code info for the delete onto the delete stack
* (if we have enough room, of course)
*/
if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
{
st_DeleteFile[st_DeleteStackTop] = file;
st_DeleteLine[st_DeleteStackTop] = line;
}
st_DeleteStackTop++;
}
/*
* Fortify_PostDelete() - Pop the delete source-code info
* off the source stack.
*/
void FORTIFY_STORAGE
Fortify_PostDelete()
{
st_DeleteStackTop--;
FORTIFY_UNLOCK();
}
/*
* operator delete - fortify's replacement delete
*/
void FORTIFY_STORAGE
operator delete(void *uptr)
{
const char *file;
DWORD line;
/*
* It is defined to be harmless to delete 0
*/
if (uptr == 0)
return;
/*
* find the source-code info
*/
if (st_DeleteStackTop)
{
if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
{
file = st_DeleteFile[st_DeleteStackTop-1];
line = st_DeleteLine[st_DeleteStackTop-1];
}
else
{
file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];
line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];
}
}
else
{
file = st_DeallocatorName[Fortify_Deallocator_delete];
line = 0;
}
Fortify_Deallocate(uptr, Fortify_Deallocator_delete, file, line);
}
#ifdef FORTIFY_PROVIDE_ARRAY_DELETE
/*
* operator delete[] - fortify's replacement delete[]
*/
void FORTIFY_STORAGE
operator delete[](void *uptr)
{
const char *file;
DWORD line;
/*
* It is defined to be harmless to delete 0
*/
if (uptr == 0)
return;
/*
* find the source-code info
*/
if (st_DeleteStackTop)
{
if (st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)
{
file = st_DeleteFile[st_DeleteStackTop-1];
line = st_DeleteLine[st_DeleteStackTop-1];
}
else
{
file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];
line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];
}
}
else
{
file = st_DeallocatorName[Fortify_Deallocator_array_delete];
line = 0;
}
Fortify_Deallocate(uptr, Fortify_Deallocator_array_delete, file, line);
}
#endif /* FORTIFY_PROVIDE_ARRAY_DELETE */
#ifdef FORTIFY_AUTOMATIC_LOG_FILE
/* Automatic log file stuff!
*
* AutoLogFile class. There can only ever be ONE of these
* instantiated! It is a static class, which means that
* it's constructor will be called at program initialization,
* and it's destructor will be called at program termination.
* We don't know if the other static class objects have been
* constructed/destructed yet, but this pretty much the best
* we can do with standard C++ language features.
*/
class Fortify_AutoLogFile
{
static FILE *fp;
static int written_something;
static char *init_string, *term_string;
public:
Fortify_AutoLogFile()
{
written_something = 0;
Fortify_SetOutputFunc(Fortify_AutoLogFile::Output);
Fortify_EnterScope(init_string, 0);
}
static void Output(const char *s)
{
if (written_something == 0)
{
FORTIFY_FIRST_ERROR_FUNCTION;
fp = fopen(FORTIFY_LOG_FILENAME, "w");
if (fp)
{
time_t t;
time(&t);
fprintf(fp, "Fortify log started at %s\n", ctime(&t));
written_something = 1;
}
}
if (fp)
{
fputs(s, fp);
fflush(fp);
}
}
~Fortify_AutoLogFile()
{
Fortify_LeaveScope(term_string, 0);
Fortify_CheckAllMemory(term_string, 0);
if (fp)
{
time_t t;
time(&t);
fprintf(fp, "\nFortify log closed at %s\n", ctime(&t));
fclose(fp);
fp = 0;
}
}
};
FILE *Fort
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -