Fix issue 147: FFFD must be printable
diff --git a/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java b/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java
index 732ffc0..6dd40e4 100644
--- a/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java
+++ b/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java
@@ -32,7 +32,7 @@
// NON_PRINTABLE changed from PyYAML: \uFFFD excluded because Java returns
// it in case of data corruption
final static Pattern NON_PRINTABLE = Pattern
- .compile("[^\t\n\r\u0020-\u007E\u0085\u00A0-\uD7FF\uE000-\uFFFC]");
+ .compile("[^\t\n\r\u0020-\u007E\u0085\u00A0-\uD7FF\uE000-\uFFFD]");
private String name;
private final Reader stream;
private int pointer = 0;
@@ -89,7 +89,7 @@
if ((c >= '\u0020' && c <= '\u007E') || c == '\n' || c == '\r' || c == '\t'
|| c == '\u0085' || (c >= '\u00A0' && c <= '\uD7FF')
- || (c >= '\uE000' && c <= '\uFFFC')) {
+ || (c >= '\uE000' && c <= '\uFFFD')) {
continue;
}
diff --git a/src/main/java/org/yaml/snakeyaml/reader/UnicodeReader.java b/src/main/java/org/yaml/snakeyaml/reader/UnicodeReader.java
index 65bfc57..f909b5e 100644
--- a/src/main/java/org/yaml/snakeyaml/reader/UnicodeReader.java
+++ b/src/main/java/org/yaml/snakeyaml/reader/UnicodeReader.java
@@ -43,6 +43,8 @@
import java.io.PushbackInputStream;
import java.io.Reader;
import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
/**
* Generic unicode textreader, which will use BOM mark to identify the encoding
@@ -106,7 +108,9 @@
internalIn.unread(bom, (n - unread), unread);
// Use given encoding
- internalIn2 = new InputStreamReader(internalIn, encoding);
+ CharsetDecoder decoder = encoding.newDecoder().onUnmappableCharacter(
+ CodingErrorAction.REPORT);
+ internalIn2 = new InputStreamReader(internalIn, decoder);
}
public void close() throws IOException {
diff --git a/src/test/java/org/pyyaml/PyReaderTest.java b/src/test/java/org/pyyaml/PyReaderTest.java
index 8e43aba..c5fda02 100644
--- a/src/test/java/org/pyyaml/PyReaderTest.java
+++ b/src/test/java/org/pyyaml/PyReaderTest.java
@@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.InputStream;
+import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.reader.ReaderException;
import org.yaml.snakeyaml.reader.StreamReader;
import org.yaml.snakeyaml.reader.UnicodeReader;
@@ -43,6 +44,8 @@
} catch (ReaderException e) {
assertTrue(e.toString(),
e.toString().contains(" special characters are not allowed"));
+ } catch (YAMLException e) {
+ assertTrue(e.toString(), e.toString().contains("MalformedInputException"));
} finally {
input.close();
}
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue147/PrintableTest.java b/src/test/java/org/yaml/snakeyaml/issues/issue147/PrintableTest.java
index 954f967..922f7e7 100644
--- a/src/test/java/org/yaml/snakeyaml/issues/issue147/PrintableTest.java
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue147/PrintableTest.java
@@ -22,12 +22,8 @@
public class PrintableTest extends TestCase {
// http://code.google.com/p/snakeyaml/issues/detail?id=147
public void testFFFD() {
- try {
- Yaml yaml = new Yaml();
- yaml.load(yaml.dump("\uFFFD"));
- fail(" \uFFFD excluded because Java returns it in case of data corruption");
- } catch (Exception e) {
- assertEquals("special characters are not allowed", e.getMessage());
- }
+ Yaml yaml = new Yaml();
+ String fffd = (String) yaml.load(yaml.dump("\uFFFD"));
+ assertEquals("\uFFFD", fffd);
}
}
\ No newline at end of file
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue68/NonAsciiCharacterTest.java b/src/test/java/org/yaml/snakeyaml/issues/issue68/NonAsciiCharacterTest.java
index a0d081a..0ee98eb 100644
--- a/src/test/java/org/yaml/snakeyaml/issues/issue68/NonAsciiCharacterTest.java
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue68/NonAsciiCharacterTest.java
@@ -21,6 +21,9 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
import java.util.Map;
import junit.framework.TestCase;
@@ -43,11 +46,14 @@
try {
Yaml yaml = new Yaml();
InputStream input = new FileInputStream("src/test/resources/issues/issue68.txt");
- Object text = yaml.load(new InputStreamReader(input, "Cp1252"));
+ CharsetDecoder decoder = Charset.forName("Cp1252").newDecoder();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ Object text = yaml.load(new InputStreamReader(input, decoder));
input.close();
fail("Invalid UTF-8 must not be accepted: " + text.toString());
} catch (Exception e) {
- assertEquals("special characters are not allowed", e.getMessage());
+ assertEquals("java.nio.charset.UnmappableCharacterException: Input length = 1",
+ e.getMessage());
}
}