Skip to content

Commit c723d02

Browse files
author
Marco Aurelio da Costa
committed
Support embedded null in zTXt and iTXt chunks
1 parent 37f84c8 commit c723d02

File tree

3 files changed

+18
-10
lines changed

3 files changed

+18
-10
lines changed

lodepng.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3219,6 +3219,7 @@ static void LodePNGIText_init(LodePNGInfo* info) {
32193219
info->itext_langtags = NULL;
32203220
info->itext_transkeys = NULL;
32213221
info->itext_strings = NULL;
3222+
info->itext_sizes = NULL;
32223223
}
32233224

32243225
static void LodePNGIText_cleanup(LodePNGInfo* info) {
@@ -3233,6 +3234,7 @@ static void LodePNGIText_cleanup(LodePNGInfo* info) {
32333234
lodepng_free(info->itext_langtags);
32343235
lodepng_free(info->itext_transkeys);
32353236
lodepng_free(info->itext_strings);
3237+
lodepng_free(info->itext_sizes);
32363238
}
32373239

32383240
static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
@@ -3241,10 +3243,11 @@ static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source)
32413243
dest->itext_langtags = NULL;
32423244
dest->itext_transkeys = NULL;
32433245
dest->itext_strings = NULL;
3246+
dest->itext_sizes = NULL;
32443247
dest->itext_num = 0;
32453248
for(i = 0; i != source->itext_num; ++i) {
3246-
CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
3247-
source->itext_transkeys[i], source->itext_strings[i]));
3249+
CERROR_TRY_RETURN(lodepng_add_itext_sized(dest, source->itext_keys[i], source->itext_langtags[i],
3250+
source->itext_transkeys[i], source->itext_strings[i], source->itext_sizes[i]));
32483251
}
32493252
return 0;
32503253
}
@@ -3253,26 +3256,29 @@ void lodepng_clear_itext(LodePNGInfo* info) {
32533256
LodePNGIText_cleanup(info);
32543257
}
32553258

3256-
static unsigned lodepng_add_itext_sized(LodePNGInfo* info, const char* key, const char* langtag,
3259+
unsigned lodepng_add_itext_sized(LodePNGInfo* info, const char* key, const char* langtag,
32573260
const char* transkey, const char* str, size_t size) {
32583261
char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1)));
32593262
char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1)));
32603263
char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1)));
32613264
char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1)));
3265+
size_t* new_sizes = (size_t*)(lodepng_realloc(info->itext_sizes, sizeof(size_t) * (info->itext_num + 1)));
32623266

32633267
if(new_keys) info->itext_keys = new_keys;
32643268
if(new_langtags) info->itext_langtags = new_langtags;
32653269
if(new_transkeys) info->itext_transkeys = new_transkeys;
32663270
if(new_strings) info->itext_strings = new_strings;
3271+
if(new_sizes) info->itext_sizes = new_sizes;
32673272

3268-
if(!new_keys || !new_langtags || !new_transkeys || !new_strings) return 83; /*alloc fail*/
3273+
if(!new_keys || !new_langtags || !new_transkeys || !new_strings || !new_sizes) return 83; /*alloc fail*/
32693274

32703275
++info->itext_num;
32713276

32723277
info->itext_keys[info->itext_num - 1] = alloc_string(key);
32733278
info->itext_langtags[info->itext_num - 1] = alloc_string(langtag);
32743279
info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey);
32753280
info->itext_strings[info->itext_num - 1] = alloc_string_sized(str, size);
3281+
info->itext_sizes[info->itext_num - 1] = size;
32763282

32773283
return 0;
32783284
}
@@ -5800,12 +5806,11 @@ static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* te
58005806
}
58015807

58025808
static unsigned addChunk_iTXt(ucvector* out, unsigned compress, const char* keyword, const char* langtag,
5803-
const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) {
5809+
const char* transkey, const char* textstring, size_t textsize, LodePNGCompressSettings* zlibsettings) {
58045810
unsigned error = 0;
58055811
unsigned char* chunk = 0;
58065812
unsigned char* compressed = 0;
58075813
size_t compressedsize = 0;
5808-
size_t textsize = lodepng_strlen(textstring);
58095814
size_t keysize = lodepng_strlen(keyword), langsize = lodepng_strlen(langtag), transsize = lodepng_strlen(transkey);
58105815

58115816
if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/
@@ -6797,7 +6802,7 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
67976802
state->error = addChunk_iTXt(
67986803
&outv, state->encoder.text_compression,
67996804
info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i],
6800-
&state->encoder.zlibsettings);
6805+
info.itext_sizes[i], &state->encoder.zlibsettings);
68016806
if(state->error) goto cleanup;
68026807
}
68036808

lodepng.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ typedef struct LodePNGInfo {
550550
char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/
551551
char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/
552552
char** itext_strings; /*the actual international text - UTF-8 string*/
553+
size_t* itext_sizes; /*the actual size of the international text - UTF-8 string, including embedded NULL, excluding terminator NULL*/
553554

554555
/*
555556
Optional exif metadata in exif_size bytes.
@@ -783,6 +784,8 @@ void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again
783784

784785
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
785786
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
787+
unsigned lodepng_add_itext_sized(LodePNGInfo* info, const char* key, const char* langtag,
788+
const char* transkey, const char* str, size_t size); /*push back the 4 texts of 1 chunk at once*/
786789
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
787790

788791
/*replaces if exists*/

lodepng_unittest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ void createComplexPNG(std::vector<unsigned char>& png, int compress) {
12991299
lodepng_add_text_sized(&info, "key1", "string1\0string2", 15);
13001300

13011301
lodepng_add_itext(&info, "ikey0", "ilangtag0", "itranskey0", "istring0");
1302-
lodepng_add_itext(&info, "ikey1", "ilangtag1", "itranskey1", "istring1");
1302+
lodepng_add_itext_sized(&info, "ikey1", "ilangtag1", "itranskey1", "istring1\0istring2", 17);
13031303

13041304
info.time_defined = 1;
13051305
info.time.year = 2012;
@@ -1388,7 +1388,7 @@ void testComplexPNGNoTextCompression() {
13881388
ASSERT_STRING_EQUALS("ikey1", info.itext_keys[1]);
13891389
ASSERT_STRING_EQUALS("ilangtag1", info.itext_langtags[1]);
13901390
ASSERT_STRING_EQUALS("itranskey1", info.itext_transkeys[1]);
1391-
ASSERT_STRING_EQUALS("istring1", info.itext_strings[1]);
1391+
ASSERT_STRING_EQUALS(std::string("istring1\0istring2", 17), std::string(info.itext_strings[1], info.itext_sizes[1]));
13921392

13931393

13941394
// TODO: test if unknown chunks listed too
@@ -1462,7 +1462,7 @@ void testComplexPNGTextCompression() {
14621462
ASSERT_STRING_EQUALS("ikey1", info.itext_keys[1]);
14631463
ASSERT_STRING_EQUALS("ilangtag1", info.itext_langtags[1]);
14641464
ASSERT_STRING_EQUALS("itranskey1", info.itext_transkeys[1]);
1465-
ASSERT_STRING_EQUALS("istring1", info.itext_strings[1]);
1465+
ASSERT_STRING_EQUALS(std::string("istring1\0istring2", 17), std::string(info.itext_strings[1], info.itext_sizes[1]));
14661466

14671467

14681468
// TODO: test if unknown chunks listed too

0 commit comments

Comments
 (0)