5 Commits
Author SHA1 Message Date
Enrique Zamudio 3c17b05bbc 1.10.2 2014-12-04 10:30:03 -06:00
Enrique Zamudio 3e3fbaa3fa fix #26 2014-12-04 10:27:55 -06:00
Enrique Zamudio ba486239bd fix #27 2014-12-04 10:27:28 -06:00
Enrique Zamudio c57ad2c5ee fix #31 2014-11-28 12:06:07 -06:00
Enrique Zamudio 6b7ec73e92 mark length final for #31 2014-11-28 11:49:50 -06:00
7 changed files with 77 additions and 60 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
apply plugin:'java'
apply plugin: 'maven'
defaultTasks 'build'
version='1.10.1'
version='1.10.2'
description='Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.'
sourceCompatibility=6
targetCompatibility=6
@@ -17,9 +17,9 @@ configurations {
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.6'
compile 'org.slf4j:slf4j-api:1.7.7'
testCompile 'junit:junit:4.11'
testRuntime 'org.slf4j:slf4j-simple:1.7.6'
testRuntime 'org.slf4j:slf4j-simple:1.7.7'
}
tasks.javadoc.options.use=true
@@ -34,7 +34,7 @@ task sourcesJar(type:Jar) {
classifier='sources'
}
tasks.withType(Compile) { Compile compile ->
tasks.withType(AbstractCompile) { AbstractCompile compile ->
compile.options.debug = true
compile.options.compilerArgs = ['-Xlint:all']
}
@@ -496,4 +496,10 @@ public class IsoMessage {
}
}
/** Remove the specified fields from the message. */
public void removeFields(int... idx) {
for (int i : idx) {
setField(i, null);
}
}
}
@@ -32,7 +32,7 @@ import com.solab.iso8583.IsoValue;
public abstract class FieldParseInfo {
protected IsoType type;
protected int length;
protected final int length;
private String encoding = System.getProperty("file.encoding");
protected boolean forceStringDecoding;
private CustomField<?> decoder;
@@ -137,7 +137,7 @@ public abstract class FieldParseInfo {
protected int decodeLength(byte[] buf, int pos, int digits) throws UnsupportedEncodingException {
if (forceStringDecoding) {
return Integer.parseInt(new String(buf, pos, digits, encoding));
return Integer.parseInt(new String(buf, pos, digits, encoding), 10);
} else if (digits == 3) {
return ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
} else {
@@ -49,22 +49,23 @@ public class LlbinParseInfo extends FieldParseInfo {
throw new ParseException(String.format("Insufficient LLBIN header field %d",
field), pos);
}
length = decodeLength(buf, pos, 2);
if (length < 0) {
final int len = decodeLength(buf, pos, 2);
if (len < 0) {
throw new ParseException(String.format("Invalid LLBIN field %d length %d pos %d",
field, length, pos), pos);
field, len, pos), pos);
}
if (length+pos+2 > buf.length) {
if (len+pos+2 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for LLBIN field %d, pos %d (LEN states '%s')",
field, pos, new String(buf, pos, 2)), pos);
}
byte[] binval = length == 0 ? new byte[0] : HexCodec.hexDecode(new String(buf, pos + 2, length));
byte[] binval = len == 0 ? new byte[0] : HexCodec.hexDecode(
new String(buf, pos + 2, len));
if (custom == null) {
return new IsoValue<byte[]>(type, binval, binval.length, null);
} else if (custom instanceof CustomBinaryField) {
try {
T dec = ((CustomBinaryField<T>)custom).decodeBinaryField(buf, pos + 2, length);
T dec = ((CustomBinaryField<T>)custom).decodeBinaryField(buf, pos + 2, len);
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
new IsoValue<T>(type, dec, 0, custom);
} catch (IndexOutOfBoundsException ex) {
@@ -74,7 +75,7 @@ public class LlbinParseInfo extends FieldParseInfo {
}
} else {
try {
T dec = custom.decodeField(new String(buf, pos + 2, length));
T dec = custom.decodeField(new String(buf, pos + 2, len));
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
new IsoValue<T>(type, dec, binval.length, custom);
} catch (IndexOutOfBoundsException ex) {
@@ -98,7 +99,7 @@ public class LlbinParseInfo extends FieldParseInfo {
}
final int l = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
if (l < 0) {
throw new ParseException(String.format("Invalid bin LLBIN length %d pos %d", length, pos), pos);
throw new ParseException(String.format("Invalid bin LLBIN length %d pos %d", l, pos), pos);
}
if (l+pos+1 > buf.length) {
throw new ParseException(String.format(
@@ -46,34 +46,35 @@ public class LllvarParseInfo extends FieldParseInfo {
throw new ParseException(String.format(
"Insufficient data for LLLVAR header field %d pos %d", field, pos), pos);
}
length = decodeLength(buf, pos, 3);
if (length < 0) {
final int len = decodeLength(buf, pos, 3);
if (len < 0) {
throw new ParseException(String.format("Invalid LLLVAR length %d field %d pos %d",
length, field, pos), pos);
} else if (length+pos+3 > buf.length) {
len, field, pos), pos);
} else if (len+pos+3 > buf.length) {
throw new ParseException(String.format("Insufficient data for LLLVAR field %d, pos %d",
field, pos), pos);
}
String _v;
try {
_v = length == 0 ? "" : new String(buf, pos + 3, length, getCharacterEncoding());
_v = len == 0 ? "" : new String(buf, pos + 3, len, getCharacterEncoding());
} catch (IndexOutOfBoundsException ex) {
throw new ParseException(String.format(
"Insufficient data for LLLVAR header, field %d pos %d", field, pos), pos);
}
//This is new: if the String's length is different from the specified length in the buffer,
//there are probably some extended characters. So we create a String from the rest of the buffer,
//and then cut it to the specified length.
if (_v.length() != length) {
_v = new String(buf, pos + 3, buf.length-pos-3, getCharacterEncoding()).substring(0, length);
//This is new: if the String's length is different from the specified length in the
//buffer, there are probably some extended characters. So we create a String from
//the rest of the buffer, and then cut it to the specified length.
if (_v.length() != len) {
_v = new String(buf, pos + 3, buf.length-pos-3,
getCharacterEncoding()).substring(0, len);
}
if (custom == null) {
return new IsoValue<String>(type, _v, length, null);
return new IsoValue<String>(type, _v, len, null);
} else {
T decoded = custom.decodeField(_v);
//If decode fails, return string; otherwise use the decoded object and its codec
return decoded == null ? new IsoValue<String>(type, _v, length, null) :
new IsoValue<T>(type, decoded, length, custom);
return decoded == null ? new IsoValue<String>(type, _v, len, null) :
new IsoValue<T>(type, decoded, len, custom);
}
}
@@ -86,20 +87,22 @@ public class LllvarParseInfo extends FieldParseInfo {
throw new ParseException(String.format(
"Insufficient data for bin LLLVAR header, field %d pos %d", field, pos), pos);
}
length = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
if (length < 0) {
final int len = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
if (len < 0) {
throw new ParseException(String.format(
"Invalid bin LLLVAR length %d, field %d pos %d", length, field, pos), pos);
} else if (length+pos+2 > buf.length) {
"Invalid bin LLLVAR length %d, field %d pos %d", len, field, pos), pos);
} else if (len+pos+2 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for bin LLLVAR field %d, pos %d", field, pos), pos);
}
if (custom == null) {
return new IsoValue<String>(type, new String(buf, pos + 2, length, getCharacterEncoding()), null);
return new IsoValue<String>(type, new String(buf, pos + 2, len, getCharacterEncoding()), null);
} else {
IsoValue<T> v = new IsoValue<T>(type, custom.decodeField(new String(buf, pos + 2, length, getCharacterEncoding())), custom);
IsoValue<T> v = new IsoValue<T>(type, custom.decodeField(
new String(buf, pos + 2, len, getCharacterEncoding())), custom);
if (v.getValue() == null) {
return new IsoValue<String>(type, new String(buf, pos + 2, length, getCharacterEncoding()), null);
return new IsoValue<String>(type,
new String(buf, pos + 2, len, getCharacterEncoding()), null);
}
return v;
}
@@ -40,37 +40,41 @@ public class LlvarParseInfo extends FieldParseInfo {
final int pos, final CustomField<T> custom)
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid LLVAR field %d %d", field, pos), pos);
} else if (pos+2 > buf.length) {
throw new ParseException(String.format("Insufficient data for LLVAR header, pos %d", pos), pos);
}
length = decodeLength(buf, pos, 2);
if (length < 0) {
throw new ParseException(String.format(
"Invalid LLVAR length %d, field %d pos %d", length, field, pos), pos);
} else if (length+pos+2 > buf.length) {
"Invalid LLVAR field %d %d", field, pos), pos);
} else if (pos+2 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for LLVAR header, pos %d", pos), pos);
}
final int len = decodeLength(buf, pos, 2);
if (len < 0) {
throw new ParseException(String.format(
"Invalid LLVAR length %d, field %d pos %d", len, field, pos), pos);
} else if (len+pos+2 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for LLVAR field %d, pos %d", field, pos), pos);
}
String _v;
try {
_v = length == 0 ? "" : new String(buf, pos + 2, length, getCharacterEncoding());
_v = len == 0 ? "" : new String(buf, pos + 2, len, getCharacterEncoding());
} catch (IndexOutOfBoundsException ex) {
throw new ParseException(String.format(
"Insufficient data for LLVAR header, field %d pos %d", field, pos), pos);
}
//This is new: if the String's length is different from the specified length in the buffer,
//there are probably some extended characters. So we create a String from the rest of the buffer,
//and then cut it to the specified length.
if (_v.length() != length) {
_v = new String(buf, pos + 2, buf.length-pos-2, getCharacterEncoding()).substring(0, length);
//This is new: if the String's length is different from the specified
// length in the buffer, there are probably some extended characters.
// So we create a String from the rest of the buffer, and then cut it to
// the specified length.
if (_v.length() != len) {
_v = new String(buf, pos + 2, buf.length-pos-2,
getCharacterEncoding()).substring(0, len);
}
if (custom == null) {
return new IsoValue<String>(type, _v, length, null);
return new IsoValue<String>(type, _v, len, null);
} else {
T dec = custom.decodeField(_v);
return dec == null ? new IsoValue<String>(type, _v, length, null) :
new IsoValue<T>(type, dec, length, custom);
return dec == null ? new IsoValue<String>(type, _v, len, null) :
new IsoValue<T>(type, dec, len, custom);
}
}
@@ -83,22 +87,25 @@ public class LlvarParseInfo extends FieldParseInfo {
field, pos), pos);
} else if (pos+1 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for bin LLVAR header, field %d pos %d", field, pos), pos);
"Insufficient data for bin LLVAR header, field %d pos %d",
field, pos), pos);
}
length = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
if (length < 0) {
final int len = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
if (len < 0) {
throw new ParseException(String.format(
"Invalid bin LLVAR length %d, field %d pos %d", length, field, pos), pos);
"Invalid bin LLVAR length %d, field %d pos %d", len, field, pos), pos);
}
if (length+pos+1 > buf.length) {
if (len+pos+1 > buf.length) {
throw new ParseException(String.format(
"Insufficient data for bin LLVAR field %d, pos %d", field, pos), pos);
}
if (custom == null) {
return new IsoValue<String>(type, new String(buf, pos + 1, length, getCharacterEncoding()), null);
return new IsoValue<String>(type, new String(buf, pos + 1, len,
getCharacterEncoding()), null);
} else {
T dec = custom.decodeField(new String(buf, pos + 1, length, getCharacterEncoding()));
return dec == null ? new IsoValue<String>(type, new String(buf, pos + 1, length, getCharacterEncoding()), null) :
T dec = custom.decodeField(new String(buf, pos + 1, len, getCharacterEncoding()));
return dec == null ? new IsoValue<String>(type,
new String(buf, pos + 1, len, getCharacterEncoding()), null) :
new IsoValue<T>(type, dec, custom);
}
}
@@ -8,7 +8,7 @@
<!ATTLIST template type NMTOKEN #REQUIRED >
<!ATTLIST template extends NMTOKEN #IMPLIED >
<!ELEMENT parse ( field+ ) >
<!ELEMENT parse ( field* ) >
<!ATTLIST parse type NMTOKEN #REQUIRED >
<!ATTLIST parse extends NMTOKEN #IMPLIED >