Skip to content

Commit

Permalink
Fixed: Server-side buffer overflow when trying to transmit a "huge" I…
Browse files Browse the repository at this point in the history
…nFine script to clients.

Improved: Added some rudimentary mod authoring, debug aids to InFine scripts. If a referenced graphic is missing, it will now be reported in the console but the script will continue to play (objects will using said graphic will be drawn without a texture).
  • Loading branch information
danij committed Jun 3, 2009
1 parent a48540a commit 5562747
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 44 deletions.
6 changes: 3 additions & 3 deletions doomsday/engine/api/doomsday.h
Expand Up @@ -200,7 +200,7 @@ extern "C" {

// Network.
void Net_SendPacket(int to_player, int type, void* data,
int length);
size_t length);
int Net_GetTicCmd(void* command, int player);
const char* Net_GetPlayerName(int player);
ident_t Net_GetPlayerID(int player);
Expand Down Expand Up @@ -410,9 +410,9 @@ extern "C" {
void R_SetViewWindow(int x, int y, int w, int h);
int R_GetViewPort(int player, int* x, int* y, int* w, int* h);
void R_SetBorderGfx(char* lumps[9]);
void R_GetSpriteInfo(int sprite, int frame,
boolean R_GetSpriteInfo(int sprite, int frame,
spriteinfo_t* sprinfo);
void R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info);
boolean R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info);
int R_CreateAnimGroup(int flags);
void R_AddToAnimGroup(int groupNum, materialnum_t num,
int tics, int randomTics);
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/net_main.h
Expand Up @@ -266,7 +266,7 @@ void Net_Shutdown(void);
void Net_AllocArrays(void);
void Net_DestroyArrays(void);
void Net_SendPacket(int to_player, int type, void *data,
int length);
size_t length);
boolean Net_GetPacket(void);
void Net_SendBuffer(int to_player, int sp_flags);
void Net_InitGame(void);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/engine/portable/include/r_things.h
Expand Up @@ -190,8 +190,8 @@ extern vissprite_t visSprSortedHead;
extern vispsprite_t visPSprites[DDMAXPSPRITES];

material_t* R_GetMaterialForSprite(int sprite, int frame);
void R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* sprinfo);
void R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info);
boolean R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* sprinfo);
boolean R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info);
float R_VisualRadius(struct mobj_s* mo);
float R_GetBobOffset(struct mobj_s* mo);
float R_MovementYaw(float momx, float momy);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/engine/portable/src/net_main.c
Expand Up @@ -284,9 +284,9 @@ boolean Net_GetPacket(void)
/**
* This is the public interface of the message sender.
*/
void Net_SendPacket(int to_player, int type, void *data, int length)
void Net_SendPacket(int to_player, int type, void *data, size_t length)
{
int flags = 0;
int flags = 0;

// What kind of delivery to use?
if(to_player & DDSP_CONFIRM)
Expand Down
39 changes: 26 additions & 13 deletions doomsday/engine/portable/src/r_things.c
Expand Up @@ -681,26 +681,27 @@ material_t* R_GetMaterialForSprite(int sprite, int frame)
return sprDef->spriteFrames[frame].mats[0];
}

void R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* info)
boolean R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* info)
{
spritedef_t* sprDef;
spriteframe_t* sprFrame;
spritetex_t* sprTex;
material_t* mat;
material_snapshot_t ms;

#ifdef RANGECHECK
if((unsigned) sprite >= (unsigned) numSprites)
Con_Error("R_GetSpriteInfo: invalid sprite number %i.\n", sprite);
#endif
{
Con_Message("R_GetSpriteInfo: Warning, invalid sprite number %i.\n", sprite);
return false;
}

sprDef = &sprites[sprite];

if(frame >= sprDef->numFrames)
{
// We have no information to return.
memset(info, 0, sizeof(*info));
return;
return false;
}

sprFrame = &sprDef->spriteFrames[frame];
Expand All @@ -717,19 +718,31 @@ void R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* info)
info->topOffset = sprTex->offY;
info->width = ms.width;
info->height = ms.height;
return true;
}

void R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info)
boolean R_GetPatchInfo(lumpnum_t lump, patchinfo_t* info)
{
lumppatch_t* patch =
(lumppatch_t*) W_CacheLumpNum(lump, PU_CACHE);
if(info)
return false;

memset(info, 0, sizeof(*info));
info->lump = info->realLump = lump;
info->width = SHORT(patch->width);
info->height = SHORT(patch->height);
info->topOffset = SHORT(patch->topOffset);
info->offset = SHORT(patch->leftOffset);

if(lump >= 0 && lump < numLumps)
{
lumppatch_t* patch =
(lumppatch_t*) W_CacheLumpNum(lump, PU_CACHE);

info->lump = info->realLump = lump;
info->width = SHORT(patch->width);
info->height = SHORT(patch->height);
info->topOffset = SHORT(patch->topOffset);
info->offset = SHORT(patch->leftOffset);
return true;
}

VERBOSE(Con_Message("R_GetPatchInfo: Warning, invalid lumpnum %i.\n", lump));
return false;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions doomsday/engine/portable/src/sys_network.c
Expand Up @@ -503,6 +503,10 @@ void N_SendDataBufferReliably(void *data, size_t size, nodeid_t destination)
transmissionBuffer = M_Realloc(transmissionBuffer, size + 2);
}

if(size > sizeof(short))
Con_Error("N_SendDataBufferReliably: Tried to send %ul bytes "
"(max pkt size %ul).\n", (unsigned long) size,
(unsigned long) sizeof(short));
{
short packetSize = SHORT(size);
memcpy(transmissionBuffer, &packetSize, 2);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/include/d_netsv.h
Expand Up @@ -58,8 +58,8 @@ void NetSv_Sound(mobj_t *origin, int sound_id, int toPlr); // toPlr
void NetSv_SoundAtVolume(mobj_t *origin, int sound_id, int volume,
int toPlr);
void NetSv_Intermission(int flags, int state, int time);
void NetSv_Finale(int flags, char *script, boolean *conds,
int numConds);
void NetSv_Finale(int flags, const char* script, const boolean* conds,
byte numConds);
void NetSv_SendPlayerInfo(int whose, int to_whom);
void NetSv_ChangePlayerInfo(int from, byte *data);
void NetSv_Ticker(void);
Expand Down
17 changes: 11 additions & 6 deletions doomsday/plugins/common/src/d_netsv.c
Expand Up @@ -794,10 +794,10 @@ void NetSv_Intermission(int flags, int state, int time)
/**
* The actual script is sent to the clients. 'script' can be NULL.
*/
void NetSv_Finale(int flags, char *script, boolean *conds, int numConds)
void NetSv_Finale(int flags, const char* script, const boolean* conds, byte numConds)
{
byte *buffer, *ptr;
int i, len;
size_t len, scriptLen = 0;
byte* buffer, *ptr;

if(IS_CLIENT)
return;
Expand All @@ -806,7 +806,8 @@ void NetSv_Finale(int flags, char *script, boolean *conds, int numConds)
if(script)
{
flags |= FINF_SCRIPT;
len = strlen(script) + 2; // The end null and flags byte.
scriptLen = strlen(script);
len = scriptLen + 2; // The end null and flags byte.

// The number of conditions and their values.
len += 1 + numConds;
Expand All @@ -824,16 +825,20 @@ void NetSv_Finale(int flags, char *script, boolean *conds, int numConds)

if(script)
{
int i;

// The conditions.
*ptr++ = numConds;
for(i = 0; i < numConds; i++)
for(i = 0; i < numConds; ++i)
*ptr++ = conds[i];

// Then the script itself.
strcpy((char*)ptr, script);
memcpy(ptr, script, scriptLen + 1);
ptr[scriptLen] = '\0';
}

Net_SendPacket(DDSP_ALL_PLAYERS | DDSP_ORDERED, GPT_FINALE2, buffer, len);

Z_Free(buffer);
}

Expand Down
72 changes: 57 additions & 15 deletions doomsday/plugins/common/src/f_infine.c
Expand Up @@ -467,9 +467,10 @@ void FI_NewState(const char *script)
memset(fi, 0, sizeof(*fi));

// Take a copy of the script.
size = strlen(script) + 1;
fi->script = Z_Malloc(size, PU_STATIC, 0);
size = strlen(script);
fi->script = Z_Malloc(size + 1, PU_STATIC, 0);
memcpy(fi->script, script, size);
fi->script[size] = '\0';

// Init the cursor, too.
fi->cp = fi->script;
Expand Down Expand Up @@ -1667,9 +1668,15 @@ void FI_GetTurnCenter(fipic_t *pic, float *center)
{
patchinfo_t info;

R_GetPatchInfo(pic->lump[pic->seq], &info);
center[VX] = info.width / 2 - info.offset;
center[VY] = info.height / 2 - info.topOffset;
if(R_GetPatchInfo(pic->lump[pic->seq], &info))
{
center[VX] = info.width / 2 - info.offset;
center[VY] = info.height / 2 - info.topOffset;
}
else
{
center[VX] = center[VY] = 0;
}
}
else
{
Expand Down Expand Up @@ -2082,9 +2089,13 @@ void FIC_Delete(void)
void FIC_Image(void)
{
fipic_t* pic = FI_GetPic(FI_GetToken());
const char* name = FI_GetToken();

FI_ClearAnimation(pic);
pic->lump[0] = W_CheckNumForName(FI_GetToken());

if((pic->lump[0] = W_CheckNumForName(name)) == -1)
Con_Message("FIC_Image: Warning, missing lump \"%s\".\n", name);

pic->flags.is_patch = false;
pic->flags.is_rect = false;
pic->flags.is_ximage = false;
Expand All @@ -2093,11 +2104,16 @@ void FIC_Image(void)
void FIC_ImageAt(void)
{
fipic_t* pic = FI_GetPic(FI_GetToken());
const char* name;

FI_InitValue(&pic->object.x, FI_GetFloat());
FI_InitValue(&pic->object.y, FI_GetFloat());
FI_ClearAnimation(pic);
pic->lump[0] = W_CheckNumForName(FI_GetToken());

name = FI_GetToken();
if((pic->lump[0] = W_CheckNumForName(name)) == -1)
Con_Message("FIC_ImageAt: Warning, missing lump \"%s\".\n", name);

pic->flags.is_patch = false;
pic->flags.is_rect = false;
pic->flags.is_ximage = false;
Expand All @@ -2112,8 +2128,9 @@ void FIC_XImage(void)

// Load the external resource.
fileName = FI_GetToken();
pic->lump[0] = GL_LoadGraphics(RC_GRAPHICS, fileName, LGM_NORMAL,
false, true, 0);
if((pic->lump[0] = GL_LoadGraphics(RC_GRAPHICS, fileName, LGM_NORMAL,
false, true, 0)) == 0)
Con_Message("FIC_XImage: Warning, missing graphic \"%s\".\n", fileName);

pic->flags.is_patch = false;
pic->flags.is_rect = true;
Expand All @@ -2123,11 +2140,16 @@ void FIC_XImage(void)
void FIC_Patch(void)
{
fipic_t* pic = FI_GetPic(FI_GetToken());
const char* name;

FI_InitValue(&pic->object.x, FI_GetFloat());
FI_InitValue(&pic->object.y, FI_GetFloat());
FI_ClearAnimation(pic);
pic->lump[0] = W_CheckNumForName(FI_GetToken());

name = FI_GetToken();
if((pic->lump[0] = W_CheckNumForName(name)) == -1)
Con_Message("FIC_Patch: Warning, missing lump \"%s\".\n", name);

pic->flags.is_patch = true;
pic->flags.is_rect = false;
}
Expand All @@ -2136,13 +2158,18 @@ void FIC_SetPatch(void)
{
int num;
fipic_t* pic = FI_GetPic(FI_GetToken());
const char* name = FI_GetToken();

if((num = W_CheckNumForName(FI_GetToken()))!= -1)
if((num = W_CheckNumForName(name))!= -1)
{
pic->lump[0] = num;
pic->flags.is_patch = true;
pic->flags.is_rect = false;
}
else
{
Con_Message("FIC_SetPatch: Warning, missing lump \"%s\".\n", name);
}
}

void FIC_ClearAnim(void)
Expand All @@ -2156,13 +2183,20 @@ void FIC_Anim(void)
{
fipic_t *pic = FI_GetPic(FI_GetToken());
int i, lump, time;
const char* name = FI_GetToken();

if((lump = W_CheckNumForName(name)) == -1)
Con_Message("FIC_Anim: Warning, lump \"%s\" not found.\n", name);

lump = W_CheckNumForName(FI_GetToken());
time = FI_GetTics();
// Find the next sequence spot.
i = FI_GetNextSeq(pic);
if(i == MAX_SEQUENCE)
return; // Can't do it...
{
Con_Message("FIC_Anim: Warning, too many frames in anim sequence "
"(max %i).\n", MAX_SEQUENCE);
return; // Can't do it...
}
pic->lump[i] = lump;
pic->seqWait[i] = time;
pic->flags.is_patch = true;
Expand All @@ -2173,13 +2207,21 @@ void FIC_AnimImage(void)
{
fipic_t *pic = FI_GetPic(FI_GetToken());
int i, lump, time;
const char* name = FI_GetToken();

if((lump = W_CheckNumForName(name)) == -1)
Con_Message("FIC_AnimImage: Warning, lump \"%s\" not found.\n", name);

lump = W_CheckNumForName(FI_GetToken());
time = FI_GetTics();
// Find the next sequence spot.
i = FI_GetNextSeq(pic);
if(i == MAX_SEQUENCE)
return; // Can't do it...
{
Con_Message("FIC_AnimImage: Warning, too many frames in anim sequence "
"(max %i).\n", MAX_SEQUENCE);
return; // Can't do it...
}

pic->lump[i] = lump;
pic->seqWait[i] = time;
pic->flags.is_patch = false;
Expand Down

0 comments on commit 5562747

Please sign in to comment.