1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
Origin: https://github.com/silnrsi/grcompiler/commit/19c55e009386d62468d97948db581cff08962bbb
From: Tim Eves <tim_eves@sil.org>
Date: Sun, 16 Aug 2020 13:05:41 +0700
Subject: Fixes #31: ResolveToFeatureID assumed little endian
The code attempted to read a series of up to 4 bytes into a 32 bit value
and left align anything less than 4 bytes.
However it used union type aliasing and assumed little endian host memory
layout. On a bigendian system this reverses the byte order and results
in corrupted Graphtie Feature IDs being written to the TTF.
---
diff --git a/compiler/GdlExpression.cpp b/compiler/GdlExpression.cpp
index 08fe847..e973c52 100644
--- a/compiler/GdlExpression.cpp
+++ b/compiler/GdlExpression.cpp
@@ -488,15 +488,13 @@ bool GdlStringExpression::ResolveToFeatureID(unsigned int * pnRet)
if (m_staValue.length() > 4)
return false;
- union {
- char rgch[4];
- unsigned int n;
- } featid;
// The way we do the assignments ensures the characters are left-aligned
// in the 4-byte integer (ie, occupying the most significant bytes).
- for (size_t ich = 0; ich < 4; ich++)
- featid.rgch[3-ich] = (ich < m_staValue.length()) ? m_staValue[ich] : 0;
- *pnRet = featid.n;
+ unsigned int id = 0;
+ for(auto c : m_staValue) { id <<= 8; id += c; }
+ id <<= 8*(4-m_staValue.length());
+
+ *pnRet = id;
return true;
}
|