diff --git a/recog/src/test/java/com/rapid7/recog/parser/FingerprintMatcherParserTest.java b/recog/src/test/java/com/rapid7/recog/parser/FingerprintMatcherParserTest.java index 6cebbf7..733e96f 100644 --- a/recog/src/test/java/com/rapid7/recog/parser/FingerprintMatcherParserTest.java +++ b/recog/src/test/java/com/rapid7/recog/parser/FingerprintMatcherParserTest.java @@ -7,6 +7,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Base64; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -20,6 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; +import static org.hamcrest.core.StringStartsWith.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -106,6 +108,34 @@ public void twoValidFingerprints() throws ParseException { new RecogMatcher(pattern("^Apache$", DOTALL, MULTILINE)).addValue("service.vendor", "Apache").addValue("service.product", "HTTPD").addValue("service.family", "Apache"))); } + @Test + public void validFingerprintBase64EncodedExample() throws ParseException { + // given + int exServiceVersion = 1; + String exText = String.format("Apache %d", exServiceVersion); + String exBase64 = Base64.getEncoder().encodeToString(exText.getBytes(StandardCharsets.US_ASCII)); + String xml = String.format("\n" + + "" + + " \n" + + " Apache returning only its major version number\n" + + " %s\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "", exServiceVersion, exBase64); + + // when + RecogMatchers patterns = new RecogParser().parse(new StringReader(xml), anyString()); + + // then + assertThat(patterns.size(), is(1)); + assertThat(patterns, hasItems(new RecogMatcher(pattern("^Apache (\\d)$")).addValue("service.vendor", "Apache").addValue("service.product", "HTTPD").addValue("service.family", "Apache").addParam(1, "service.version"))); + assertThat(patterns.get(0).getExamples().size(), is(1)); + assertThat(patterns.get(0).getExamples(), contains(hasProperty("text", is(exText)))); + } + @Test public void validFingerprintExternalExampleFile() throws ParseException { // given @@ -323,6 +353,35 @@ public void paramNonZeroPositionWithValueFailsWhenStrict() { assertEquals(expectedMessage, exception.getMessage()); } + @Test + public void invalidFingerprintBase64EncodedExampleFailsWhenStrict() { + // given + int exServiceVersion = 1; + String exText = String.format("Apache %d", exServiceVersion); + String exBase64 = Base64.getEncoder().encodeToString(exText.getBytes(StandardCharsets.US_ASCII)); + String badExBase64 = String.format("%s!", exBase64); + String xml = String.format("\n" + + "" + + " \n" + + " Apache returning only its major version number\n" + + " %s\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "", exServiceVersion, badExBase64); + String expectedMessageStart = "Input byte array has incorrect ending byte at"; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + new RecogParser(true).parse(new StringReader(xml), anyString()); + }); + + // then + assertThat(exception.getMessage(), startsWith(expectedMessageStart)); + } + @Test public void missingExternalExampleFileFailsWhenStrict() { // given