summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-04-16 11:52:37 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-04-16 12:18:41 +0200
commit0b709e3409a1899caa6aaf3a5442e83524e2355c (patch)
tree9dd592fc23c00ae237afbdebd206d7ccd7eaef34
parente88e9afe952d90ada054634e403be0cebe06d1c9 (diff)
downloadphp-git-0b709e3409a1899caa6aaf3a5442e83524e2355c.tar.gz
Fix bug #79336
Make reading of floats and doubles host-endian independent.
-rw-r--r--NEWS4
-rw-r--r--ext/exif/exif.c43
2 files changed, 38 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index f6dead73f9..9afe0d6734 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ PHP NEWS
. Fixed bug #78221 (DOMNode::normalize() doesn't remove empty text nodes).
(cmb)
+- EXIF:
+ . Fixed bug #79336 (ext/exif/tests/bug79046.phpt fails on Big endian arch).
+ (Nikita)
+
- MBString:
. Fixed bug #79441 (Segfault in mb_chr() if internal encoding is unsupported).
(Girgias)
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