83 lines
3.0 KiB
Diff
Executable File
83 lines
3.0 KiB
Diff
Executable File
From f93f613aa9873026ccf7b0d625eb86c27b6b42b9 Mon Sep 17 00:00:00 2001
|
|
From: Chris Liddell <chris.liddell@artifex.com>
|
|
Date: Thu, 1 Oct 2020 15:58:25 +0100
|
|
Subject: [PATCH] Searching for a marker in a stream, honor alignment
|
|
|
|
When searching for markers in a stream buffer, we were "seeking" to the point
|
|
in the buffer, and casting to either a byte, ushort or a uint to make the
|
|
value comparison. But we cannot do that on SPARC because of the strict
|
|
alignment on that hardware.
|
|
|
|
So, we have to "unpack" the individual bytes from the stream to do the value
|
|
comparison.
|
|
|
|
Note: there are slightly confusing comments in the code that mention being
|
|
"on a 16 bit boundary" and "on a 32 bit boundary" - that's referring to the
|
|
offset into the buffer, *not* the actual memory address alignment.
|
|
|
|
Found in testing on Solaris/SPARC
|
|
---
|
|
jbig2_mmr.c | 19 ++++++++++++++++---
|
|
1 file changed, 16 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/jbig2_mmr.c b/jbig2_mmr.c
|
|
index 578754c..5c39903 100644
|
|
--- a/jbig2_mmr.c
|
|
+++ b/jbig2_mmr.c
|
|
@@ -744,6 +744,16 @@ const mmr_table_node jbig2_mmr_black_decode[] = {
|
|
|
|
#define getbit(buf, x) ( ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 )
|
|
|
|
+/* On platforms that enforce aligned memory accesses, we can't just
|
|
+ * cast the byte * to the type of object we are accessing, we have
|
|
+ * unpack the requisite number of bytes, and deal with it that way.
|
|
+ * Note that the comments below about being 16/32 bit boundaries
|
|
+ * is referring to offsets into the byte stream, *not* memory
|
|
+ * addresses.
|
|
+ */
|
|
+#define getword16(b) ((uint16_t)(b[0] | (b[1] << 8)))
|
|
+#define getword32(b) ((uint32_t)(getword16(b) | (getword16((b + 2)) << 16)))
|
|
+
|
|
static uint32_t
|
|
jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
|
|
{
|
|
@@ -817,7 +827,7 @@ jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
|
|
if (w - x < 16) {
|
|
goto check8;
|
|
}
|
|
- if ( ((uint16_t*) line)[ x / 16] != all16) {
|
|
+ if ( getword16((line + (x / 8))) != all16) {
|
|
goto check8_no_eof;
|
|
}
|
|
x += 16; /* This will make x a multiple of 32. */
|
|
@@ -835,7 +845,7 @@ jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
|
|
look at the next uint16, then uint8, then last 8 bits. */
|
|
goto check16;
|
|
}
|
|
- if (((uint32_t*) line)[x/32] != all32) {
|
|
+ if ( getword32((line + (x / 8))) != all32) {
|
|
goto check16_no_eof;
|
|
}
|
|
x += 32;
|
|
@@ -849,7 +859,7 @@ jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
|
|
}
|
|
check16_no_eof:
|
|
assert(w - x >= 16);
|
|
- if ( ((uint16_t*) line)[x/16] != all16) {
|
|
+ if ( getword16((line + (x / 8))) != all16) {
|
|
goto check8_no_eof;
|
|
}
|
|
x += 16;
|
|
@@ -890,6 +900,9 @@ jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
|
|
return x;
|
|
}
|
|
|
|
+#undef getword16
|
|
+#undef getword32
|
|
+
|
|
static uint32_t
|
|
jbig2_find_changing_element_of_color(const byte *line, uint32_t x, uint32_t w, int color)
|
|
{
|
|
--
|
|
2.27.0
|