diff --git a/src/main/java/org/codejive/properties/PropertiesParser.java b/src/main/java/org/codejive/properties/PropertiesParser.java index 8a37551..c1649c5 100644 --- a/src/main/java/org/codejive/properties/PropertiesParser.java +++ b/src/main/java/org/codejive/properties/PropertiesParser.java @@ -272,6 +272,10 @@ private void addChar(int ch) throws IOException { if (ch == '\\') { hasEscapes = true; int ch2 = readChar(); + if (isEof(ch2)) { + // A backslash at the end of the input escapes nothing + return; + } str.append((char) ch2); if (ch2 == 'u') { for (int i = 0; i < 4; i++) { @@ -315,6 +319,9 @@ public static String unescape(String escape) { for (int i = 0; i < escape.length(); i++) { char ch = escape.charAt(i); if (ch == '\\') { + if (i == escape.length() - 1) { + break; + } ch = escape.charAt(++i); switch (ch) { case 't': diff --git a/src/test/java/org/codejive/properties/TestPropertiesParser.java b/src/test/java/org/codejive/properties/TestPropertiesParser.java index f967642..333ae40 100644 --- a/src/test/java/org/codejive/properties/TestPropertiesParser.java +++ b/src/test/java/org/codejive/properties/TestPropertiesParser.java @@ -131,4 +131,16 @@ void testMissingSeparatorAndValueAtEof() throws IOException { new Token(Type.SEPARATOR, ""), new Token(Type.VALUE, "")); } + + @Test + void testBackslashAtEof() throws IOException { + List tokens = + PropertiesParser.tokens(new StringReader("foo=bar\\")).collect(Collectors.toList()); + + assertThat(tokens) + .containsExactly( + new Token(Type.KEY, "foo"), + new Token(Type.SEPARATOR, "="), + new Token(Type.VALUE, "bar\\", "bar")); + } }