Skip to content

Commit fd990bf

Browse files
authored
Merge pull request #83 from plokhotnyuk/master
Fix of unexpected MatchError in case of invalid escape character
2 parents c424ee6 + af382ec commit fd990bf

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

commons-core/src/main/scala/com/avsystem/commons/serialization/json/JsonStringInput.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,15 +298,15 @@ final class JsonReader(val json: String) {
298298
case 'r' => '\r'
299299
case 't' => '\t'
300300
case 'u' => ((readHex() << 12) + (readHex() << 8) + (readHex() << 4) + readHex()).toChar
301+
case c => throw new ReadFailure(s"Unexpected character: '${c.toChar}'")
301302
}
302303
sb.append(unesc)
303304
plainStart = i
304305
case _ =>
305306
}
306307
}
307308
if (sb != null) {
308-
sb.append(json, plainStart, i - 1)
309-
sb.toString
309+
sb.append(json, plainStart, i - 1).toString
310310
} else {
311311
json.substring(plainStart, i - 1)
312312
}

commons-core/src/main/scala/com/avsystem/commons/serialization/json/JsonStringOutput.scala

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,33 @@ trait BaseJsonOutput {
2323
var i = 0
2424
var s = 0
2525
while (i < str.length) {
26-
val esc = str.charAt(i) match {
27-
case '"' => "\\\""
28-
case '\\' => "\\\\"
29-
case '\b' => "\\b"
30-
case '\f' => "\\f"
31-
case '\n' => "\\n"
32-
case '\r' => "\\r"
33-
case '\t' => "\\t"
34-
case c if (ascii && c.toInt > 127) || Character.isISOControl(c) =>
35-
c.toInt.formatted("\\u%04x")
36-
case _ => null
26+
val ch = str.charAt(i)
27+
val esc = ch match {
28+
case '"' => '"'
29+
case '\\' => '\\'
30+
case '\b' => 'b'
31+
case '\f' => 'f'
32+
case '\n' => 'n'
33+
case '\r' => 'r'
34+
case '\t' => 't'
35+
case _ => (if ((ascii && ch.toInt > 127) || Character.isISOControl(ch)) 1 else 0).toChar
3736
}
38-
if (esc != null) {
39-
builder.append(str, s, i).append(esc)
37+
if (esc != 0) {
38+
builder.append(str, s, i).append('\\')
4039
s = i + 1
40+
if (esc != 1) {
41+
builder.append(esc)
42+
} else {
43+
builder.append('u').append(toHex((ch >> 12) & 15)).append(toHex((ch >> 8) & 15))
44+
.append(toHex((ch >> 4) & 15)).append(toHex(ch & 15))
45+
}
4146
}
4247
i += 1
4348
}
44-
builder.append(str, s, str.length)
45-
builder.append('"')
49+
builder.append(str, s, str.length).append('"')
4650
}
51+
52+
protected final def toHex(nibble: Int): Char = (nibble + (if (nibble >= 10) 'a' - 10 else '0')).toChar
4753
}
4854

4955
final class JsonStringOutput(builder: JStringBuilder, options: JsonOptions = JsonOptions.Default, depth: Int = 0)

commons-core/src/test/scala/com/avsystem/commons/serialization/json/JsonStringInputOutputTest.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class JsonStringInputOutputTest extends FunSuite with SerializationTestUtils wit
110110
val options = JsonOptions(asciiOutput = true)
111111
assert(write[String]("ąę", options) == "\"\\u0105\\u0119\"")
112112
assert(read[String]("\"\\u0105\\u0119\"", options) == "ąę")
113+
intercept[ReadFailure](read[String]("\"\\x0105\""))
113114
}
114115

115116
test("indentation") {

version.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version in ThisBuild := "1.29.1"
1+
version in ThisBuild := "1.29.2-SNAPSHOT"

0 commit comments

Comments
 (0)