mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 14:25:38 +03:00
Added buffer overflow (stack corruption) checking. To be tested!
This commit is contained in:
parent
551d51ea42
commit
ec5f9ec5ca
@ -52,7 +52,7 @@
|
|||||||
{ \
|
{ \
|
||||||
strcpy(outbuf, ""); \
|
strcpy(outbuf, ""); \
|
||||||
len = 0; \
|
len = 0; \
|
||||||
AMXXLOG_Log("[AMXX] Plugin did not format a string correctly (parameter %d (total %d), line %d, \"%s\")", parm, paramCount, amx->curline, g_plugins.findPluginFast(amx)); \
|
AMXXLOG_Log("[AMXX] Plugin did not format a string correctly (parameter %d (total %d), line %d, \"%s\")", parm, paramCount, amx->curline, g_plugins.findPluginFast(amx)->getName()); \
|
||||||
return outbuf; \
|
return outbuf; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +506,7 @@ int CLangMngr::GetKeyEntry(String &key)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
const char *CLangMngr::Format(const char *src, ...)
|
const char *CLangMngr::Format(const char *src, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
@ -541,7 +542,7 @@ const char *CLangMngr::Format(const char *src, ...)
|
|||||||
format[0] = '%';
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
while (!isalpha(*ptr++ = *src++))
|
while (!isalpha(*ptr++ = *src++))
|
||||||
/*nothing*/;
|
;
|
||||||
--src;
|
--src;
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
sprintf(outptr, format, va_arg(argptr, double));
|
sprintf(outptr, format, va_arg(argptr, double));
|
||||||
@ -613,7 +614,7 @@ const char *CLangMngr::Format(const char *src, ...)
|
|||||||
format[0] = '%';
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
while (!isalpha(*ptr++ = *src++))
|
while (!isalpha(*ptr++ = *src++))
|
||||||
/*nothing*/;
|
;
|
||||||
--src;
|
--src;
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
sprintf(outptr, format, va_arg(argptr, int));
|
sprintf(outptr, format, va_arg(argptr, int));
|
||||||
@ -633,13 +634,24 @@ const char *CLangMngr::Format(const char *src, ...)
|
|||||||
*outptr++ = 0;
|
*outptr++ = 0;
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
PM: Commented out so anyone using it will get a linker error*/
|
||||||
|
|
||||||
|
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
|
||||||
|
AMXXLOG_Log("[AMXX] Buffer overflow in formatting (line %d, \"%s\")", amx->curline, g_plugins.findPluginFast(amx)->getName()); \
|
||||||
|
outbuf[0] = 0; \
|
||||||
|
len = 0; \
|
||||||
|
return outbuf; }
|
||||||
|
#define CHECK_OUTPTR(offset) CHECK_PTR(outptr+offset, outbuf, sizeof(outbuf))
|
||||||
|
#define ZEROTERM(buf) buf[(sizeof(buf)/sizeof(buf[0]))-1]=0;
|
||||||
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||||
{
|
{
|
||||||
|
// number of parameters ( for NEXT_PARAM macro )
|
||||||
int paramCount = *params / sizeof(cell);
|
int paramCount = *params / sizeof(cell);
|
||||||
|
// the output buffer
|
||||||
static char outbuf[4096];
|
static char outbuf[4096];
|
||||||
cell *src = get_amxaddr(amx, params[parm++]);
|
|
||||||
char *outptr = outbuf;
|
char *outptr = outbuf;
|
||||||
|
cell *src = get_amxaddr(amx, params[parm++]);
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
S_Normal,
|
S_Normal,
|
||||||
@ -678,14 +690,14 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pAmxLangName)->pEdict, "lang");
|
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pAmxLangName)->pEdict, "lang");
|
||||||
}
|
}
|
||||||
} else { // Language Name
|
} else { // Language Name
|
||||||
int len = 0;
|
int tmplen = 0;
|
||||||
cpLangName = get_amxstring(amx, langName, 2, len);
|
cpLangName = get_amxstring(amx, langName, 2, tmplen);
|
||||||
}
|
}
|
||||||
if (!cpLangName || strlen(cpLangName) < 1)
|
if (!cpLangName || strlen(cpLangName) < 1)
|
||||||
cpLangName = "en";
|
cpLangName = "en";
|
||||||
int len = 0;
|
int tmplen = 0;
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
char *key = get_amxstring(amx, params[parm++], 1, len);
|
char *key = get_amxstring(amx, params[parm++], 1, tmplen);
|
||||||
const char *def = GetDef(cpLangName, key);
|
const char *def = GetDef(cpLangName, key);
|
||||||
if (def == NULL)
|
if (def == NULL)
|
||||||
{
|
{
|
||||||
@ -699,7 +711,8 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
}
|
}
|
||||||
if (!def)
|
if (!def)
|
||||||
{
|
{
|
||||||
static char buf[255];
|
static char buf[512];
|
||||||
|
CHECK_PTR((char*)buf+17+strlen(key), buf, sizeof(buf));
|
||||||
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
||||||
def = buf;
|
def = buf;
|
||||||
}
|
}
|
||||||
@ -709,44 +722,52 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
if (*def == '%')
|
if (*def == '%')
|
||||||
{
|
{
|
||||||
++def;
|
++def;
|
||||||
char format[16];
|
char format[32];
|
||||||
format[0] = '%';
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
while (!isalpha(*ptr++ = *def++))
|
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
|
ZEROTERM(format);
|
||||||
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
switch ( *(ptr-1) )
|
switch ( *(ptr-1) )
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
char tmpString[256];
|
char tmpString[4096];
|
||||||
char *tmpPtr = tmpString;
|
char *tmpPtr = tmpString;
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||||
while (*tmpCell)
|
while (tmpPtr-tmpString < sizeof(tmpString) && *tmpCell)
|
||||||
*tmpPtr++ = *tmpCell++;
|
*tmpPtr++ = *tmpCell++;
|
||||||
|
|
||||||
|
tmpString[sizeof(tmpString)-1] = 0;
|
||||||
|
|
||||||
*tmpPtr = 0;
|
*tmpPtr = 0;
|
||||||
sprintf(outptr, format, tmpString);
|
_snprintf(outptr, outptr-outbuf, format, tmpString);
|
||||||
|
ZEROTERM(outbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
_snprintf(outptr, outptr-outbuf, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
|
ZEROTERM(outbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
_snprintf(outptr, outptr-outbuf, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||||
|
ZEROTERM(outbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
*outptr++ = '%';
|
CHECK_OUTPTR(strlen(format)+1);
|
||||||
*outptr++ = *(ptr-1);
|
strcpy(outptr, format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,15 +779,19 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
switch (*def)
|
switch (*def)
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = '\n';
|
*outptr++ = '\n';
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = '\t';
|
*outptr++ = '\t';
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '^':
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = '^';
|
*outptr++ = '^';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
CHECK_OUTPTR(2);
|
||||||
*outptr++ = '^';
|
*outptr++ = '^';
|
||||||
*outptr++ = *def;
|
*outptr++ = *def;
|
||||||
break;
|
break;
|
||||||
@ -774,21 +799,25 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
++def;
|
++def;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = *def++;
|
*outptr++ = *def++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char tmpString[256];
|
char tmpString[4096];
|
||||||
char *tmpPtr = tmpString;
|
char *tmpPtr = tmpString;
|
||||||
int tmpLen = 0;
|
int tmpLen = 0;
|
||||||
char format[16];
|
char format[32];
|
||||||
format[0] = '%';
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
if (*src != '%')
|
if (*src != '%')
|
||||||
{
|
{
|
||||||
while (*src != 0 && !isalpha(*ptr++ = *src++))
|
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = *src++))
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
|
ZEROTERM(format);
|
||||||
--src;
|
--src;
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
switch ( *(ptr-1) )
|
switch ( *(ptr-1) )
|
||||||
@ -797,44 +826,51 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||||
while (*tmpCell)
|
while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell)
|
||||||
*tmpPtr++ = *tmpCell++;
|
*tmpPtr++ = *tmpCell++;
|
||||||
*tmpPtr = 0;
|
*tmpPtr = 0;
|
||||||
sprintf(outptr, format, tmpString);
|
_snprintf(outptr, outptr-outbuf, format, tmpString);
|
||||||
|
ZEROTERM(outbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
_snprintf(outptr, outptr-outbuf, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
_snprintf(outptr, outptr-outbuf, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
CHECK_OUTPTR(strlen(format)+1);
|
||||||
strcpy(outptr, format);
|
strcpy(outptr, format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outptr += strlen(outptr);
|
outptr += strlen(outptr);
|
||||||
} else {
|
} else {
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = '%';
|
*outptr++ = '%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curState = S_Normal;
|
curState = S_Normal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = *src;
|
*outptr++ = *src;
|
||||||
|
}
|
||||||
++src;
|
++src;
|
||||||
}
|
}
|
||||||
len = outptr - outbuf;
|
len = outptr - outbuf;
|
||||||
|
CHECK_OUTPTR(1);
|
||||||
*outptr++ = 0;
|
*outptr++ = 0;
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user