Skip to content

Commit

Permalink
Workaround for German characters encoded in Latin-1 as Unicode code p…
Browse files Browse the repository at this point in the history
…oint in JSON strings
  • Loading branch information
zargony committed Jan 22, 2025
1 parent 8d294c5 commit 6e4b8cf
Showing 1 changed file with 35 additions and 3 deletions.
38 changes: 35 additions & 3 deletions firmware/src/json/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,30 @@ impl<R: BufRead> Reader<R> {
// guarantees that no character encoding is a substring of any other character
b'\\' => {
self.consume();
let ch = self.peek().await?;
buf.push(ch);
self.consume();
// Parse escape sequence
match self.peek().await? {
// Quick and dirty Latin-1 as Unicode code point hack for German characters
// FIXME: Replace with proper character decoding
b'u' => {
self.consume();
let hex: [u8; 4] = self.read_exact().await?;
match const_hex::decode_to_array(hex) {
Ok([0x00, 0xc4]) => buf.extend("Ä".bytes()),
Ok([0x00, 0xd6]) => buf.extend("Ö".bytes()),
Ok([0x00, 0xdc]) => buf.extend("Ü".bytes()),
Ok([0x00, 0xe5]) => buf.extend("ä".bytes()),
Ok([0x00, 0xf6]) => buf.extend("ö".bytes()),
Ok([0x00, 0xfc]) => buf.extend("ü".bytes()),
Ok(_) => buf.push(b'?'),
Err(_) => return Err(Error::InvalidType),
}
}
// Take any other character literally
ch => {
buf.push(ch);
self.consume();
}
}
}
b'"' => {
self.consume();
Expand Down Expand Up @@ -399,6 +420,16 @@ impl<R: BufRead> Reader<R> {
}
}
}

/// Read exact number of characters
async fn read_exact<const N: usize>(&mut self) -> Result<[u8; N], Error<R::Error>> {
let mut s = [0; N];
for ch in &mut s {
*ch = self.peek().await?;
self.consume();
}
Ok(s)
}
}

/// Deserialize from streaming JSON
Expand Down Expand Up @@ -691,6 +722,7 @@ mod tests {
read_string,
Ok("hello \"world\"".into())
);
assert_read_eq!(r#""h\u00eall\u00f6""#, read_string, Ok("h?llö".into()));
assert_read_eq!("\"hello", read_string, Err(Error::Eof));
}

Expand Down

0 comments on commit 6e4b8cf

Please sign in to comment.