Be more careful about sign extension in FXSYS_UINT32_GET_MSBFIRST() etc.

Make definition consistent with those used in fdrm/, which guard against
being applied to a signed char* ptr, getting back, say, a -28, then
sign-extending 1s when casting to uint32_t. We don't seem to do this
anywhere, but it is a good safeguard.

-- Add tests which flunk prior to this change.

Change-Id: I9993d6420947e5d0cd7478424747f7e701045428
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86974
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/byteorder_unittest.cpp b/core/fxcrt/byteorder_unittest.cpp
index 1133a8a..11c3024 100644
--- a/core/fxcrt/byteorder_unittest.cpp
+++ b/core/fxcrt/byteorder_unittest.cpp
@@ -25,6 +25,10 @@
     uint16_t expected =
         FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<const uint8_t*>(&v16));
     EXPECT_EQ(expected, ByteSwapToLE16(v16)) << v;
+
+    // Check safety against unexpectedly signed bytes.
+    expected = FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<const int8_t*>(&v16));
+    EXPECT_EQ(expected, ByteSwapToLE16(v16)) << v;
   }
 }
 
@@ -33,6 +37,10 @@
     uint32_t expected =
         FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<const uint8_t*>(&v));
     EXPECT_EQ(expected, ByteSwapToLE32(v)) << v;
+
+    // Check safety against unexpectedly signed bytes.
+    expected = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<const int8_t*>(&v));
+    EXPECT_EQ(expected, ByteSwapToLE32(v)) << v;
   }
 }
 
@@ -43,6 +51,10 @@
     uint16_t expected =
         FXSYS_UINT16_GET_MSBFIRST(reinterpret_cast<const uint8_t*>(&v16));
     EXPECT_EQ(expected, ByteSwapToBE16(v16)) << v;
+
+    // Check safety against unexpectedly signed bytes.
+    expected = FXSYS_UINT16_GET_MSBFIRST(reinterpret_cast<const int8_t*>(&v16));
+    EXPECT_EQ(expected, ByteSwapToBE16(v16)) << v;
   }
 }
 
@@ -51,6 +63,10 @@
     uint32_t expected =
         FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<const uint8_t*>(&v));
     EXPECT_EQ(expected, ByteSwapToBE32(v)) << v;
+
+    // Check safety against unexpectedly signed bytes.
+    expected = FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<const int8_t*>(&v));
+    EXPECT_EQ(expected, ByteSwapToBE32(v)) << v;
   }
 }
 
diff --git a/core/fxcrt/fx_system.h b/core/fxcrt/fx_system.h
index b0d4ccf..03ce86b 100644
--- a/core/fxcrt/fx_system.h
+++ b/core/fxcrt/fx_system.h
@@ -118,20 +118,24 @@
 }
 
 // Could be C, but uses C++-style casting.
-#define FXSYS_UINT16_GET_LSBFIRST(p)                            \
-  (static_cast<uint16_t>((static_cast<uint32_t>((p)[1]) << 8) | \
-                         (static_cast<uint32_t>((p)[0]))))
-#define FXSYS_UINT16_GET_MSBFIRST(p)                            \
-  (static_cast<uint16_t>((static_cast<uint32_t>((p)[0]) << 8) | \
-                         (static_cast<uint32_t>((p)[1]))))
-#define FXSYS_UINT32_GET_LSBFIRST(p)       \
-  ((static_cast<uint32_t>((p)[3]) << 24) | \
-   (static_cast<uint32_t>((p)[2]) << 16) | \
-   (static_cast<uint32_t>((p)[1]) << 8) | (static_cast<uint32_t>((p)[0])))
-#define FXSYS_UINT32_GET_MSBFIRST(p)       \
-  ((static_cast<uint32_t>((p)[0]) << 24) | \
-   (static_cast<uint32_t>((p)[1]) << 16) | \
-   (static_cast<uint32_t>((p)[2]) << 8) | (static_cast<uint32_t>((p)[3])))
+#define FXSYS_UINT16_GET_LSBFIRST(p)                               \
+  (static_cast<uint16_t>(                                          \
+      (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 8) | \
+      (static_cast<uint32_t>(static_cast<uint8_t>((p)[0])))))
+#define FXSYS_UINT16_GET_MSBFIRST(p)                               \
+  (static_cast<uint16_t>(                                          \
+      (static_cast<uint32_t>(static_cast<uint8_t>((p)[0])) << 8) | \
+      (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])))))
+#define FXSYS_UINT32_GET_LSBFIRST(p)                             \
+  ((static_cast<uint32_t>(static_cast<uint8_t>((p)[3])) << 24) | \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[2])) << 16) | \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 8) |  \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[0]))))
+#define FXSYS_UINT32_GET_MSBFIRST(p)                             \
+  ((static_cast<uint32_t>(static_cast<uint8_t>((p)[0])) << 24) | \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 16) | \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[2])) << 8) |  \
+   (static_cast<uint32_t>(static_cast<uint8_t>((p)[3]))))
 #endif  // __cplusplus
 
 #endif  // CORE_FXCRT_FX_SYSTEM_H_