From 21eb978d6732714751ffee4c74edb8479260340f Mon Sep 17 00:00:00 2001 From: AlexGeller1 <87009702+AlexGeller1@users.noreply.github.com> Date: Tue, 16 Nov 2021 01:25:31 +0100 Subject: [PATCH] Fix of error in specification ISO/IEC 16022 Second edition Annex P as suggested by Martin Burke of zint (See https://sourceforge.net/p/zint/code/ci/68566fefd2a4623041b0232a5941f8fed1e22018/) (#1459) Quote of Martin's proposed changes to the spec: The algorithm can be salvaged to be at least sound by making those changes, e.g. by adding to step e): "1) If the next character cannot be encoded as X12, switch to ASCII mode and go to step b)." (and renumbering the following sub-steps). Similarly step f): "1) If the next character cannot be encoded as EDIFACT, switch to ASCII mode and go to step b)." --- .../datamatrix/encoder/HighLevelEncoder.java | 20 ++++++++++++++ .../encoder/HighLevelEncodeTestCase.java | 27 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java b/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java index 8ee95ee21..f379188ab 100644 --- a/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java +++ b/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java @@ -193,6 +193,26 @@ public final class HighLevelEncoder { } static int lookAheadTest(CharSequence msg, int startpos, int currentMode) { + int newMode = lookAheadTestIntern(msg, startpos, currentMode); + if (currentMode == X12_ENCODATION && newMode == X12_ENCODATION) { + int endpos = Math.min(startpos + 3, msg.length()); + for (int i = startpos; i < endpos; i++) { + if (!isNativeX12(msg.charAt(i))) { + return ASCII_ENCODATION; + } + } + } else if (currentMode == EDIFACT_ENCODATION && newMode == EDIFACT_ENCODATION) { + int endpos = Math.min(startpos + 4, msg.length()); + for (int i = startpos; i < endpos; i++) { + if (!isNativeEDIFACT(msg.charAt(i))) { + return ASCII_ENCODATION; + } + } + } + return newMode; + } + + static int lookAheadTestIntern(CharSequence msg, int startpos, int currentMode) { if (startpos >= msg.length()) { return currentMode; } diff --git a/core/src/test/java/com/google/zxing/datamatrix/encoder/HighLevelEncodeTestCase.java b/core/src/test/java/com/google/zxing/datamatrix/encoder/HighLevelEncodeTestCase.java index 0cb8d4477..903096ed6 100644 --- a/core/src/test/java/com/google/zxing/datamatrix/encoder/HighLevelEncodeTestCase.java +++ b/core/src/test/java/com/google/zxing/datamatrix/encoder/HighLevelEncodeTestCase.java @@ -353,6 +353,33 @@ public final class HighLevelEncodeTestCase extends Assert { assertEquals("240 168 209 77 4 229 45 196 107 77 21 53 5 12 135 192", visualized); } + @Test + public void testX12AndEDIFACTSpecErrors() { + //X12 encoding error with spec conform float point comparisons in lookAheadTest() + String visualized = encodeHighLevel("AAAAAAAAAAA**\u00FCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + assertEquals("230 89 191 89 191 89 191 89 178 56 114 10 243 177 63 89 191 89 191 89 191 89 191 89 191 89 191 89 " + + "191 89 191 89 191 254 66 129", visualized); + //X12 encoding error with integer comparisons in lookAheadTest() + visualized = encodeHighLevel("AAAAAAAAAAAA0+****AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + assertEquals("238 89 191 89 191 89 191 89 191 254 240 194 186 170 170 160 65 4 16 65 4 16 65 4 16 65 4 16 65 4 " + + "16 65 4 16 65 4 16 65 124 129 167 62 212 107", visualized); + //EDIFACT encoding error with spec conform float point comparisons in lookAheadTest() + visualized = encodeHighLevel("AAAAAAAAAAA++++\u00FCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + assertEquals("230 89 191 89 191 89 191 254 66 66 44 44 44 44 235 125 230 89 191 89 191 89 191 89 191 89 191 89 " + + "191 89 191 89 191 89 191 89 191 254 129 17 167 62 212 107", visualized); + //EDIFACT encoding error with integer comparisons in lookAheadTest() + visualized = encodeHighLevel("++++++++++AAa0 0++++++++++++++++++++++++++++++"); + assertEquals("240 174 186 235 174 186 235 174 176 65 124 98 240 194 12 43 174 186 235 174 186 235 174 186 235 " + + "174 186 235 174 186 235 174 186 235 174 186 235 173 240 129 167 62 212 107", visualized); + visualized = encodeHighLevel("AAAAAAAAAAAA*+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + assertEquals("230 89 191 89 191 89 191 89 191 7 170 64 191 89 191 89 191 89 191 89 191 89 191 89 191 89 191 89 " + + "191 89 191 66", visualized); + visualized = encodeHighLevel("AAAAAAAAAAA*0a0 *AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + assertEquals("230 89 191 89 191 89 191 89 178 56 227 6 228 7 183 89 191 89 191 89 191 89 191 89 191 89 191 89 " + + "191 89 191 89 191 254 66 66", visualized); + + } + private static String encodeHighLevel(String msg) { CharSequence encoded = HighLevelEncoder.encodeHighLevel(msg); //DecodeHighLevel.decode(encoded);