Skip to content

Commit bd3dba0

Browse files
committed
Don't apply any text encoding to binary input data
This fixes barcode generation for arbitrary binary input failing entirely or producing incomplete/incorrect results. Observed for example with Hungarian domestic railway tickets (zlib compressed data in PDF417).
1 parent 25b1eff commit bd3dba0

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

core/src/TextDecoder.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ void TextDecoder::Append(std::string& str, const uint8_t* bytes, size_t length,
2929
if (eci == -1)
3030
eci = 899; // Binary
3131

32+
if (eci == 899) {
33+
str.reserve(str_len + length);
34+
std::copy(bytes, bytes + length, std::back_inserter(str));
35+
return;
36+
}
37+
3238
int error_number = zueci_dest_len_utf8(eci, bytes, bytes_len, replacement, flags, &utf8_len);
3339
if (error_number >= ZUECI_ERROR)
3440
throw std::runtime_error("zueci_dest_len_utf8 failed");
@@ -46,9 +52,14 @@ void TextDecoder::Append(std::string& str, const uint8_t* bytes, size_t length,
4652

4753
void TextDecoder::Append(std::wstring& str, const uint8_t* bytes, size_t length, CharacterSet charset)
4854
{
49-
std::string u8str;
50-
Append(u8str, bytes, length, charset);
51-
str.append(FromUtf8(u8str));
55+
if (charset == CharacterSet::BINARY) {
56+
str.reserve(str.size() + length);
57+
std::copy(bytes, bytes + length, std::back_inserter(str));
58+
} else {
59+
std::string u8str;
60+
Append(u8str, bytes, length, charset);
61+
str.append(FromUtf8(u8str));
62+
}
5263
}
5364

5465
/**

core/src/TextEncoder.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ void TextEncoder::GetBytes(const std::string& str, CharacterSet charset, std::st
2424
if (eci == -1)
2525
eci = 899; // Binary
2626

27+
if (eci == 899) {
28+
bytes = str;
29+
return;
30+
}
31+
2732
bytes.clear();
2833

2934
int error_number = zueci_dest_len_eci(eci, reinterpret_cast<const unsigned char *>(str.data()), str_len, &eci_len);
@@ -44,7 +49,13 @@ void TextEncoder::GetBytes(const std::string& str, CharacterSet charset, std::st
4449

4550
void TextEncoder::GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes)
4651
{
47-
GetBytes(ToUtf8(str), charset, bytes);
52+
if (charset == CharacterSet::BINARY) {
53+
bytes.clear();
54+
bytes.reserve(str.size());
55+
std::copy(str.begin(), str.end(), std::back_inserter(bytes));
56+
} else {
57+
GetBytes(ToUtf8(str), charset, bytes);
58+
}
4859
}
4960

5061
} // ZXing

test/unit/TextEncoderTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ TEST(TextEncoderTest, FullCycleEncodeDecode)
6060
EnDeCode(CharacterSet::UTF32BE, u8"\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN
6161
EnDeCode(CharacterSet::UTF32LE, u8"\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN
6262
// EnDeCode(CharacterSet::ISO646_Inv, "%", "%");
63-
EnDeCode(CharacterSet::BINARY, u8"\u0080\u00FF", "\x80\xFF");
64-
EnDeCode(CharacterSet::Unknown, u8"\u0080", "\x80"); // Treated as binary
65-
EnDeCode(CharacterSet::EUC_JP, u8"\u0080", "\x80"); // Not supported, treated as binary
63+
EnDeCode(CharacterSet::BINARY, u8"\u0080\u00FF", "\xC2\x80\xC3\xBF");
64+
EnDeCode(CharacterSet::Unknown, u8"\u0080", "\xC2\x80"); // Treated as binary
65+
EnDeCode(CharacterSet::EUC_JP, u8"\u0080", "\xC2\x80"); // Not supported, treated as binary
6666
}

0 commit comments

Comments
 (0)