From 0b709e3409a1899caa6aaf3a5442e83524e2355c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 16 Apr 2020 11:52:37 +0200 Subject: Fix bug #79336 Make reading of floats and doubles host-endian independent. --- ext/exif/exif.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'ext/exif') diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 2dee5cdffe..31ef1e2dd0 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1487,7 +1487,7 @@ static signed short php_ifd_get16s(void *value, int motorola_intel) } /* }}} */ -/* {{{ php_ifd_get32s +/* {{{ php_ifd_get32u * Convert a 32 bit unsigned value from file's native byte order */ static unsigned php_ifd_get32u(void *void_value, int motorola_intel) { @@ -1506,6 +1506,33 @@ static unsigned php_ifd_get32u(void *void_value, int motorola_intel) } /* }}} */ +/* {{{ php_ifd_get64u + * Convert a 64 bit unsigned value from file's native byte order */ +static uint64_t php_ifd_get64u(void *void_value, int motorola_intel) +{ + uchar *value = (uchar *) void_value; + if (motorola_intel) { + return ((uint64_t)value[0] << 56) + | ((uint64_t)value[1] << 48) + | ((uint64_t)value[2] << 40) + | ((uint64_t)value[3] << 32) + | ((uint64_t)value[4] << 24) + | ((uint64_t)value[5] << 16) + | ((uint64_t)value[6] << 8 ) + | ((uint64_t)value[7] ); + } else { + return ((uint64_t)value[7] << 56) + | ((uint64_t)value[6] << 48) + | ((uint64_t)value[5] << 40) + | ((uint64_t)value[4] << 32) + | ((uint64_t)value[3] << 24) + | ((uint64_t)value[2] << 16) + | ((uint64_t)value[1] << 8 ) + | ((uint64_t)value[0] ); + } +} +/* }}} */ + /* {{{ php_ifd_get32u * Convert a 32 bit signed value from file's native byte order */ static unsigned php_ifd_get32s(void *value, int motorola_intel) @@ -1547,17 +1574,15 @@ static void php_ifd_set32u(char *data, size_t value, int motorola_intel) /* }}} */ static float php_ifd_get_float(char *data) { - /* Copy to avoid alignment issues */ - float f; - memcpy(&f, data, sizeof(float)); - return f; + union { uint32_t i; float f; } u; + u.i = php_ifd_get32u(data, 0); + return u.f; } static double php_ifd_get_double(char *data) { - /* Copy to avoid alignment issues */ - double f; - memcpy(&f, data, sizeof(double)); - return f; + union { uint64_t i; double f; } u; + u.i = php_ifd_get64u(data, 0); + return u.f; } #ifdef EXIF_DEBUG -- cgit v1.2.1