6054: Fix editor crash when shifting left/right, fix wrong up/down shifting r=heinrich5991 a=Robyt3

Shifting left/right with a shift value greater than the layer's width crashed the game due to a heap-buffer-overflow.

Shifting up/down with a shift value greater or equal to half the layer's height did not correctly shift the entire layer.

The values of the enum constants `DIRECTION_*` are changed to consecutive numbers instead of exponents of two, as the directions cannot be combined together as flags.

Closes #6036.

## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [X] Considered possible null pointers and out of bounds array indexing
- [X] Changed no physics that affect existing maps
- [X] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2022-11-16 20:27:02 +00:00 committed by GitHub
commit 56088cb4b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 16 deletions

View file

@ -3245,22 +3245,22 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int *
UI()->DoLabel(&Shifter, "Y", 10.0f, TEXTALIGN_CENTER);
if(DoButton_ButtonDec(&pIDs[i], "-", 0, &Left, 0, "Left"))
{
*pNewVal = 1;
*pNewVal = DIRECTION_LEFT;
Change = i;
}
if(DoButton_ButtonInc(((char *)&pIDs[i]) + 3, "+", 0, &Right, 0, "Right"))
{
*pNewVal = 2;
*pNewVal = DIRECTION_RIGHT;
Change = i;
}
if(DoButton_ButtonDec(((char *)&pIDs[i]) + 1, "-", 0, &Up, 0, "Up"))
{
*pNewVal = 4;
*pNewVal = DIRECTION_UP;
Change = i;
}
if(DoButton_ButtonInc(((char *)&pIDs[i]) + 2, "+", 0, &Down, 0, "Down"))
{
*pNewVal = 8;
*pNewVal = DIRECTION_DOWN;
Change = i;
}
}

View file

@ -510,10 +510,10 @@ enum
enum
{
DIRECTION_LEFT = 1,
DIRECTION_RIGHT = 2,
DIRECTION_UP = 4,
DIRECTION_DOWN = 8,
DIRECTION_LEFT = 0,
DIRECTION_RIGHT,
DIRECTION_UP,
DIRECTION_DOWN,
};
struct RECTi
@ -531,32 +531,45 @@ protected:
switch(Direction)
{
case DIRECTION_LEFT:
ShiftBy = minimum(ShiftBy, m_Width);
for(int y = 0; y < m_Height; ++y)
{
mem_move(&pTiles[y * m_Width], &pTiles[y * m_Width + ShiftBy], (m_Width - ShiftBy) * sizeof(T));
if(ShiftBy < m_Width)
mem_move(&pTiles[y * m_Width], &pTiles[y * m_Width + ShiftBy], (m_Width - ShiftBy) * sizeof(T));
mem_zero(&pTiles[y * m_Width + (m_Width - ShiftBy)], ShiftBy * sizeof(T));
}
break;
case DIRECTION_RIGHT:
ShiftBy = minimum(ShiftBy, m_Width);
for(int y = 0; y < m_Height; ++y)
{
mem_move(&pTiles[y * m_Width + ShiftBy], &pTiles[y * m_Width], (m_Width - ShiftBy) * sizeof(T));
if(ShiftBy < m_Width)
mem_move(&pTiles[y * m_Width + ShiftBy], &pTiles[y * m_Width], (m_Width - ShiftBy) * sizeof(T));
mem_zero(&pTiles[y * m_Width], ShiftBy * sizeof(T));
}
break;
case DIRECTION_UP:
for(int y = 0; y < m_Height - ShiftBy; ++y)
ShiftBy = minimum(ShiftBy, m_Height);
for(int y = ShiftBy; y < m_Height; ++y)
{
mem_copy(&pTiles[y * m_Width], &pTiles[(y + ShiftBy) * m_Width], m_Width * sizeof(T));
mem_zero(&pTiles[(y + ShiftBy) * m_Width], m_Width * sizeof(T));
mem_copy(&pTiles[(y - ShiftBy) * m_Width], &pTiles[y * m_Width], m_Width * sizeof(T));
}
for(int y = m_Height - ShiftBy; y < m_Height; ++y)
{
mem_zero(&pTiles[y * m_Width], m_Width * sizeof(T));
}
break;
case DIRECTION_DOWN:
for(int y = m_Height - 1; y >= ShiftBy; --y)
ShiftBy = minimum(ShiftBy, m_Height);
for(int y = m_Height - ShiftBy - 1; y >= 0; --y)
{
mem_copy(&pTiles[y * m_Width], &pTiles[(y - ShiftBy) * m_Width], m_Width * sizeof(T));
mem_zero(&pTiles[(y - ShiftBy) * m_Width], m_Width * sizeof(T));
mem_copy(&pTiles[(y + ShiftBy) * m_Width], &pTiles[y * m_Width], m_Width * sizeof(T));
}
for(int y = 0; y < ShiftBy; ++y)
{
mem_zero(&pTiles[y * m_Width], m_Width * sizeof(T));
}
break;
}
}
template<typename T>