Fix Lua string escaping.

Closes #314.
This commit is contained in:
Lucien Greathouse
2020-04-16 12:00:02 -07:00
parent a4d4beeb97
commit 5364c9c1bc
2 changed files with 50 additions and 2 deletions

View File

@@ -2,6 +2,7 @@
## Unreleased Changes
* Fixed crash when malformed CSV files are put into a project. ([#310](https://github.com/rojo-rbx/rojo/issues/310))
* Fixed incorrect string escaping when producing Lua code from JSON files. ([#314](https://github.com/rojo-rbx/rojo/issues/314))
* Updated default place template to take advantage of [#210](https://github.com/rojo-rbx/rojo/pull/210).
## [6.0.0 Release Candidate 1](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.1) (March 29, 2020)

View File

@@ -21,6 +21,18 @@ trait FmtLua {
}
}
struct DisplayLua<T>(T);
impl<T> fmt::Display for DisplayLua<T>
where
T: FmtLua,
{
fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut stream = LuaStream::new(output);
self.0.fmt_lua(&mut stream)
}
}
pub(crate) enum Statement {
Return(Expression),
}
@@ -125,16 +137,37 @@ impl FmtLua for f64 {
}
}
/// Wrapper struct to display the wrapped string using Lua's string escaping
/// rules.
struct LuaEscape<'a>(&'a str);
impl fmt::Display for LuaEscape<'_> {
fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
for c in self.0.chars() {
match c {
'"' => output.write_str("\\\"")?,
'\r' => output.write_str("\\r")?,
'\n' => output.write_str("\\n")?,
'\t' => output.write_str("\\t")?,
'\\' => output.write_str("\\\\")?,
_ => output.write_char(c)?,
}
}
Ok(())
}
}
impl FmtLua for String {
fn fmt_lua(&self, output: &mut LuaStream<'_>) -> fmt::Result {
write!(output, "\"{}\"", self)
write!(output, "\"{}\"", LuaEscape(self))
}
fn fmt_table_key(&self, output: &mut LuaStream<'_>) -> fmt::Result {
if is_valid_ident(self) {
write!(output, "{}", self)
} else {
write!(output, "[\"{}\"]", self)
write!(output, "[\"{}\"]", LuaEscape(self))
}
}
}
@@ -277,3 +310,17 @@ impl<'a> LuaStream<'a> {
self.inner.write_str("\n")
}
}
#[cfg(test)]
mod test {
use super::*;
/// Regression test for https://github.com/rojo-rbx/rojo/issues/314
#[test]
fn bug_314() {
let my_value = "\"\r\n\t\\".to_owned();
let displayed = format!("{}", DisplayLua(my_value));
assert_eq!(displayed, "\"\\\"\\r\\n\\t\\\\\"");
}
}