Skip to content

Commit c582208

Browse files
committed
JPEG2000 writer: remove NUL terminated byte at end of payload of 'lbl ' and 'xml ' boxes
For label boxes, the spec is pretty explicit about that: "Label strings are not null-terminated" Cf https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.801-200208-S!!PDF-E&type=items "M.11.13 Label box", page 197 For XML boxes, nothing explicit, but in the absence of a statement, null-terminating byte doesn't seem necessary. Furthermore jpylyzer documentation at https://jpylyzer.openpreservation.org/doc/latest/userManual.html has a 'nullxml' option because 'Apparently some old versions of the Kakadu demo applications would erroneously add a null-byte to embedded XML'. Fixes https://lists.osgeo.org/pipermail/gdal-dev/2025-November/061180.html Reported-by: Brad Hards <[email protected]>
1 parent 6b5353e commit c582208

File tree

3 files changed

+9
-7
lines changed

3 files changed

+9
-7
lines changed
-3 Bytes
Binary file not shown.

gcore/gdaljp2box.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ GDALJP2Box *GDALJP2Box::CreateLblBox(const char *pszLabel)
488488
{
489489
GDALJP2Box *const poBox = new GDALJP2Box();
490490
poBox->SetType("lbl ");
491-
poBox->SetWritableData(static_cast<int>(strlen(pszLabel) + 1),
491+
poBox->SetWritableData(static_cast<int>(strlen(pszLabel)),
492492
reinterpret_cast<const GByte *>(pszLabel));
493493

494494
return poBox;
@@ -504,12 +504,12 @@ GDALJP2Box *GDALJP2Box::CreateLabelledXMLAssoc(const char *pszLabel,
504504
{
505505
GDALJP2Box oLabel;
506506
oLabel.SetType("lbl ");
507-
oLabel.SetWritableData(static_cast<int>(strlen(pszLabel) + 1),
507+
oLabel.SetWritableData(static_cast<int>(strlen(pszLabel)),
508508
reinterpret_cast<const GByte *>(pszLabel));
509509

510510
GDALJP2Box oXML;
511511
oXML.SetType("xml ");
512-
oXML.SetWritableData(static_cast<int>(strlen(pszXML) + 1),
512+
oXML.SetWritableData(static_cast<int>(strlen(pszXML)),
513513
reinterpret_cast<const GByte *>(pszXML));
514514

515515
GDALJP2Box *aoList[2] = {&oLabel, &oXML};
@@ -530,6 +530,8 @@ GDALJP2Box *GDALJP2Box::CreateJUMBFDescriptionBox(const GByte *pabyUUIDType,
530530

531531
poBox->AppendWritableData(16, pabyUUIDType);
532532
poBox->AppendUInt8(3); // requestable field
533+
// +1 since NUL terminated byte requested in the spec
534+
// cf other implementation at https://gitlab.com/wg1/jpeg-systems/reference-software/jumbf-reference-implementation-2/-/blame/main/dbench_jumbf/src/db_jumbf_desc_box.cpp?ref_type=heads#L169
533535
const size_t nLabelLen = strlen(pszLabel) + 1;
534536
poBox->AppendWritableData(static_cast<int>(nLabelLen), pszLabel);
535537

gcore/gdaljp2metadata.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,7 +3333,7 @@ GDALJP2Metadata::CreateGDALMultiDomainMetadataXMLBox(GDALDataset *poSrcDS,
33333333

33343334
GDALJP2Box *poBox = new GDALJP2Box();
33353335
poBox->SetType("xml ");
3336-
poBox->SetWritableData(static_cast<int>(strlen(pszXML) + 1),
3336+
poBox->SetWritableData(static_cast<int>(strlen(pszXML)),
33373337
reinterpret_cast<const GByte *>(pszXML));
33383338
CPLFree(pszXML);
33393339

@@ -3362,7 +3362,7 @@ GDALJP2Box **GDALJP2Metadata::CreateXMLBoxes(GDALDataset *poSrcDS, int *pnBoxes)
33623362
GDALJP2Box *poBox = new GDALJP2Box();
33633363
poBox->SetType("xml ");
33643364
poBox->SetWritableData(
3365-
static_cast<int>(strlen(*papszSrcMD) + 1),
3365+
static_cast<int>(strlen(*papszSrcMD)),
33663366
reinterpret_cast<const GByte *>(*papszSrcMD));
33673367
papoBoxes = static_cast<GDALJP2Box **>(CPLRealloc(
33683368
papoBoxes, sizeof(GDALJP2Box *) * (*pnBoxes + 1)));
@@ -3385,7 +3385,7 @@ GDALJP2Box *GDALJP2Metadata::CreateXMPBox(GDALDataset *poSrcDS)
33853385
if (papszSrcMD && *papszSrcMD)
33863386
{
33873387
poBox = GDALJP2Box::CreateUUIDBox(
3388-
xmp_uuid, static_cast<int>(strlen(*papszSrcMD) + 1),
3388+
xmp_uuid, static_cast<int>(strlen(*papszSrcMD)),
33893389
reinterpret_cast<const GByte *>(*papszSrcMD));
33903390
}
33913391
return poBox;
@@ -3403,7 +3403,7 @@ GDALJP2Box *GDALJP2Metadata::CreateIPRBox(GDALDataset *poSrcDS)
34033403
{
34043404
poBox = new GDALJP2Box();
34053405
poBox->SetType("jp2i");
3406-
poBox->SetWritableData(static_cast<int>(strlen(*papszSrcMD) + 1),
3406+
poBox->SetWritableData(static_cast<int>(strlen(*papszSrcMD)),
34073407
reinterpret_cast<const GByte *>(*papszSrcMD));
34083408
}
34093409
return poBox;

0 commit comments

Comments
 (0)