mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 23:01:59 +00:00
- Added "\c" support to ParseCommandLine() when it parses quoted strings.
- Fixed: When changing your name from the menu, you got an extra " appended to your name if it ended with a backslash. - Added escape sequences for user info strings, so now they can contain embedded backslashes. - Fixed an array-out-of-bounds access when drawing the player setup menu with an invalid team number. SVN r598 (trunk)
This commit is contained in:
parent
089c2dab48
commit
8d5402cec2
5 changed files with 123 additions and 37 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
December 14, 2007
|
||||||
|
- Added "\c" support to ParseCommandLine() when it parses quoted strings.
|
||||||
|
- Fixed: When changing your name from the menu, you got an extra " appended
|
||||||
|
to your name if it ended with a backslash.
|
||||||
|
- Added escape sequences for user info strings, so now they can contain
|
||||||
|
embedded backslashes.
|
||||||
|
- Fixed an array-out-of-bounds access when drawing the player setup menu with
|
||||||
|
an invalid team number.
|
||||||
|
|
||||||
December 10, 2007
|
December 10, 2007
|
||||||
- Fixed: The MAPINFO flags that control jumping, crouching, and freelook,
|
- Fixed: The MAPINFO flags that control jumping, crouching, and freelook,
|
||||||
rather than overriding the dmflags values, actually overwrote the dmflags
|
rather than overriding the dmflags values, actually overwrote the dmflags
|
||||||
|
|
|
@ -718,7 +718,10 @@ void AddCommandString (char *cmd, int keynum)
|
||||||
// to point to a buffer large enough to hold all the arguments. The
|
// to point to a buffer large enough to hold all the arguments. The
|
||||||
// return value is the necessary size of this buffer.
|
// return value is the necessary size of this buffer.
|
||||||
//
|
//
|
||||||
// Special processing: Inside quoted strings, \" becomes just "
|
// Special processing:
|
||||||
|
// Inside quoted strings, \" becomes just "
|
||||||
|
// \\ becomes just \
|
||||||
|
// \c becomes just TEXTCOLOR_ESCAPE
|
||||||
// $<cvar> is replaced by the contents of <cvar>
|
// $<cvar> is replaced by the contents of <cvar>
|
||||||
|
|
||||||
static long ParseCommandLine (const char *args, int *argc, char **argv)
|
static long ParseCommandLine (const char *args, int *argc, char **argv)
|
||||||
|
@ -759,6 +762,14 @@ static long ParseCommandLine (const char *args, int *argc, char **argv)
|
||||||
{
|
{
|
||||||
stuff = '\"', args++;
|
stuff = '\"', args++;
|
||||||
}
|
}
|
||||||
|
else if (stuff == '\\' && *args == '\\')
|
||||||
|
{
|
||||||
|
args++;
|
||||||
|
}
|
||||||
|
else if (stuff == '\\' && *args == 'c')
|
||||||
|
{
|
||||||
|
stuff = TEXTCOLOR_ESCAPE, args++;
|
||||||
|
}
|
||||||
else if (stuff == '\"')
|
else if (stuff == '\"')
|
||||||
{
|
{
|
||||||
stuff = 0;
|
stuff = 0;
|
||||||
|
|
|
@ -110,6 +110,55 @@ static const char *UserInfoStrings[] =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replace \ with %/ and % with %%
|
||||||
|
FString D_EscapeUserInfo (const char *str)
|
||||||
|
{
|
||||||
|
FString ret;
|
||||||
|
|
||||||
|
for (; *str != '\0'; ++str)
|
||||||
|
{
|
||||||
|
if (*str == '\\')
|
||||||
|
{
|
||||||
|
ret << '%' << '/';
|
||||||
|
}
|
||||||
|
else if (*str == '%')
|
||||||
|
{
|
||||||
|
ret << '%' << '%';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret << *str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace %/ with \ and %% with %
|
||||||
|
FString D_UnescapeUserInfo (const char *str, size_t len)
|
||||||
|
{
|
||||||
|
const char *end = str + len;
|
||||||
|
FString ret;
|
||||||
|
|
||||||
|
while (*str != '\0' && str < end)
|
||||||
|
{
|
||||||
|
if (*str == '%')
|
||||||
|
{
|
||||||
|
if (*(str + 1) == '/')
|
||||||
|
{
|
||||||
|
ret << '\\';
|
||||||
|
str += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (*(str + 1) == '%')
|
||||||
|
{
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret << *str++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int D_GenderToInt (const char *gender)
|
int D_GenderToInt (const char *gender)
|
||||||
{
|
{
|
||||||
if (!stricmp (gender, "female"))
|
if (!stricmp (gender, "female"))
|
||||||
|
@ -339,6 +388,7 @@ void D_SetupUserInfo ()
|
||||||
void D_UserInfoChanged (FBaseCVar *cvar)
|
void D_UserInfoChanged (FBaseCVar *cvar)
|
||||||
{
|
{
|
||||||
UCVarValue val;
|
UCVarValue val;
|
||||||
|
FString escaped_val;
|
||||||
char foo[256];
|
char foo[256];
|
||||||
|
|
||||||
if (cvar == &autoaim)
|
if (cvar == &autoaim)
|
||||||
|
@ -356,10 +406,11 @@ void D_UserInfoChanged (FBaseCVar *cvar)
|
||||||
}
|
}
|
||||||
|
|
||||||
val = cvar->GetGenericRep (CVAR_String);
|
val = cvar->GetGenericRep (CVAR_String);
|
||||||
if (4 + strlen (cvar->GetName ()) + strlen (val.String) > 256)
|
escaped_val = D_EscapeUserInfo(val.String);
|
||||||
|
if (4 + strlen(cvar->GetName()) + escaped_val.Len() > 256)
|
||||||
I_Error ("User info descriptor too big");
|
I_Error ("User info descriptor too big");
|
||||||
|
|
||||||
sprintf (foo, "\\%s\\%s", cvar->GetName (), val.String);
|
sprintf (foo, "\\%s\\%s", cvar->GetName(), escaped_val.GetChars());
|
||||||
|
|
||||||
Net_WriteByte (DEM_UINFCHANGED);
|
Net_WriteByte (DEM_UINFCHANGED);
|
||||||
Net_WriteString (foo);
|
Net_WriteString (foo);
|
||||||
|
@ -518,17 +569,18 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
"\\stillbob\\%g"
|
"\\stillbob\\%g"
|
||||||
"\\playerclass\\%s"
|
"\\playerclass\\%s"
|
||||||
,
|
,
|
||||||
info->netname,
|
D_EscapeUserInfo(info->netname).GetChars(),
|
||||||
(double)info->aimdist / (float)ANGLE_1,
|
(double)info->aimdist / (float)ANGLE_1,
|
||||||
RPART(info->color), GPART(info->color), BPART(info->color),
|
RPART(info->color), GPART(info->color), BPART(info->color),
|
||||||
skins[info->skin].name, info->team,
|
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
|
||||||
|
info->team,
|
||||||
info->gender == GENDER_FEMALE ? "female" :
|
info->gender == GENDER_FEMALE ? "female" :
|
||||||
info->gender == GENDER_NEUTER ? "other" : "male",
|
info->gender == GENDER_NEUTER ? "other" : "male",
|
||||||
info->neverswitch,
|
info->neverswitch,
|
||||||
(float)(info->MoveBob) / 65536.f,
|
(float)(info->MoveBob) / 65536.f,
|
||||||
(float)(info->StillBob) / 65536.f,
|
(float)(info->StillBob) / 65536.f,
|
||||||
info->PlayerClass == -1 ? "Random" :
|
info->PlayerClass == -1 ? "Random" :
|
||||||
type->Meta.GetMetaString (APMETA_DisplayName)
|
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -546,10 +598,10 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
"\\%g" // stillbob
|
"\\%g" // stillbob
|
||||||
"\\%s" // playerclass
|
"\\%s" // playerclass
|
||||||
,
|
,
|
||||||
info->netname,
|
D_EscapeUserInfo(info->netname).GetChars(),
|
||||||
(double)info->aimdist / (float)ANGLE_1,
|
(double)info->aimdist / (float)ANGLE_1,
|
||||||
RPART(info->color), GPART(info->color), BPART(info->color),
|
RPART(info->color), GPART(info->color), BPART(info->color),
|
||||||
skins[info->skin].name,
|
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
|
||||||
info->team,
|
info->team,
|
||||||
info->gender == GENDER_FEMALE ? "female" :
|
info->gender == GENDER_FEMALE ? "female" :
|
||||||
info->gender == GENDER_NEUTER ? "other" : "male",
|
info->gender == GENDER_NEUTER ? "other" : "male",
|
||||||
|
@ -557,7 +609,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
(float)(info->MoveBob) / 65536.f,
|
(float)(info->MoveBob) / 65536.f,
|
||||||
(float)(info->StillBob) / 65536.f,
|
(float)(info->StillBob) / 65536.f,
|
||||||
info->PlayerClass == -1 ? "Random" :
|
info->PlayerClass == -1 ? "Random" :
|
||||||
type->Meta.GetMetaString (APMETA_DisplayName)
|
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,9 +620,9 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
||||||
{
|
{
|
||||||
userinfo_t *info = &players[i].userinfo;
|
userinfo_t *info = &players[i].userinfo;
|
||||||
char *ptr = *((char **)stream);
|
const char *ptr = *((const char **)stream);
|
||||||
char *breakpt;
|
const char *breakpt;
|
||||||
char *value;
|
FString value;
|
||||||
bool compact;
|
bool compact;
|
||||||
int infotype = -1;
|
int infotype = -1;
|
||||||
|
|
||||||
|
@ -583,25 +635,37 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
breakpt = strchr (ptr, '\\');
|
int j;
|
||||||
|
|
||||||
if (breakpt != NULL)
|
breakpt = strchr (ptr, '\\');
|
||||||
*breakpt = 0;
|
|
||||||
|
|
||||||
if (compact)
|
if (compact)
|
||||||
{
|
{
|
||||||
value = ptr;
|
value = D_UnescapeUserInfo(ptr, breakpt - ptr);
|
||||||
infotype++;
|
infotype++;
|
||||||
}
|
}
|
||||||
else if (breakpt != NULL)
|
else
|
||||||
{
|
{
|
||||||
value = breakpt + 1;
|
assert(breakpt != NULL);
|
||||||
if ( (breakpt = strchr (value, '\\')) )
|
// A malicious remote machine could invalidate the above assert.
|
||||||
*breakpt = 0;
|
if (breakpt == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const char *valstart = breakpt + 1;
|
||||||
|
if ( (breakpt = strchr (valstart, '\\')) != NULL )
|
||||||
|
{
|
||||||
|
value = D_UnescapeUserInfo(valstart, breakpt - valstart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = D_UnescapeUserInfo(valstart, strlen(valstart));
|
||||||
|
}
|
||||||
|
|
||||||
int j = 0;
|
for (j = 0;
|
||||||
while (UserInfoStrings[j] && stricmp (UserInfoStrings[j], ptr) != 0)
|
UserInfoStrings[j] && strnicmp (UserInfoStrings[j], ptr, valstart - ptr - 1) != 0;
|
||||||
j++;
|
++j)
|
||||||
|
{ }
|
||||||
if (UserInfoStrings[j] == NULL)
|
if (UserInfoStrings[j] == NULL)
|
||||||
{
|
{
|
||||||
infotype = -1;
|
infotype = -1;
|
||||||
|
@ -611,10 +675,6 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
||||||
infotype = j;
|
infotype = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // Shush, GCC.
|
|
||||||
value = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (infotype)
|
switch (infotype)
|
||||||
{
|
{
|
||||||
|
@ -718,13 +778,8 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compact)
|
|
||||||
{
|
|
||||||
*(value - 1) = '\\';
|
|
||||||
}
|
|
||||||
if (breakpt)
|
if (breakpt)
|
||||||
{
|
{
|
||||||
*breakpt = '\\';
|
|
||||||
ptr = breakpt + 1;
|
ptr = breakpt + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -2078,7 +2078,7 @@ static void M_PlayerSetupDrawer ()
|
||||||
screen->DrawText (label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team",
|
screen->DrawText (label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team",
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
screen->DrawText (value, x, PSetupDef.y + LINEHEIGHT+yo,
|
screen->DrawText (value, x, PSetupDef.y + LINEHEIGHT+yo,
|
||||||
players[consoleplayer].userinfo.team == TEAM_None ? "None" :
|
(unsigned)players[consoleplayer].userinfo.team >= NUM_TEAMS ? "None" :
|
||||||
TeamNames[players[consoleplayer].userinfo.team],
|
TeamNames[players[consoleplayer].userinfo.team],
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
|
|
||||||
|
@ -2279,6 +2279,7 @@ static BYTE smoke[1024] =
|
||||||
7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5,
|
7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is one plasma and two rotozoomers. I think it turned out quite awesome.
|
||||||
static void M_RenderPlayerBackdrop ()
|
static void M_RenderPlayerBackdrop ()
|
||||||
{
|
{
|
||||||
BYTE *from;
|
BYTE *from;
|
||||||
|
@ -2521,9 +2522,19 @@ static void M_PlayerNameNotChanged ()
|
||||||
|
|
||||||
static void M_PlayerNameChanged (FSaveGameNode *dummy)
|
static void M_PlayerNameChanged (FSaveGameNode *dummy)
|
||||||
{
|
{
|
||||||
char command[SAVESTRINGSIZE+8];
|
const char *p;
|
||||||
|
FString command("name \"");
|
||||||
|
|
||||||
sprintf (command, "name \"%s\"", savegamestring);
|
// Escape any backslashes or quotation marks before sending the name to the console.
|
||||||
|
for (p = savegamestring; *p != '\0'; ++p)
|
||||||
|
{
|
||||||
|
if (*p == '"' || *p == '\\')
|
||||||
|
{
|
||||||
|
command << '\\';
|
||||||
|
}
|
||||||
|
command << *p;
|
||||||
|
}
|
||||||
|
command << '"';
|
||||||
C_DoCommand (command);
|
C_DoCommand (command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4478,7 +4478,7 @@ newline:
|
||||||
|
|
||||||
normal_token:
|
normal_token:
|
||||||
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
|
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
|
||||||
sc_StringLen = MIN (ScriptPtr - tok, MAX_STRING_SIZE-1);
|
sc_StringLen = (unsigned int)MIN<size_t> (ScriptPtr - tok, MAX_STRING_SIZE-1);
|
||||||
if (tokens && (sc_TokenType == TK_StringConst || sc_TokenType == TK_NameConst))
|
if (tokens && (sc_TokenType == TK_StringConst || sc_TokenType == TK_NameConst))
|
||||||
{
|
{
|
||||||
sc_StringLen -= 2;
|
sc_StringLen -= 2;
|
||||||
|
|
Loading…
Reference in a new issue