Skip to content

Commit

Permalink
Fix invalid read
Browse files Browse the repository at this point in the history
  • Loading branch information
BusyStudent committed Sep 24, 2021
1 parent 7f02fc4 commit 629f0e6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
1 change: 0 additions & 1 deletion build/Linux/SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ for i in os.listdir("../../src/Psd/"):
#Remove win32 source
if i.endswith(".cpp") and i != "PsdNativeFile.cpp":
source.append("../../src/Psd/" + i)
print(source)

source.append("../../src/Psd/Psdminiz.c")

Expand Down
47 changes: 46 additions & 1 deletion src/Samples/PsdSamples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ PSD_USING_NAMESPACE;


#ifdef __linux
#define OutputDebugStringA(S) fputs(S,stderr)
#define OutputDebugStringA(S) fprintf(stderr,"%s",S)
#include <climits>
#include <cstring>
#endif
Expand Down Expand Up @@ -364,7 +364,52 @@ int SampleReadPsd(void)
std::wstringstream layerName;
if (layer->utf16Name)
{
#ifdef _WIN32
//In Windows wchar_t is utf16
static_assert(sizeof(wchar_t) == sizeof(uint16_t));
layerName << reinterpret_cast<wchar_t*>(layer->utf16Name);
#else
//In Linux, wchar_t is utf32
//Convert code from https://stackoverflow.com/questions/23919515/how-to-convert-from-utf-16-to-utf-32-on-linux-with-std-library#comment95663809_23920015
//We cannot use C++11,so use macro instead of lambda
#define is_surrogate(uc) ( (uc - 0xd800u) < 2048u )
#define is_high_surrogate(uc) ( (uc & 0xfffffc00) == 0xd800 )
#define is_low_surrogate(uc) ( (uc & 0xfffffc00) == 0xdc00 )
#define surrogate_to_utf32(high,low) ((high << 10) + low - 0x35fdc00)
static_assert(sizeof(wchar_t) == sizeof(uint32_t));

//Begin convert
size_t u16len = 0;
const uint16_t * cur = layer->utf16Name;
while(*cur != uint16_t('\0')){
cur++;
u16len++;
}
//Len it

const uint16_t * const end = layer->utf16Name + u16len;
const uint16_t * input = layer->utf16Name;
while (input < end) {
const uint16_t uc = *input++;
if (!is_surrogate(uc)) {
layerName << wchar_t(uc);
}
else {
if (is_high_surrogate(uc) && input < end && is_low_surrogate(*input)){
layerName << wchar_t(surrogate_to_utf32(uc, *input++));
}
else{
// Error
// Impossible
std::abort();
}
}
}
#undef is_surrogate
#undef is_high_surrogate
#undef is_low_surrogate
#undef surrogate_to_utf32
#endif
}
else
{
Expand Down

0 comments on commit 629f0e6

Please sign in to comment.