Skip to content

Commit

Permalink
Fix pattern matching of UTF-8 strings containing escape chars
Browse files Browse the repository at this point in the history
  • Loading branch information
richard-viney authored and lpil committed Mar 3, 2025
1 parent 0475308 commit 09ed78a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@
the package interface file if some modules were cached.
([Surya Rose](https://github.com/GearsDatapacks))

- Fixed a bug where pattern matching using a UTF-8 string constant would not
work correctly on the JavaScript target when the string contained escape
characters.
([Richard Viney](https://github.com/richard-viney))

## v1.8.1 - 2025-02-11

### Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion compiler-core/src/javascript/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ impl<'module_ctx, 'expression_gen, 'a> Generator<'module_ctx, 'expression_gen, '

[Opt::Utf8 { .. }] => match segment.value.as_ref() {
Pattern::String { value, .. } => {
for byte in value.as_bytes() {
for byte in convert_string_escape_chars(value).as_bytes() {
if offset.bits % 8 == 0 {
self.push_byte_at(offset.bits / 8);
} else {
Expand Down
11 changes: 11 additions & 0 deletions compiler-core/src/javascript/tests/bit_arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,17 @@ fn go(x) {
);
}

#[test]
fn match_utf8_with_escape_chars() {
assert_js!(
r#"
fn go(x) {
let assert <<"\"\\\r\n\t\f\u{1f600}">> = x
}
"#,
);
}

#[test]
fn match_utf8() {
assert_js!(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
source: compiler-core/src/javascript/tests/bit_arrays.rs
expression: "\nfn go(x) {\n let assert <<\"\\\"\\\\\\r\\n\\t\\f\\u{1f600}\">> = x\n}\n"
---
----- SOURCE CODE

fn go(x) {
let assert <<"\"\\\r\n\t\f\u{1f600}">> = x
}


----- COMPILED JAVASCRIPT
import { makeError } from "../gleam.mjs";

function go(x) {
if (
x.byteAt(0) !== 34 ||
x.byteAt(1) !== 92 ||
x.byteAt(2) !== 13 ||
x.byteAt(3) !== 10 ||
x.byteAt(4) !== 9 ||
x.byteAt(5) !== 12 ||
x.byteAt(6) !== 240 ||
x.byteAt(7) !== 159 ||
x.byteAt(8) !== 152 ||
x.byteAt(9) !== 128 ||
!(x.bitSize == 80)
) {
throw makeError(
"let_assert",
"my/mod",
3,
"go",
"Pattern match failed, no pattern matched the value.",
{ value: x }
)
}
return x;
}

0 comments on commit 09ed78a

Please sign in to comment.