Skip to content

Commit 229be28

Browse files
author
Grok Compression
committed
grk_read: fix windows crashes in release mode
1 parent abf3704 commit 229be28

File tree

1 file changed

+70
-9
lines changed

1 file changed

+70
-9
lines changed

src/lib/core/util/BufferedStream.h

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,19 +236,80 @@ void grk_write(uint8_t* buffer, TYPE value)
236236
}
237237

238238
template<typename TYPE>
239-
void grk_read(const uint8_t* buffer, TYPE* value, uint32_t numBytes)
239+
void grk_read(const uint8_t* src, TYPE* value, uint32_t numBytes)
240240
{
241241
assert(numBytes > 0 && numBytes <= sizeof(TYPE));
242-
#if defined(GROK_BIG_ENDIAN)
243-
auto dataPtr = ((uint8_t*)value);
244-
*value = 0;
245-
memcpy(dataPtr + sizeof(TYPE) - numBytes, buffer, numBytes);
246-
#else
247-
auto dataPtr = ((uint8_t*)value) + numBytes - 1;
242+
if(numBytes == 0 || numBytes > sizeof(TYPE))
243+
throw std::runtime_error("read size too large");
244+
248245
*value = 0;
249-
for(uint32_t i = 0; i < numBytes; ++i)
250-
*(dataPtr--) = *(buffer++);
246+
memcpy(value, src, numBytes); // Copy bytes directly
247+
248+
if(std::getenv("GRK_DEBUG"))
249+
{
250+
std::cout << "grk_read: src=" << (void*)src << ", bytes=";
251+
for(uint32_t i = 0; i < numBytes; ++i)
252+
{
253+
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)src[i] << " ";
254+
}
255+
std::cout << ", raw value=0x" << std::hex << *value;
256+
std::cout << std::dec << " (" << *value << ")";
257+
}
258+
259+
#if defined(_MSC_VER) // MSVC
260+
if(numBytes == 8)
261+
{
262+
*value = (TYPE)_byteswap_uint64((uint64_t)*value); // Big-endian to little-endian
263+
}
264+
else if(numBytes == 4)
265+
{
266+
*value = (TYPE)_byteswap_ulong((uint32_t)*value);
267+
}
268+
else if(numBytes == 2)
269+
{
270+
*value = (TYPE)_byteswap_ushort((uint16_t)*value);
271+
}
272+
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
273+
defined(__OpenBSD__) // POSIX with byteswap.h
274+
#include <byteswap.h>
275+
if(numBytes == 8)
276+
{
277+
*value = (TYPE)bswap_64((uint64_t)*value);
278+
}
279+
else if(numBytes == 4)
280+
{
281+
*value = (TYPE)bswap_32((uint32_t)*value);
282+
}
283+
else if(numBytes == 2)
284+
{
285+
*value = (TYPE)bswap_16((uint16_t)*value);
286+
}
287+
#else // Fallback for other POSIX systems
288+
if(numBytes == 8)
289+
{
290+
uint64_t tmp = *(uint64_t*)value;
291+
*value = (TYPE)(((tmp >> 56) & 0xFF) | ((tmp >> 40) & 0xFF00) | ((tmp >> 24) & 0xFF0000) |
292+
((tmp >> 8) & 0xFF000000) | ((tmp << 8) & 0xFF00000000) |
293+
((tmp << 24) & 0xFF0000000000) | ((tmp << 40) & 0xFF000000000000) |
294+
((tmp << 56) & 0xFF00000000000000));
295+
}
296+
else if(numBytes == 4)
297+
{
298+
uint32_t tmp = *(uint32_t*)value;
299+
*value = (TYPE)(((tmp >> 24) & 0xFF) | ((tmp >> 8) & 0xFF00) | ((tmp << 8) & 0xFF0000) |
300+
((tmp << 24) & 0xFF000000));
301+
}
302+
else if(numBytes == 2)
303+
{
304+
uint16_t tmp = *(uint16_t*)value;
305+
*value = (TYPE)(((tmp >> 8) & 0xFF) | ((tmp << 8) & 0xFF00));
306+
}
251307
#endif
308+
309+
if(std::getenv("GRK_DEBUG"))
310+
{
311+
std::cout << ", converted value=" << *value << ", type size=" << sizeof(TYPE) << std::endl;
312+
}
252313
}
253314

254315
template<typename TYPE>

0 commit comments

Comments
 (0)