Skip to content

Commit

Permalink
Merge pull request #168 from xlate/167_premature_unb_term_fix
Browse files Browse the repository at this point in the history
Fix handling of UNB terminated prematurely
  • Loading branch information
MikeEdgar committed Jan 23, 2021
2 parents 5e79193 + 2ae2e89 commit a3c58c0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ private void write(int output) throws EDIStreamException {
case HEADER_DATA:
case HEADER_ELEMENT_END:
case HEADER_COMPONENT_END:
case HEADER_SEGMENT_END:
writeHeader((char) output);
break;
case INVALID:
Expand Down Expand Up @@ -353,6 +354,9 @@ void writeHeader(char output) throws EDIStreamException {
case HEADER_COMPONENT_END:
state = State.COMPONENT_END;
break;
case HEADER_SEGMENT_END:
state = State.SEGMENT_END;
break;
default:
throw new IllegalStateException("Confirmed at state " + state);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public class EDIFACTDialect extends Dialect {
public static final String UNA = "UNA";
public static final String UNB = "UNB";

private static final String[] EMPTY = new String[0];

static final char DFLT_SEGMENT_TERMINATOR = '\'';
static final char DFLT_DATA_ELEMENT_SEPARATOR = '+';
static final char DFLT_COMPONENT_ELEMENT_SEPARATOR = ':';
Expand Down Expand Up @@ -109,21 +107,32 @@ boolean initialize(CharacterSet characters) {
}

private String[] parseVersion() {
int versionStart = findVersionStart();
int versionEnd = header.indexOf(String.valueOf(elementDelimiter), versionStart);
final int versionStart = findVersionStart();
String versionComposite = findVersionString(versionStart, elementDelimiter);

if (versionEnd - versionStart > 1) {
return header.substring(versionStart, versionEnd).split('\\' + String.valueOf(componentDelimiter));
if (versionComposite == null) {
// Handle the case where the segment was terminated prematurely (zero or one element)
versionComposite = findVersionString(versionStart, segmentDelimiter);
}

return EMPTY;
return versionComposite.split('\\' + String.valueOf(componentDelimiter));
}

int findVersionStart() {
// Skip four characters: UNB<delim>
return UNB.equals(headerTag) ? 4 : unbStart + 4;
}

String findVersionString(int versionStart, char delimiter) {
final int versionEnd = header.indexOf(String.valueOf(delimiter), versionStart);

if (versionEnd - versionStart > -1) {
return header.substring(versionStart, versionEnd);
}

return null;
}

@Override
public boolean isServiceAdviceSegment(CharSequence tag) {
return UNA.contentEquals(tag);
Expand Down Expand Up @@ -214,7 +223,7 @@ boolean processServiceStringAdvice(CharacterSet characters, char value) {
if (characters.isIgnored(value)) {
header.deleteCharAt(index--);
} else if (isIndexBeyondUNBFirstElement()) {
if (value == elementDelimiter) {
if (value == elementDelimiter || value == segmentDelimiter) {
rejected = !initialize(characters);
proceed = isConfirmed();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2094,4 +2094,27 @@ void testEscapeCharEscaped() throws IOException, EDIStreamException {

assertEquals("UNB+UNO1:1++++'ISA+??????'", new String(stream.toByteArray()));
}

@Test
void testIncompleteUNB() throws IOException, EDIStreamException, EDISchemaException {
final EDIOutputFactory factory = EDIOutputFactory.newFactory();
ByteArrayOutputStream stream = new ByteArrayOutputStream(4096);

try (EDIStreamWriter writer = factory.createEDIStreamWriter(stream)) {
writer.startInterchange();
writer.writeStartSegment("UNA")
.writeEndSegment();
writer.writeStartSegment("UNB")
.writeStartElement()
.writeComponent("UNOA")
.writeComponent("3")
.endElement()
.writeEndSegment();

writer.writeStartSegment("UNH");
writer.flush();
}

assertEquals("UNA:+.? 'UNB+UNOA:3'UNH", new String(stream.toByteArray()));
}
}

0 comments on commit a3c58c0

Please sign in to comment.