Avoid float to int cast UB in exif

This commit is contained in:
Nikita Popov 2019-12-17 13:15:01 +01:00
parent ddd6e68ef9
commit dd997a40d0
3 changed files with 66 additions and 2 deletions

View file

@ -1697,6 +1697,27 @@ static int exif_rewrite_tag_format_to_unsigned(int format)
} }
/* }}} */ /* }}} */
/* 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 /* {{{ exif_convert_any_to_int
* Evaluate number, be it int, rational, or float from directory. */ * 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) 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
#ifdef EXIF_DEBUG #ifdef EXIF_DEBUG
php_error_docref(NULL, E_NOTICE, "Found value of type single"); php_error_docref(NULL, E_NOTICE, "Found value of type single");
#endif #endif
return (size_t) php_ifd_get_float(value); return float_to_size_t(php_ifd_get_float(value));
case TAG_FMT_DOUBLE: case TAG_FMT_DOUBLE:
#ifdef EXIF_DEBUG #ifdef EXIF_DEBUG
php_error_docref(NULL, E_NOTICE, "Found value of type double"); php_error_docref(NULL, E_NOTICE, "Found value of type double");
#endif #endif
return (size_t) php_ifd_get_double(value); return double_to_size_t(php_ifd_get_double(value));
} }
return 0; return 0;
} }

View file

@ -0,0 +1,43 @@
--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)
}
}

Binary file not shown.