mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
19af1890b5
This commit replaces sprintf(buf, ...) with snprintf(buf, sizeof(buf), ...), specifically in the "easy" cases where buf is allocated with a size known at compile time. The changes make sure we are not write outside array/string bounds which will lead to undefined behaviour. In case the code is trying to write outside bounds - safe version of functions simply cut the string messages so we process this gracefully. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. bsonudf.cpp warnings cleanup by Daniel Black Reviewer: Daniel Black
200 lines
6.4 KiB
C++
200 lines
6.4 KiB
C++
#include "my_global.h"
|
|
#ifdef UNIX
|
|
#include "osutil.h"
|
|
#include <errno.h>
|
|
#include <stddef.h>
|
|
#else /* WINDOWS */
|
|
//#include <windows.h>
|
|
#include "osutil.h"
|
|
#endif /* WINDOWS */
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include "global.h"
|
|
#include "plgdbsem.h"
|
|
#include "maputil.h"
|
|
|
|
#ifdef _WIN32
|
|
/***********************************************************************/
|
|
/* In Insert mode, just open the file for append. Otherwise */
|
|
/* create the mapping file object. The map handle can be released */
|
|
/* immediately because they will not be used anymore. */
|
|
/* If del is true in DELETE mode, then delete the whole file. */
|
|
/* Returns the file handle that can be used by caller. */
|
|
/***********************************************************************/
|
|
HANDLE CreateFileMap(PGLOBAL g, LPCSTR filename,
|
|
MEMMAP *mm, MODE mode, bool del)
|
|
{
|
|
HANDLE hFile;
|
|
HANDLE hFileMap;
|
|
DWORD access, share, disposition;
|
|
|
|
memset(mm, 0, sizeof(MEMMAP));
|
|
*g->Message = '\0';
|
|
|
|
switch (mode) {
|
|
case MODE_READ:
|
|
access = GENERIC_READ;
|
|
share = FILE_SHARE_READ;
|
|
disposition = OPEN_EXISTING;
|
|
break;
|
|
case MODE_UPDATE:
|
|
case MODE_DELETE:
|
|
access = GENERIC_READ | GENERIC_WRITE;
|
|
share = 0;
|
|
disposition = (del) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
|
break;
|
|
case MODE_INSERT:
|
|
access = GENERIC_WRITE;
|
|
share = 0;
|
|
disposition = OPEN_ALWAYS;
|
|
break;
|
|
default:
|
|
snprintf(g->Message, sizeof(g->Message), MSG(BAD_FUNC_MODE), "CreateFileMap", mode);
|
|
return INVALID_HANDLE_VALUE;
|
|
} // endswitch
|
|
|
|
hFile = CreateFile(filename, access, share, NULL, disposition,
|
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
if (mode != MODE_INSERT) {
|
|
/*****************************************************************/
|
|
/* Create the file-mapping object. */
|
|
/*****************************************************************/
|
|
access = (mode == MODE_READ) ? PAGE_READONLY : PAGE_READWRITE;
|
|
hFileMap = CreateFileMapping(hFile, NULL, access, 0, 0, NULL);
|
|
|
|
if (!hFileMap) {
|
|
DWORD ler = GetLastError();
|
|
|
|
if (ler && ler != 1006) {
|
|
snprintf(g->Message, sizeof(g->Message), MSG(FILE_MAP_ERROR), filename, ler);
|
|
CloseHandle(hFile);
|
|
return INVALID_HANDLE_VALUE;
|
|
} else {
|
|
snprintf(g->Message, sizeof(g->Message), MSG(FILE_IS_EMPTY), filename);
|
|
return hFile;
|
|
} // endif ler
|
|
|
|
} // endif hFileMap
|
|
|
|
access = (mode == MODE_READ) ? FILE_MAP_READ : FILE_MAP_WRITE;
|
|
|
|
if (!(mm->memory = MapViewOfFile(hFileMap, access, 0, 0, 0))) {
|
|
DWORD ler = GetLastError();
|
|
|
|
snprintf(g->Message, sizeof(g->Message), "Error %ld in MapViewOfFile %s",
|
|
ler, filename);
|
|
CloseHandle(hFile);
|
|
return INVALID_HANDLE_VALUE;
|
|
} // endif memory
|
|
|
|
// lenH is the high-order word of the file size
|
|
mm->lenL = GetFileSize(hFile, &mm->lenH);
|
|
CloseHandle(hFileMap); // Not used anymore
|
|
} else // MODE_INSERT
|
|
/*****************************************************************/
|
|
/* The starting point must be the end of file as for append. */
|
|
/*****************************************************************/
|
|
SetFilePointer(hFile, 0, NULL, FILE_END);
|
|
|
|
return hFile;
|
|
} // end of CreateFileMap
|
|
|
|
bool CloseMemMap(LPVOID memory, size_t dwSize)
|
|
{
|
|
return (memory) ? !UnmapViewOfFile(memory) : false;
|
|
} // end of CloseMemMap
|
|
|
|
#else /* UNIX */
|
|
// Code to handle Linux and Solaris
|
|
#include <sys/types.h>
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
/***********************************************************************/
|
|
/* In Insert mode, just open the file for append. Otherwise */
|
|
/* create the mapping file object. The map handle can be released */
|
|
/* immediately because they will not be used anymore. */
|
|
/* If del is true in DELETE mode, then delete the whole file. */
|
|
/* Returns the file handle that can be used by caller. */
|
|
/***********************************************************************/
|
|
HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName,
|
|
MEMMAP *mm, MODE mode, bool del)
|
|
{
|
|
unsigned int openMode;
|
|
int protmode;
|
|
HANDLE fd;
|
|
size_t filesize;
|
|
struct stat st;
|
|
|
|
memset(mm, 0, sizeof(MEMMAP));
|
|
*g->Message = '\0';
|
|
|
|
switch (mode) {
|
|
case MODE_READ:
|
|
openMode = O_RDONLY;
|
|
protmode = PROT_READ;
|
|
break;
|
|
case MODE_UPDATE:
|
|
case MODE_DELETE:
|
|
openMode = (del) ? (O_RDWR | O_TRUNC) : O_RDWR;
|
|
protmode = PROT_READ | PROT_WRITE;
|
|
break;
|
|
case MODE_INSERT:
|
|
openMode = (O_WRONLY | O_CREAT | O_APPEND);
|
|
protmode = PROT_WRITE;
|
|
break;
|
|
default:
|
|
snprintf(g->Message, sizeof(g->Message), MSG(BAD_FUNC_MODE), "CreateFileMap", mode);
|
|
return INVALID_HANDLE_VALUE;
|
|
} // endswitch
|
|
|
|
// Try to open the addressed file.
|
|
fd= global_open(g, MSGID_NONE, fileName, openMode);
|
|
|
|
if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) {
|
|
/* We must know about the size of the file. */
|
|
if (fstat(fd, &st)) {
|
|
snprintf(g->Message, sizeof(g->Message), MSG(FILE_MAP_ERROR), fileName, errno);
|
|
close(fd);
|
|
return INVALID_HANDLE_VALUE;
|
|
} // endif fstat
|
|
|
|
if ((filesize = st.st_size))
|
|
// Now we are ready to load the file. If mmap() is available we try
|
|
// this first. If not available or it failed we try to load it.
|
|
mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0);
|
|
else
|
|
mm->memory = 0;
|
|
|
|
if (mm->memory != MAP_FAILED) {
|
|
mm->lenL = (mm->memory != 0) ? filesize : 0;
|
|
mm->lenH = 0;
|
|
} else {
|
|
strcpy(g->Message, "Memory mapping failed");
|
|
close(fd);
|
|
return INVALID_HANDLE_VALUE;
|
|
} // endif memory
|
|
|
|
} /* endif fd */
|
|
|
|
// mmap() call was successful. ??????????
|
|
return fd;
|
|
} // end of CreateFileMap
|
|
|
|
bool CloseMemMap(void *memory, size_t dwSize)
|
|
{
|
|
if (memory) {
|
|
// All this must be redesigned
|
|
int rc = msync((char*)memory, dwSize, MS_SYNC);
|
|
return (munmap((char*)memory, dwSize) < 0) ? true : false;
|
|
} else
|
|
return false;
|
|
|
|
} // end of CloseMemMap
|
|
|
|
#endif // UNIX
|