Skip to content

Commit dd997a4

Browse files
committed
Avoid float to int cast UB in exif
1 parent ddd6e68 commit dd997a4

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

ext/exif/exif.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,27 @@ static int exif_rewrite_tag_format_to_unsigned(int format)
16971697
}
16981698
/* }}} */
16991699

1700+
/* Use saturation for out of bounds values to avoid UB */
1701+
static size_t float_to_size_t(float x) {
1702+
if (x < 0.0f) {
1703+
return 0;
1704+
} else if (x > (float) SIZE_MAX) {
1705+
return SIZE_MAX;
1706+
} else {
1707+
return (size_t) x;
1708+
}
1709+
}
1710+
1711+
static size_t double_to_size_t(double x) {
1712+
if (x < 0.0) {
1713+
return 0;
1714+
} else if (x > (double) SIZE_MAX) {
1715+
return SIZE_MAX;
1716+
} else {
1717+
return (size_t) x;
1718+
}
1719+
}
1720+
17001721
/* {{{ exif_convert_any_to_int
17011722
* Evaluate number, be it int, rational, or float from directory. */
17021723
static size_t exif_convert_any_to_int(void *value, int format, int motorola_intel)
@@ -1735,12 +1756,12 @@ static size_t exif_convert_any_to_int(void *value, int format, int motorola_inte
17351756
#ifdef EXIF_DEBUG
17361757
php_error_docref(NULL, E_NOTICE, "Found value of type single");
17371758
#endif
1738-
return (size_t) php_ifd_get_float(value);
1759+
return float_to_size_t(php_ifd_get_float(value));
17391760
case TAG_FMT_DOUBLE:
17401761
#ifdef EXIF_DEBUG
17411762
php_error_docref(NULL, E_NOTICE, "Found value of type double");
17421763
#endif
1743-
return (size_t) php_ifd_get_double(value);
1764+
return double_to_size_t(php_ifd_get_double(value));
17441765
}
17451766
return 0;
17461767
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Overflow in float to int cast
3+
--FILE--
4+
<?php
5+
6+
var_dump(@exif_read_data(__DIR__ . '/float_cast_overflow.tiff'));
7+
8+
?>
9+
--EXPECTF--
10+
array(8) {
11+
["FileName"]=>
12+
string(24) "float_cast_overflow.tiff"
13+
["FileDateTime"]=>
14+
int(%d)
15+
["FileSize"]=>
16+
int(142)
17+
["FileType"]=>
18+
int(7)
19+
["MimeType"]=>
20+
string(10) "image/tiff"
21+
["SectionsFound"]=>
22+
string(24) "ANY_TAG, IFD0, THUMBNAIL"
23+
["COMPUTED"]=>
24+
array(5) {
25+
["html"]=>
26+
string(20) "width="1" height="1""
27+
["Height"]=>
28+
int(1)
29+
["Width"]=>
30+
int(1)
31+
["IsColor"]=>
32+
int(0)
33+
["ByteOrderMotorola"]=>
34+
int(0)
35+
}
36+
["THUMBNAIL"]=>
37+
array(2) {
38+
["ImageWidth"]=>
39+
int(1)
40+
["ImageLength"]=>
41+
float(-2.5961487387524E+33)
42+
}
43+
}
142 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)