Possible fix for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38197 ; refactor FieldParser data impl

This commit is contained in:
Sean Owen 2021-09-06 20:43:18 -05:00
parent 8761b26a50
commit 0235f355ff

View file

@ -28,164 +28,106 @@ package com.google.zxing.oned.rss.expanded.decoders;
import com.google.zxing.NotFoundException; import com.google.zxing.NotFoundException;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/ */
final class FieldParser { final class FieldParser {
private static final Object VARIABLE_LENGTH = new Object(); private static final Map<String,DataLength> TWO_DIGIT_DATA_LENGTH = new HashMap<>();
static {
private static final Object [][] TWO_DIGIT_DATA_LENGTH = { TWO_DIGIT_DATA_LENGTH.put("00", DataLength.fixed(18));
// "DIGITS", new Integer(LENGTH) TWO_DIGIT_DATA_LENGTH.put("01", DataLength.fixed(14));
// or TWO_DIGIT_DATA_LENGTH.put("02", DataLength.fixed(14));
// "DIGITS", VARIABLE_LENGTH, new Integer(MAX_SIZE) TWO_DIGIT_DATA_LENGTH.put("10", DataLength.variable(20));
TWO_DIGIT_DATA_LENGTH.put("11", DataLength.fixed(6));
{ "00", 18}, TWO_DIGIT_DATA_LENGTH.put("12", DataLength.fixed(6));
{ "01", 14}, TWO_DIGIT_DATA_LENGTH.put("13", DataLength.fixed(6));
{ "02", 14}, TWO_DIGIT_DATA_LENGTH.put("15", DataLength.fixed(6));
TWO_DIGIT_DATA_LENGTH.put("17", DataLength.fixed(6));
{ "10", VARIABLE_LENGTH, 20}, TWO_DIGIT_DATA_LENGTH.put("20", DataLength.fixed(2));
{ "11", 6}, TWO_DIGIT_DATA_LENGTH.put("21", DataLength.variable(20));
{ "12", 6}, TWO_DIGIT_DATA_LENGTH.put("22", DataLength.variable(29));
{ "13", 6}, TWO_DIGIT_DATA_LENGTH.put("30", DataLength.variable(8));
{ "15", 6}, TWO_DIGIT_DATA_LENGTH.put("37", DataLength.variable(8));
{ "17", 6},
{ "20", 2},
{ "21", VARIABLE_LENGTH, 20},
{ "22", VARIABLE_LENGTH, 29},
{ "30", VARIABLE_LENGTH, 8},
{ "37", VARIABLE_LENGTH, 8},
//internal company codes //internal company codes
{ "90", VARIABLE_LENGTH, 30}, for (int i = 90; i <= 99; i++) {
{ "91", VARIABLE_LENGTH, 30}, TWO_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.variable(30));
{ "92", VARIABLE_LENGTH, 30}, }
{ "93", VARIABLE_LENGTH, 30}, }
{ "94", VARIABLE_LENGTH, 30},
{ "95", VARIABLE_LENGTH, 30},
{ "96", VARIABLE_LENGTH, 30},
{ "97", VARIABLE_LENGTH, 30},
{ "98", VARIABLE_LENGTH, 30},
{ "99", VARIABLE_LENGTH, 30},
};
private static final Object [][] THREE_DIGIT_DATA_LENGTH = { private static final Map<String,DataLength> THREE_DIGIT_DATA_LENGTH = new HashMap<>();
// Same format as above static {
THREE_DIGIT_DATA_LENGTH.put("240", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("241", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("242", DataLength.variable(6));
THREE_DIGIT_DATA_LENGTH.put("250", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("251", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("253", DataLength.variable(17));
THREE_DIGIT_DATA_LENGTH.put("254", DataLength.variable(20));
THREE_DIGIT_DATA_LENGTH.put("400", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("401", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("402", DataLength.fixed(17));
THREE_DIGIT_DATA_LENGTH.put("403", DataLength.variable(30));
THREE_DIGIT_DATA_LENGTH.put("410", DataLength.fixed(13));
THREE_DIGIT_DATA_LENGTH.put("411", DataLength.fixed(13));
THREE_DIGIT_DATA_LENGTH.put("412", DataLength.fixed(13));
THREE_DIGIT_DATA_LENGTH.put("413", DataLength.fixed(13));
THREE_DIGIT_DATA_LENGTH.put("414", DataLength.fixed(13));
THREE_DIGIT_DATA_LENGTH.put("420", DataLength.variable(20));
THREE_DIGIT_DATA_LENGTH.put("421", DataLength.variable(15));
THREE_DIGIT_DATA_LENGTH.put("422", DataLength.fixed(3));
THREE_DIGIT_DATA_LENGTH.put("423", DataLength.variable(15));
THREE_DIGIT_DATA_LENGTH.put("424", DataLength.fixed(3));
THREE_DIGIT_DATA_LENGTH.put("425", DataLength.fixed(3));
THREE_DIGIT_DATA_LENGTH.put("426", DataLength.fixed(3));
}
{ "240", VARIABLE_LENGTH, 30}, private static final Map<String,DataLength> THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = new HashMap<>();
{ "241", VARIABLE_LENGTH, 30}, static {
{ "242", VARIABLE_LENGTH, 6}, for (int i = 310; i <= 316; i++) {
{ "250", VARIABLE_LENGTH, 30}, THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
{ "251", VARIABLE_LENGTH, 30}, }
{ "253", VARIABLE_LENGTH, 17}, for (int i = 320; i <= 336; i++) {
{ "254", VARIABLE_LENGTH, 20}, THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
}
for (int i = 340; i <= 357; i++) {
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
}
for (int i = 360; i <= 369; i++) {
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
}
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("390", DataLength.variable(15));
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("391", DataLength.variable(18));
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("392", DataLength.variable(15));
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("393", DataLength.variable(18));
THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("703", DataLength.variable(30));
}
{ "400", VARIABLE_LENGTH, 30}, private static final Map<String,DataLength> FOUR_DIGIT_DATA_LENGTH = new HashMap<>();
{ "401", VARIABLE_LENGTH, 30}, static {
{ "402", 17}, FOUR_DIGIT_DATA_LENGTH.put("7001", DataLength.fixed(13));
{ "403", VARIABLE_LENGTH, 30}, FOUR_DIGIT_DATA_LENGTH.put("7002", DataLength.variable(30));
{ "410", 13}, FOUR_DIGIT_DATA_LENGTH.put("7003", DataLength.fixed(10));
{ "411", 13}, FOUR_DIGIT_DATA_LENGTH.put("8001", DataLength.fixed(14));
{ "412", 13}, FOUR_DIGIT_DATA_LENGTH.put("8002", DataLength.variable(20));
{ "413", 13}, FOUR_DIGIT_DATA_LENGTH.put("8003", DataLength.variable(30));
{ "414", 13}, FOUR_DIGIT_DATA_LENGTH.put("8004", DataLength.variable(30));
{ "420", VARIABLE_LENGTH, 20}, FOUR_DIGIT_DATA_LENGTH.put("8005", DataLength.fixed(6));
{ "421", VARIABLE_LENGTH, 15}, FOUR_DIGIT_DATA_LENGTH.put("8006", DataLength.fixed(18));
{ "422", 3}, FOUR_DIGIT_DATA_LENGTH.put("8007", DataLength.variable(30));
{ "423", VARIABLE_LENGTH, 15}, FOUR_DIGIT_DATA_LENGTH.put("8008", DataLength.variable(12));
{ "424", 3}, FOUR_DIGIT_DATA_LENGTH.put("8018", DataLength.fixed(18));
{ "425", 3}, FOUR_DIGIT_DATA_LENGTH.put("8020", DataLength.variable(25));
{ "426", 3}, FOUR_DIGIT_DATA_LENGTH.put("8100", DataLength.fixed(6));
}; FOUR_DIGIT_DATA_LENGTH.put("8101", DataLength.fixed(10));
FOUR_DIGIT_DATA_LENGTH.put("8102", DataLength.fixed(2));
private static final Object [][] THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = { FOUR_DIGIT_DATA_LENGTH.put("8110", DataLength.variable(70));
// Same format as above FOUR_DIGIT_DATA_LENGTH.put("8200", DataLength.variable(70));
}
{ "310", 6},
{ "311", 6},
{ "312", 6},
{ "313", 6},
{ "314", 6},
{ "315", 6},
{ "316", 6},
{ "320", 6},
{ "321", 6},
{ "322", 6},
{ "323", 6},
{ "324", 6},
{ "325", 6},
{ "326", 6},
{ "327", 6},
{ "328", 6},
{ "329", 6},
{ "330", 6},
{ "331", 6},
{ "332", 6},
{ "333", 6},
{ "334", 6},
{ "335", 6},
{ "336", 6},
{ "340", 6},
{ "341", 6},
{ "342", 6},
{ "343", 6},
{ "344", 6},
{ "345", 6},
{ "346", 6},
{ "347", 6},
{ "348", 6},
{ "349", 6},
{ "350", 6},
{ "351", 6},
{ "352", 6},
{ "353", 6},
{ "354", 6},
{ "355", 6},
{ "356", 6},
{ "357", 6},
{ "360", 6},
{ "361", 6},
{ "362", 6},
{ "363", 6},
{ "364", 6},
{ "365", 6},
{ "366", 6},
{ "367", 6},
{ "368", 6},
{ "369", 6},
{ "390", VARIABLE_LENGTH, 15},
{ "391", VARIABLE_LENGTH, 18},
{ "392", VARIABLE_LENGTH, 15},
{ "393", VARIABLE_LENGTH, 18},
{ "703", VARIABLE_LENGTH, 30},
};
private static final Object [][] FOUR_DIGIT_DATA_LENGTH = {
// Same format as above
{ "7001", 13},
{ "7002", VARIABLE_LENGTH, 30},
{ "7003", 10},
{ "8001", 14},
{ "8002", VARIABLE_LENGTH, 20},
{ "8003", VARIABLE_LENGTH, 30},
{ "8004", VARIABLE_LENGTH, 30},
{ "8005", 6},
{ "8006", 18},
{ "8007", VARIABLE_LENGTH, 30},
{ "8008", VARIABLE_LENGTH, 12},
{ "8018", 18},
{ "8020", VARIABLE_LENGTH, 25},
{ "8100", 6},
{ "8101", 10},
{ "8102", 2},
{ "8110", VARIABLE_LENGTH, 70},
{ "8200", VARIABLE_LENGTH, 70},
};
private FieldParser() { private FieldParser() {
} }
@ -201,15 +143,12 @@ final class FieldParser {
throw NotFoundException.getNotFoundInstance(); throw NotFoundException.getNotFoundInstance();
} }
String firstTwoDigits = rawInformation.substring(0, 2); DataLength twoDigitDataLength = TWO_DIGIT_DATA_LENGTH.get(rawInformation.substring(0, 2));
if (twoDigitDataLength != null) {
for (Object[] dataLength : TWO_DIGIT_DATA_LENGTH) { if (twoDigitDataLength.variable) {
if (dataLength[0].equals(firstTwoDigits)) { return processVariableAI(2, twoDigitDataLength.length, rawInformation);
if (dataLength[1] == VARIABLE_LENGTH) {
return processVariableAI(2, (Integer) dataLength[2], rawInformation);
}
return processFixedAI(2, (Integer) dataLength[1], rawInformation);
} }
return processFixedAI(2, twoDigitDataLength.length, rawInformation);
} }
if (rawInformation.length() < 3) { if (rawInformation.length() < 3) {
@ -217,39 +156,32 @@ final class FieldParser {
} }
String firstThreeDigits = rawInformation.substring(0, 3); String firstThreeDigits = rawInformation.substring(0, 3);
DataLength threeDigitDataLength = THREE_DIGIT_DATA_LENGTH.get(firstThreeDigits);
for (Object[] dataLength : THREE_DIGIT_DATA_LENGTH) { if (threeDigitDataLength != null) {
if (dataLength[0].equals(firstThreeDigits)) { if (threeDigitDataLength.variable) {
if (dataLength[1] == VARIABLE_LENGTH) { return processVariableAI(3, threeDigitDataLength.length, rawInformation);
return processVariableAI(3, (Integer) dataLength[2], rawInformation);
}
return processFixedAI(3, (Integer) dataLength[1], rawInformation);
}
}
for (Object[] dataLength : THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH) {
if (dataLength[0].equals(firstThreeDigits)) {
if (dataLength[1] == VARIABLE_LENGTH) {
return processVariableAI(4, (Integer) dataLength[2], rawInformation);
}
return processFixedAI(4, (Integer) dataLength[1], rawInformation);
} }
return processFixedAI(3, threeDigitDataLength.length, rawInformation);
} }
if (rawInformation.length() < 4) { if (rawInformation.length() < 4) {
throw NotFoundException.getNotFoundInstance(); throw NotFoundException.getNotFoundInstance();
} }
String firstFourDigits = rawInformation.substring(0, 4); DataLength threeDigitPlusDigitDataLength = THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.get(firstThreeDigits);
if (threeDigitPlusDigitDataLength != null) {
for (Object[] dataLength : FOUR_DIGIT_DATA_LENGTH) { if (threeDigitPlusDigitDataLength.variable) {
if (dataLength[0].equals(firstFourDigits)) { return processVariableAI(4, threeDigitPlusDigitDataLength.length, rawInformation);
if (dataLength[1] == VARIABLE_LENGTH) {
return processVariableAI(4, (Integer) dataLength[2], rawInformation);
}
return processFixedAI(4, (Integer) dataLength[1], rawInformation);
} }
return processFixedAI(4, threeDigitPlusDigitDataLength.length, rawInformation);
}
DataLength firstFourDigitLength = FOUR_DIGIT_DATA_LENGTH.get(rawInformation.substring(0, 4));
if (firstFourDigitLength != null) {
if (firstFourDigitLength.variable) {
return processVariableAI(4, firstFourDigitLength.length, rawInformation);
}
return processFixedAI(4, firstFourDigitLength.length, rawInformation);
} }
throw NotFoundException.getNotFoundInstance(); throw NotFoundException.getNotFoundInstance();
@ -283,4 +215,25 @@ final class FieldParser {
String parsedAI = parseFieldsInGeneralPurpose(remaining); String parsedAI = parseFieldsInGeneralPurpose(remaining);
return parsedAI == null ? result : result + parsedAI; return parsedAI == null ? result : result + parsedAI;
} }
private static final class DataLength {
final boolean variable;
final int length;
private DataLength(boolean variable, int length) {
this.variable = variable;
this.length = length;
}
static DataLength fixed(int length) {
return new DataLength(false, length);
}
static DataLength variable(int length) {
return new DataLength(true, length);
}
}
} }