summaryrefslogtreecommitdiff
path: root/jbig2dec
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2020-10-01 15:58:25 +0100
committerChris Liddell <chris.liddell@artifex.com>2020-11-27 15:20:54 +0000
commitbac9c5d2ed82390da058653afbac0d9e29e9bd3f (patch)
treefa804a3a7c70694ac4eebf462bf92e6018538ccd /jbig2dec
parent3d33e44d3d014ee78a4505c37b244957066d7b12 (diff)
downloadghostpdl-bac9c5d2ed82390da058653afbac0d9e29e9bd3f.tar.gz
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
Diffstat (limited to 'jbig2dec')
-rw-r--r--jbig2dec/jbig2_mmr.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/jbig2dec/jbig2_mmr.c b/jbig2dec/jbig2_mmr.c
index 578754c9a..5c399033d 100644
--- a/jbig2dec/jbig2_mmr.c
+++ b/jbig2dec/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 @@ check16:
}
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 @@ end:
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)
{