Skip to content

Commit

Permalink
Added ASCII restriction to STR64k validation [25880211]
Browse files Browse the repository at this point in the history
  • Loading branch information
SQUIDwarrior committed Apr 11, 2012
1 parent 32d2e91 commit c041870
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 57 deletions.
87 changes: 55 additions & 32 deletions src/main/java/edu/cmu/sv/arinc838/validation/DataValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,47 @@ public long validateUint32(long value) {
* defined as a string that is a maximum of {@link STR64K_MAX_LENGTH}
* characters.
*
*
* @param value
* The input value
* @return The validated input value
* @throws IllegalArgumentException
* if the input value does not validate.
* @return A {@link List} of {@link Exception}s that detail the errors found
*/
public String validateStr64kBinary(String value) {
public List<Exception> validateStr64kBinary(String value) {
ArrayList<Exception> errors = new ArrayList<Exception>();

if (value == null) {
throw new IllegalArgumentException("The input value cannot be null");
errors.add(new IllegalArgumentException(
"The input value cannot be null"));
} else {

String checked = XmlFormatter.unescapeXmlSpecialChars(value);

try {
checked = checkForNonASCII(checked);
} catch (Exception e) {
errors.add(e);
}

if (checked.length() > STR64K_MAX_LENGTH) {
errors.add(new IllegalArgumentException(
"The input value length of "
+ checked.length()
+ " exceeds the maximum allowed characters of 65535"));
}
}

String checked = XmlFormatter.unescapeXmlSpecialChars(value);
return errors;
}

private String checkForNonASCII(String value) {

Pattern p = Pattern.compile("[^\\p{ASCII}]");
Matcher m = p.matcher(value);

if (checked.length() > STR64K_MAX_LENGTH) {
throw new IllegalArgumentException("The input value length of "
+ checked.length()
+ " exceeds the maximum allowed characters of 65535");
if (m.find()) {
int index = m.start();
char illegal = value.charAt(index);
throw new IllegalArgumentException("Non-ASCII character '"
+ illegal + "' found at index " + index);
}

return value;
Expand All @@ -160,11 +183,8 @@ public List<Exception> validateStr64kXml(String value) {
errors.add(new IllegalAccessException("Str64k cannot be null"));
return errors;
}
try {
validateStr64kBinary(value);
} catch (IllegalArgumentException e) {
errors.add(e);
}

errors.addAll(validateStr64kBinary(value));

try {
checkForEscapedXMLChars(value);
Expand Down Expand Up @@ -246,7 +266,8 @@ public byte[] validateFileFormatVersion(byte[] version) {
"File format version was set to 0x"
+ Converter.bytesToHex(version)
+ ", expected 0x"
+ Converter.bytesToHex(SoftwareDefinitionFileDao.DEFAULT_FILE_FORMAT_VERSION));
+ Converter
.bytesToHex(SoftwareDefinitionFileDao.DEFAULT_FILE_FORMAT_VERSION));
}
return version;
}
Expand Down Expand Up @@ -516,13 +537,13 @@ public List<Exception> validateDataFileName(String fileName) {
.substring(fileName.lastIndexOf(".") + 1);
if (Arrays.asList(INVALID_DATA_FILE_EXTENSIONS).contains(
extension.toLowerCase())) {
errors.add(new IllegalArgumentException(
"File name '" + fileName + "' contained an illegal extension '"
+ extension + "'."));
errors.add(new IllegalArgumentException("File name '"
+ fileName + "' contained an illegal extension '"
+ extension + "'."));
}
} catch (StringIndexOutOfBoundsException e) {
errors.add(new IllegalArgumentException(
"File name '" + fileName + "' must have an extension, e.g. '.bin'"));
errors.add(new IllegalArgumentException("File name '" + fileName
+ "' must have an extension, e.g. '.bin'"));
}

// check file names for bad characters
Expand All @@ -532,9 +553,9 @@ public List<Exception> validateDataFileName(String fileName) {
if (m.find()) {
int index = m.start();
char illegal = name.charAt(index);
errors.add(new IllegalArgumentException(
"File name '" + fileName + "' contained an illegal character '" + illegal
+ "' at index " + index + "."));
errors.add(new IllegalArgumentException("File name '" + fileName
+ "' contained an illegal character '" + illegal
+ "' at index " + index + "."));
}

return errors;
Expand All @@ -553,26 +574,28 @@ public List<Exception> validateDataFileName(String fileName) {
public List<Exception> validateDataFileNamesAreUnique(
List<FileDefinitionDao> fileDefs) {
ArrayList<Exception> errors = new ArrayList<Exception>();
// map of lower case file names to list of actual file names
// map of lower case file names to list of actual file names
Map<String, List<String>> fileNames = new HashMap<String, List<String>>();
for (FileDefinitionDao fileDef : fileDefs) {
List<String> values = fileNames.get(fileDef.getFileName().toLowerCase());
if(values == null) {
List<String> values = fileNames.get(fileDef.getFileName()
.toLowerCase());
if (values == null) {
values = new ArrayList<String>();
fileNames.put(fileDef.getFileName().toLowerCase(), values);
}
values.add(fileDef.getFileName());
}

for(String lowerCaseFileNames: fileNames.keySet()) {
String fileNameList = fileNames.get(lowerCaseFileNames).toString().replaceAll("^\\[|\\]$", "");
for (String lowerCaseFileNames : fileNames.keySet()) {
String fileNameList = fileNames.get(lowerCaseFileNames).toString()
.replaceAll("^\\[|\\]$", "");

if(fileNames.get(lowerCaseFileNames).size() > 1) {
if (fileNames.get(lowerCaseFileNames).size() > 1) {
errors.add(new IllegalArgumentException(
"Duplicate data file names: " + fileNameList + "."));
}
}

return errors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public List<Exception> validateSoftwareDescription(
+ "' or '" + partNumberAsBDF + "'."));
}

// TODO when do we use XML vs. binary validator?
errors.addAll(dataVal.validateStr64kXml(softwareDesc
.getSoftwareTypeDescription()));
try {
Expand All @@ -91,6 +92,7 @@ public List<Exception> validateTargetHardwareDefinitions(
continue;
}
for (String position : thwDef.getPositions()) {
// TODO when do we use XML vs. binary validator?
errors.addAll(dataVal.validateStr64kXml(position));
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/edu/cmu/sv/arinc838/validation/XmlFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class XmlFormatter {
/**
* Returns a string with special XML characters escaped:
* <ol>
* <li>'<' becomes '&lt'</li>
* <li>'>' becomes '&gt'</li>
* <li>'&' becomes '&amp'</li>
* <li>'<' becomes {@literal '&lt'}</li>
* <li>'>' becomes {@literal '&gt'}</li>
* <li>'&' becomes {@literal '&amp'}</li>
* </ol>
* @param value
* @return
Expand All @@ -39,9 +39,9 @@ public static String escapeXmlSpecialChars(String value) {
/**
* Returns a string with escaped special XML characters reverted to plain characters:
* <ol>
* <li>'&lt' becomes '<'</li>
* <li>'&gt' becomes '>'</li>
* <li>'&amp' becomes '&'</li>
* <li>{@literal '&lt'} becomes '<'</li>
* <li>{@literal '&gt'} becomes '>'</li>
* <li>{@literal '&amp'} becomes '&'</li>
* </ol>
* @param value
* @return
Expand Down
52 changes: 33 additions & 19 deletions src/test/java/edu/cmu/sv/arinc838/validation/DataValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.Arrays;
import java.util.List;


import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -57,22 +56,25 @@ public void testValidateUint32OutOfRange() {
@Test
public void testValidateStr64kBinary() {
String inputStr = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789 -_=+`~'\"[]{}\\|;:,./?!@#$%^*()";
assertEquals(inputStr,
new DataValidator().validateStr64kBinary(inputStr));
assertEquals(str64kMax,
new DataValidator().validateStr64kBinary(str64kMax));
assertEquals("", new DataValidator().validateStr64kBinary(""));
assertTrue(new DataValidator().validateStr64kBinary(inputStr).isEmpty());
assertTrue(str64kMax,
new DataValidator().validateStr64kBinary(str64kMax).isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("").isEmpty());

assertEquals("&lt", new DataValidator().validateStr64kBinary("&lt"));
assertEquals("hello&lt",
new DataValidator().validateStr64kBinary("hello&lt"));
assertEquals("&gt", new DataValidator().validateStr64kBinary("&gt"));
assertEquals("&gtthere",
new DataValidator().validateStr64kBinary("&gtthere"));
assertEquals("&amp", new DataValidator().validateStr64kBinary("&amp"));
assertEquals("hello&amp&ampthere",
new DataValidator().validateStr64kBinary("hello&amp&ampthere"));
assertTrue(new DataValidator().validateStr64kBinary("&lt").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("hello&lt")
.isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("&gt").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("&gtthere")
.isEmpty());
assertTrue(new DataValidator().validateStr64kBinary("&amp").isEmpty());
assertTrue(new DataValidator().validateStr64kBinary(
"hello&amp&ampthere").isEmpty());
}

@Test
public void testValidateStr64kBinaryNonASCII() {
assertEquals(1, new DataValidator().validateStr64kBinary("abc" + (char) 255).size());
}

@Test
Expand Down Expand Up @@ -102,6 +104,13 @@ public void testValidateStr64kXml() {
.isEmpty());
}

@Test
public void testValidateStr64kXmlNonASCII() {
assertEquals(1,
new DataValidator().validateStr64kXml("abc" + (char) 255)
.size());
}

@Test
public void testValidateStr64kXmlWithNonEscapedChars() {
assertEquals(
Expand All @@ -128,19 +137,24 @@ public void testValidateStr64kXmlMultipleErrors() {
.size());
}

@Test(expectedExceptions = IllegalArgumentException.class)
@Test
public void testValidateStr64kBinaryTooLarge() {
new DataValidator().validateStr64kBinary(str64kMax + "Y");
assertEquals(1, new DataValidator().validateStr64kBinary(str64kMax + "Y").size());
}

@Test
public void testValidateStr64kBinaryMultipleErrors() {
assertEquals(2, new DataValidator().validateStr64kBinary(str64kMax + (char)255).size());
}

@Test
public void testValidateStr64kXmlNull() {
assertEquals(1, new DataValidator().validateStr64kXml(null).size());
}

@Test(expectedExceptions = IllegalArgumentException.class)
@Test
public void testValidateStr64kBinaryNull() {
new DataValidator().validateStr64kBinary(null);
assertEquals(1, new DataValidator().validateStr64kBinary(null).size());
}

@Test
Expand Down

0 comments on commit c041870

Please sign in to comment.