Skip to content

Commit 8be9e15

Browse files
committed
Added sanity checks in progressive JPEG decoder
1 parent a4ff7ba commit 8be9e15

File tree

1 file changed

+29
-23
lines changed

1 file changed

+29
-23
lines changed

gid-decoding_jpg.adb

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ package body GID.Decoding_JPG is
10201020
y_val_8 : U8;
10211021
begin
10221022
for ymb in flat'Range (2) loop
1023-
exit when y0 + Integer_32 (ymb) >= image.height;
1023+
exit when y0 + Integer_32 (ymb) >= image.height or else x0 >= image.width;
10241024
Set_X_Y (Integer (x0), Integer (image.height - 1 - (y0 + Integer_32 (ymb))));
10251025
for xmb in flat'Range (1) loop
10261026
exit when x0 + Integer_32 (xmb) >= image.width;
@@ -1291,7 +1291,7 @@ package body GID.Decoding_JPG is
12911291
declare
12921292
info : JPEG_Defs.Info_per_Component_A
12931293
renames image.JPEG_stuff.info (c);
1294-
block_x, block_y, delta_x, delta_y : Natural_32;
1294+
block_x, block_y, x_delta_x, y_delta_y : Natural_32;
12951295
new_bit : Integer;
12961296
begin
12971297
-- (x, y) coordinates, on the image, of current MCU's corner
@@ -1314,14 +1314,16 @@ package body GID.Decoding_JPG is
13141314
-- Coordinates of the block on the current MCU
13151315
block_x := Natural_32 (block_count mod info.ups.samples_hor);
13161316
block_y := Natural_32 (block_count / info.ups.samples_hor);
1317-
delta_x := 8 * block_x;
1318-
delta_y := 8 * block_y;
1317+
x_delta_x := x + 8 * block_x;
1318+
y_delta_y := y + 8 * block_y;
13191319
if refining then
13201320
-- Refining scan for the DC values
13211321
new_bit := Get_Bits (1);
1322-
image_array (x + delta_x, y + delta_y, compo_idx) :=
1323-
image_array (x + delta_x, y + delta_y, compo_idx) +
1324-
new_bit * (2 ** bit_position_low);
1322+
if x_delta_x <= image_array'Last (1) and then y_delta_y <= image_array'Last (2) then
1323+
image_array (x_delta_x, y_delta_y, compo_idx) :=
1324+
image_array (x_delta_x, y_delta_y, compo_idx) +
1325+
new_bit * (2 ** bit_position_low);
1326+
end if;
13251327
else
13261328
-- Decode DC value
13271329
Get_VLC
@@ -1332,17 +1334,18 @@ package body GID.Decoding_JPG is
13321334
info_B (c).dc_predictor := dc_value;
13331335
-- Store the partial DC value on the image array
13341336
-- Note that dc_value can be (and is often) negative.
1335-
image_array (x + delta_x, y + delta_y, compo_idx) :=
1336-
dc_value * (2 ** bit_position_low);
1337+
1338+
if x_delta_x <= image_array'Last (1) and then y_delta_y <= image_array'Last (2) then
1339+
image_array (x_delta_x, y_delta_y, compo_idx) := dc_value * (2 ** bit_position_low);
1340+
end if;
13371341
end if;
13381342
if full_trace then
13391343
Put_Line
13401344
(dump_file,
13411345
dump_sep & dump_sep & dump_sep &
1342-
Integer_32'Image (x + delta_x) & dump_sep &
1343-
Integer_32'Image (y + delta_y) & dump_sep &
1344-
image_array
1345-
(x + delta_x, y + delta_y, compo_idx)'Image);
1346+
Integer_32'Image (x_delta_x) & dump_sep &
1347+
Integer_32'Image (y_delta_y) & dump_sep &
1348+
image_array (x_delta_x, y_delta_y, compo_idx)'Image);
13461349
end if;
13471350
end loop;
13481351
end;
@@ -1756,7 +1759,7 @@ package body GID.Decoding_JPG is
17561759
-- for the upsampling, which gives a bit more complexity, especially
17571760
-- since it depends on settings *per component*...
17581761
x_image_array, y_image_array :
1759-
array (Component) of Integer_32 := (others => 0);
1762+
array (Component) of Natural_32 := (others => 0);
17601763

17611764
qt_zz : array (Component) of JPEG_Defs.Quantization_Table;
17621765

@@ -1799,17 +1802,20 @@ package body GID.Decoding_JPG is
17991802
declare
18001803
block : Block_8x8 renames mb (c, sbx, sby);
18011804
qt_local : JPEG_Defs.Quantization_Table renames qt_zz (c);
1805+
x_base : constant Natural_32 := x_image_array (c) + Integer_32 (8 * (sbx - 1));
1806+
y_base : constant Natural_32 := y_image_array (c) + Integer_32 (8 * (sby - 1));
18021807
begin
1803-
-- Copy block data:
1804-
for yb in reverse 0 .. 7 loop
1805-
for xb in reverse 0 .. 7 loop
1806-
block (xb + yb * 8) :=
1807-
image_array
1808-
(x_image_array (c) + Integer_32 (8 * (sbx - 1) + xb),
1809-
y_image_array (c) + Integer_32 (8 * (sby - 1) + yb),
1810-
c_idx);
1808+
if x_base + 7 <= image_array'Last (1) and then y_base + 7 <= image_array'Last (2) then
1809+
-- Copy block data:
1810+
for yb in reverse 0 .. 7 loop
1811+
for xb in reverse 0 .. 7 loop
1812+
block (xb + yb * 8) :=
1813+
image_array (x_base + Natural_32 (xb), y_base + Natural_32 (yb), c_idx);
1814+
end loop;
18111815
end loop;
1812-
end loop;
1816+
else
1817+
block := (others => 0);
1818+
end if;
18131819
-- Undo quantization on the block:
18141820
for i in reverse 0 .. 63 loop
18151821
block (i) := block (i) * qt_local (i);

0 commit comments

Comments
 (0)