}
/* }}} */
+/* Use saturation for out of bounds values to avoid UB */
+static size_t float_to_size_t(float x) {
+ if (x < 0.0f) {
+ return 0;
+ } else if (x > (float) SIZE_MAX) {
+ return SIZE_MAX;
+ } else {
+ return (size_t) x;
+ }
+}
+
+static size_t double_to_size_t(double x) {
+ if (x < 0.0) {
+ return 0;
+ } else if (x > (double) SIZE_MAX) {
+ return SIZE_MAX;
+ } else {
+ return (size_t) x;
+ }
+}
+
/* {{{ exif_convert_any_to_int
* Evaluate number, be it int, rational, or float from directory. */
static size_t exif_convert_any_to_int(void *value, int format, int motorola_intel)
#ifdef EXIF_DEBUG
php_error_docref(NULL, E_NOTICE, "Found value of type single");
#endif
- return (size_t) php_ifd_get_float(value);
+ return float_to_size_t(php_ifd_get_float(value));
case TAG_FMT_DOUBLE:
#ifdef EXIF_DEBUG
php_error_docref(NULL, E_NOTICE, "Found value of type double");
#endif
- return (size_t) php_ifd_get_double(value);
+ return double_to_size_t(php_ifd_get_double(value));
}
return 0;
}
--- /dev/null
+--TEST--
+Overflow in float to int cast
+--FILE--
+<?php
+
+var_dump(@exif_read_data(__DIR__ . '/float_cast_overflow.tiff'));
+
+?>
+--EXPECTF--
+array(8) {
+ ["FileName"]=>
+ string(24) "float_cast_overflow.tiff"
+ ["FileDateTime"]=>
+ int(%d)
+ ["FileSize"]=>
+ int(142)
+ ["FileType"]=>
+ int(7)
+ ["MimeType"]=>
+ string(10) "image/tiff"
+ ["SectionsFound"]=>
+ string(24) "ANY_TAG, IFD0, THUMBNAIL"
+ ["COMPUTED"]=>
+ array(5) {
+ ["html"]=>
+ string(20) "width="1" height="1""
+ ["Height"]=>
+ int(1)
+ ["Width"]=>
+ int(1)
+ ["IsColor"]=>
+ int(0)
+ ["ByteOrderMotorola"]=>
+ int(0)
+ }
+ ["THUMBNAIL"]=>
+ array(2) {
+ ["ImageWidth"]=>
+ int(1)
+ ["ImageLength"]=>
+ float(-2.5961487387524E+33)
+ }
+}