From d22671f620878f5bcff857a3a26a9c8c3202574e Mon Sep 17 00:00:00 2001 From: Thomas Heritage Date: Wed, 26 Jun 2024 14:56:10 +0100 Subject: [PATCH] MXF parsing: terminate strings on the first null character Per SMPTE ST 377-1:2019, a "zero value" can be used to terminate a string. So, discard any data after the first null character found (if any). This has the same effect as the implementation for strings in regxmllib at: https://github.com/sandflow/regxmllib/blob/b47b0cdbd6dbf51cae4fb14c3a6a827eb3e0e2cc/src/main/java/com/sandflow/smpte/regxml/FragmentBuilder.java#L902 Note that regxmllib also uses the same `readCharacters` method for MXF properties with a Type of Type Kind "Character", and allows values of this Type to contain the null character. Photon does not support such "Character" Types (and indeed none have ever been used in MXF according to the SMPTE Metadata Registers). So, no consideration is given to these Types in this patch. --- .../imflibrary/MXFPropertyPopulator.java | 9 +++++++-- .../netflix/imflibrary/app/IMPAnalyzerTest.java | 9 +++++++++ .../AUDIO.null_terminated_strings.mxf | Bin 0 -> 20482 bytes 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/IMFTrackFiles/AUDIO.null_terminated_strings.mxf diff --git a/src/main/java/com/netflix/imflibrary/MXFPropertyPopulator.java b/src/main/java/com/netflix/imflibrary/MXFPropertyPopulator.java index b2e02ed2..7806d5dc 100644 --- a/src/main/java/com/netflix/imflibrary/MXFPropertyPopulator.java +++ b/src/main/java/com/netflix/imflibrary/MXFPropertyPopulator.java @@ -253,7 +253,7 @@ else if ((field.getType() == Boolean.class) && (byteArraySize == 1)) } /** - * Getter for a string representing the byte[] + * Getter for a string representing the byte[], terminating on the first null character * * @param byteArray the byte array * @param charset the charset @@ -261,7 +261,12 @@ else if ((field.getType() == Boolean.class) && (byteArraySize == 1)) */ public static String getString(byte[] byteArray, Charset charset) { - return new String(byteArray, charset); + String s = new String(byteArray, charset); + int i = s.indexOf('\u0000'); + if (i == -1) { + return s; + } + return s.substring(0, i); } /** diff --git a/src/test/java/com/netflix/imflibrary/app/IMPAnalyzerTest.java b/src/test/java/com/netflix/imflibrary/app/IMPAnalyzerTest.java index 9425508d..54b8b85d 100644 --- a/src/test/java/com/netflix/imflibrary/app/IMPAnalyzerTest.java +++ b/src/test/java/com/netflix/imflibrary/app/IMPAnalyzerTest.java @@ -214,4 +214,13 @@ public void IMPAnalyzerAnalyzeUnknownFileError() throws IOException } + @Test + public void IMPAnalyzerAnalyzeTrackFileNullTerminatedStrings() throws IOException + { + File inputFile = TestHelper.findResourceByPath("IMFTrackFiles/AUDIO.null_terminated_strings.mxf"); + List errorList = analyzeFile(inputFile); + Assert.assertEquals(errorList.size(), 0); + + } + } diff --git a/src/test/resources/IMFTrackFiles/AUDIO.null_terminated_strings.mxf b/src/test/resources/IMFTrackFiles/AUDIO.null_terminated_strings.mxf new file mode 100644 index 0000000000000000000000000000000000000000..9d25766c8023d4c2b425e0da096625ec973d92d4 GIT binary patch literal 20482 zcmeI4Yitx%6vxjzcDB3FGOYny0n?&_yjR2m&aNAzvH~(UylmF+hxwpe2x? zQJbm>iVq&jLy(t72#6pmL1WZ_uV_RQ!62Z~7y$)@@qg~_Ja*bpO#FDK+3D=rGw1xz z@7}q0J{_Z|_dqqID20luD5_3Nh-Q#N8WGN|9%F9HnlmM>{tTmmn7WdSsfaLqGCjMd zsD>*1+}t4rx%E2uar}~al)VuIM@JPFvecYK4XcU?sbqy53*spu_KD;yAw^ZW2C|$u zY%x{nu-f^2Ock*$!--=kif$ls+=-)x%EO|9xa%XbBX(SI?qVN~9CsD6MPrNZ_d$si zcQvz57z*QIzfY7c1%8XccWHhL1d`=iSTkoYbF;H0gt~gT3Sr?elys`l6-{SglytJQ zg#%NW|1O<1S2-3Q3zL1S+$xxc0vc6rrGgJ)TTT@^>ro2elc(8$Ps-J-WD!!z$)&== zk}2gzMieooY1bzd%T|$g;~=}nUa7oXJX=)vERy-u_z%i>Bv6oS&HES zpEIsS)A`XM`?O~XD+VkvXLOi63(T%N6L@{%qd%{C>*G-}AMIj(-q>|$#m*z<{G#{z zth7`r2%l(IP!hiScPoSmq*)RFDuw~Tuvt+mMNo#(VuiEX5$3%(Ov~{6GS^SovheSb zA2+^Kux!xM%C441=FcOq+wn=!h$HVz`Re=UKd8QB6_7djQuE@Cl(}*BTbq9?wt98u z+EiD0jFlf?<-vGy=$tn1!^n|jI=17`(Y;F|PmYcoUNvzAx^BncFsv=8lJ2EB^boFf z>P9zFKN^5fjLPXonosxPw{m(gXYUEG5ShE~$=uYhW6g?J59*H`I(}|VJWNqA5PacL zK-bc2nu)j>nncwi(w+F;K$SF*IELo;&#$YL>zd4U1(}qo9>WdqA6&k{9NM_9@7BN8 z?26TtDNu{Y93QiL!|a(&-=v!?cFiYzV7*JQD#yI50DdkQZF zG!!!p`vB7nA5Q6lDy4bG(w;^po#q*vJ5qRZ=IFIGC#MbXyzA(gPUGvpcs@T{2hKK@ zvjzRISh`Ov)@^}R zVv1Xt5y25DRtqtQCiPFM&pNA#|(FTFeWwyOP)z5e#lrn@77Ipq-z`n6T9 zpXjuoR(EfVruVIS{5`wR#%*8aSL6{5`n8oKkEo!Go2iN1nvf8)nMxA_+)4FB>$?DvRMjr}JB z3-)^a(m?$Y0lU0+ov(fttDnc}g9KRpE45Z#%1V!K`es) zJ({weWs>dD7b15g3*GBzG9-FQ7_IjDamEYn(^`&~Q;$=p^WDkP@;@`X((!V;=b^y~ Wat{nd%XMRN*z&KA4!#yzQvU)?+GG;| literal 0 HcmV?d00001