mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +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
|
||||
- Fixed: The MAPINFO flags that control jumping, crouching, and freelook,
|
||||
rather than overriding the dmflags values, actually overwrote the dmflags
|
||||
|
|
|
@ -718,8 +718,11 @@ void AddCommandString (char *cmd, int keynum)
|
|||
// to point to a buffer large enough to hold all the arguments. The
|
||||
// return value is the necessary size of this buffer.
|
||||
//
|
||||
// Special processing: Inside quoted strings, \" becomes just "
|
||||
// $<cvar> is replaced by the contents of <cvar>
|
||||
// Special processing:
|
||||
// Inside quoted strings, \" becomes just "
|
||||
// \\ becomes just \
|
||||
// \c becomes just TEXTCOLOR_ESCAPE
|
||||
// $<cvar> is replaced by the contents of <cvar>
|
||||
|
||||
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++;
|
||||
}
|
||||
else if (stuff == '\\' && *args == '\\')
|
||||
{
|
||||
args++;
|
||||
}
|
||||
else if (stuff == '\\' && *args == 'c')
|
||||
{
|
||||
stuff = TEXTCOLOR_ESCAPE, args++;
|
||||
}
|
||||
else if (stuff == '\"')
|
||||
{
|
||||
stuff = 0;
|
||||
|
|
|
@ -110,6 +110,55 @@ static const char *UserInfoStrings[] =
|
|||
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)
|
||||
{
|
||||
if (!stricmp (gender, "female"))
|
||||
|
@ -339,6 +388,7 @@ void D_SetupUserInfo ()
|
|||
void D_UserInfoChanged (FBaseCVar *cvar)
|
||||
{
|
||||
UCVarValue val;
|
||||
FString escaped_val;
|
||||
char foo[256];
|
||||
|
||||
if (cvar == &autoaim)
|
||||
|
@ -356,10 +406,11 @@ void D_UserInfoChanged (FBaseCVar *cvar)
|
|||
}
|
||||
|
||||
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");
|
||||
|
||||
sprintf (foo, "\\%s\\%s", cvar->GetName (), val.String);
|
||||
sprintf (foo, "\\%s\\%s", cvar->GetName(), escaped_val.GetChars());
|
||||
|
||||
Net_WriteByte (DEM_UINFCHANGED);
|
||||
Net_WriteString (foo);
|
||||
|
@ -518,17 +569,18 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
|||
"\\stillbob\\%g"
|
||||
"\\playerclass\\%s"
|
||||
,
|
||||
info->netname,
|
||||
D_EscapeUserInfo(info->netname).GetChars(),
|
||||
(double)info->aimdist / (float)ANGLE_1,
|
||||
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_NEUTER ? "other" : "male",
|
||||
info->neverswitch,
|
||||
(float)(info->MoveBob) / 65536.f,
|
||||
(float)(info->StillBob) / 65536.f,
|
||||
info->PlayerClass == -1 ? "Random" :
|
||||
type->Meta.GetMetaString (APMETA_DisplayName)
|
||||
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars()
|
||||
);
|
||||
}
|
||||
else
|
||||
|
@ -546,10 +598,10 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
|||
"\\%g" // stillbob
|
||||
"\\%s" // playerclass
|
||||
,
|
||||
info->netname,
|
||||
D_EscapeUserInfo(info->netname).GetChars(),
|
||||
(double)info->aimdist / (float)ANGLE_1,
|
||||
RPART(info->color), GPART(info->color), BPART(info->color),
|
||||
skins[info->skin].name,
|
||||
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
|
||||
info->team,
|
||||
info->gender == GENDER_FEMALE ? "female" :
|
||||
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->StillBob) / 65536.f,
|
||||
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)
|
||||
{
|
||||
userinfo_t *info = &players[i].userinfo;
|
||||
char *ptr = *((char **)stream);
|
||||
char *breakpt;
|
||||
char *value;
|
||||
const char *ptr = *((const char **)stream);
|
||||
const char *breakpt;
|
||||
FString value;
|
||||
bool compact;
|
||||
int infotype = -1;
|
||||
|
||||
|
@ -583,25 +635,37 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
breakpt = strchr (ptr, '\\');
|
||||
int j;
|
||||
|
||||
if (breakpt != NULL)
|
||||
*breakpt = 0;
|
||||
breakpt = strchr (ptr, '\\');
|
||||
|
||||
if (compact)
|
||||
{
|
||||
value = ptr;
|
||||
value = D_UnescapeUserInfo(ptr, breakpt - ptr);
|
||||
infotype++;
|
||||
}
|
||||
else if (breakpt != NULL)
|
||||
else
|
||||
{
|
||||
value = breakpt + 1;
|
||||
if ( (breakpt = strchr (value, '\\')) )
|
||||
*breakpt = 0;
|
||||
assert(breakpt != NULL);
|
||||
// A malicious remote machine could invalidate the above assert.
|
||||
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;
|
||||
while (UserInfoStrings[j] && stricmp (UserInfoStrings[j], ptr) != 0)
|
||||
j++;
|
||||
for (j = 0;
|
||||
UserInfoStrings[j] && strnicmp (UserInfoStrings[j], ptr, valstart - ptr - 1) != 0;
|
||||
++j)
|
||||
{ }
|
||||
if (UserInfoStrings[j] == NULL)
|
||||
{
|
||||
infotype = -1;
|
||||
|
@ -611,10 +675,6 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
infotype = j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Shush, GCC.
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
switch (infotype)
|
||||
{
|
||||
|
@ -718,13 +778,8 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!compact)
|
||||
{
|
||||
*(value - 1) = '\\';
|
||||
}
|
||||
if (breakpt)
|
||||
{
|
||||
*breakpt = '\\';
|
||||
ptr = breakpt + 1;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2078,7 +2078,7 @@ static void M_PlayerSetupDrawer ()
|
|||
screen->DrawText (label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team",
|
||||
DTA_Clean, true, TAG_DONE);
|
||||
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],
|
||||
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,
|
||||
};
|
||||
|
||||
// This is one plasma and two rotozoomers. I think it turned out quite awesome.
|
||||
static void M_RenderPlayerBackdrop ()
|
||||
{
|
||||
BYTE *from;
|
||||
|
@ -2521,9 +2522,19 @@ static void M_PlayerNameNotChanged ()
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -4478,7 +4478,7 @@ newline:
|
|||
|
||||
normal_token:
|
||||
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))
|
||||
{
|
||||
sc_StringLen -= 2;
|
||||
|
|
Loading…
Reference in a new issue