Skip to content

Commit 996bde8

Browse files
authored
[WIN32K] Fix gdi/dib horizontal line draw function crashes (reactos#8263)
* [WIN32K] Fix gdi/dib assembly code and 'C' code horizontal line draw function crashes. Do not do subtracts that cause a wrap to a negative value when determining length. This affects bit depths of 8, 16, 24, and 32 Bits per Plane. CORE-19634 CORE-13532
1 parent ea189a3 commit 996bde8

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

win32ss/gdi/dib/dib16bpp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ DIB_16BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
4343
/* This is about 10% faster than the generic C code below */
4444
LONG Count = x2 - x1;
4545

46+
if (x1 >= x2)
47+
return;
48+
4649
__asm__ __volatile__ (
4750
" cld\n"
4851
" mov %0, %%eax\n"
@@ -70,6 +73,9 @@ DIB_16BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
7073
LONG cx = x1;
7174
DWORD cc;
7275

76+
if (x1 >= x2)
77+
return;
78+
7379
if (0 != (cx & 0x01))
7480
{
7581
*((PWORD) addr) = (WORD)c;

win32ss/gdi/dib/dib24bppc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
1818
PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
1919
ULONG Count = x2 - x1;
2020

21+
if (x1 >= x2)
22+
return;
23+
2124
if (Count < 8)
2225
{
2326
/* For small fills, don't bother doing anything fancy */

win32ss/gdi/dib/dib8bpp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ DIB_8BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
3636
VOID
3737
DIB_8BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
3838
{
39+
if (x1 >= x2)
40+
return;
41+
3942
memset((PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x1, (BYTE) c, x2 - x1);
4043
}
4144

win32ss/gdi/dib/i386/dib24bpp_hline.s

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ PUBLIC _DIB_24BPP_HLine
1919
sub esp, 24
2020
mov ebx, [esp+40]
2121
mov edi, [esp+52]
22-
mov ecx, [esp+44]
22+
mov ecx, [esp+44] // ecx = LONG x1
2323
mov eax, [ebx+36]
2424
mov esi, [ebx+32]
25-
mov edx, [esp+48]
25+
mov edx, [esp+48] // edx = LONG x2
2626
imul eax, edi
27-
sub edx, ecx
27+
sub edx, ecx // cx = (x2 - x1);
28+
jc short .exit_here // cx must not be negative
2829
mov [esp], edx
2930
add eax, esi
3031
lea eax, [eax+ecx*2]
@@ -37,6 +38,7 @@ PUBLIC _DIB_24BPP_HLine
3738
mov [esp], eax
3839
inc eax
3940
jnz small_fill
41+
.exit_here:
4042
add esp, 24
4143
pop ebx
4244
pop esi

win32ss/gdi/dib/i386/dib32bpp_hline.s

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
PUBLIC _DIB_32BPP_HLine
1414

1515
_DIB_32BPP_HLine:
16-
sub esp, 12 // rember the base is not hex it is dec
16+
sub esp, 12 // remember the base is decimal
1717
mov ecx, [esp+16]
1818
mov [esp+4], ebx
1919
mov edx, [esp+20] // edx = LONG x1
@@ -23,7 +23,8 @@ _DIB_32BPP_HLine:
2323
mov ebx, [esp+24] // ebx = LONG x2
2424
imul eax, edi
2525
mov edi, [ecx+32]
26-
sub ebx, edx // cx = (x2 - x1) ;
26+
sub ebx, edx // cx = (x2 - x1);
27+
jc short .exit_here // cx must not be negative
2728
add eax, edi
2829
lea edx, [eax+edx*4]
2930
mov [esp], edx
@@ -47,7 +48,7 @@ _save_rest:
4748
rep stosd // The actual fill
4849
shr eax, 16
4950
stosw
50-
51+
.exit_here:
5152
mov ebx, [esp+4]
5253
mov edi, [esp+8]
5354
add esp, 12

0 commit comments

Comments
 (0)