Repository: swc-project/swc (rust)

Issue:
swc tries to parse `//# sourceMappingURL` from inside a string variable
### Describe the bug

swc incorrectly tries to parse `//# sourceMappingURL` directive from inside of a string variable

The issue doesn't show up in playground, since the code does compile but when compiling in terminal, the error is written to console.


### Input code

```typescript
var a = "//# sourceMappingURL=[file].map"
```


### Config

```json
{
    "sourceMaps": "inline",
    "jsc": {
        "target": "es2021",
        "parser": {
          "syntax": "ecmascript"
        }
    }
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.4.14&code=H4sIAAAAAAAAAytLLFJIVLBVUNLXV1Yozi8tSk71TSwoyMxLDw3ysY1Oy8xJjdXLTSxQAgDDoVpaKQAAAA%3D%3D&config=H4sIAAAAAAAAA1WMQQqAMAwE732F5OxBPfoHHxFqkIrWkqSgiH%2B3rSK4l7C7szlNlQSyRbY0YBDoK3B%2BcZ6gfrpZbArPYkqgyBNpBkm6pmtfsHQBWYh%2FfH5%2FeMW9LOyKYtkFhQ%2B4nv17wMmwjXGhhCtHMpe5AeizYuOlAAAA

### SWC Info output

```
    Operating System:
        Platform: win32
        Arch: x64
        Machine Type: x86_64
        Version: Windows 10 Pro
        CPU: (8 cores)
            Models: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz

    Binaries:
        Node: 16.19.0
        npm: N/A
        Yarn: N/A
        pnpm: N/A

    Relevant Packages:
        @swc/core: 1.4.14
        @swc/helpers: N/A
        @swc/types: 0.1.6


    SWC Config:
        output: N/A
        .swcrc path: N/A

    Next.js info:
        output: N/A
```

### Expected behavior

No error in console

### Actual behavior

```
  ERROR  failed to read input source map: failed to parse inline source map url
[file].map"

Caused by:
    relative URL without a base
    at C:\Users\runneradmin\.cargo\registry\src\index.crates.io-6f17d22bba15001f\swc-0.273.25\src\lib.rs:385

Successfully compiled 1 file with swc.
var a = "//# sourceMappingURL=[file].map";

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QuanMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGEgPSBcIi8vIyBzb3VyY2VNYXBwaW5nVVJMPVtmaWxlXS5tYXBcIiJdLCJuYW1lcyI6WyJhIl0sInJhbmdlTWFwcGluZ3MiOiIiLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsSUFBSSJ9

```

### Version

1.4.14

### Additional context

_No response_

Pull request:
fix(es): Ignore `sourceMappingURL` in string literals
**Description:**


**Related issue:**

 - Closes #8869

Patch:
diff --git a/crates/swc/src/lib.rs b/crates/swc/src/lib.rs
index 880b295f8f..1b8ed41647 100644
--- a/crates/swc/src/lib.rs
+++ b/crates/swc/src/lib.rs
@@ -120,7 +120,10 @@ use std::{
 
 use anyhow::{bail, Context, Error};
 use base64::prelude::{Engine, BASE64_STANDARD};
-use common::{comments::SingleThreadedComments, errors::HANDLER};
+use common::{
+    comments::{Comment, SingleThreadedComments},
+    errors::HANDLER,
+};
 use jsonc_parser::{parse_to_serde_value, ParseOptions};
 use once_cell::sync::Lazy;
 use serde_json::error::Category;
@@ -242,6 +245,7 @@ impl Compiler {
         &self,
         fm: &SourceFile,
         input_src_map: &InputSourceMap,
+        comments: &[Comment],
         is_default: bool,
     ) -> Result<Option<sourcemap::SourceMap>, Error> {
         self.run(|| -> Result<_, Error> {
@@ -364,22 +368,19 @@ impl Compiler {
 
             let read_sourcemap = || -> Option<sourcemap::SourceMap> {
                 let s = "sourceMappingURL=";
-                let idx = fm.src.rfind(s);
 
-                let data_url = idx.map(|idx| {
-                    let data_idx = idx + s.len();
-                    if let Some(end) = fm.src[data_idx..].find('\n').map(|i| i + data_idx + 1) {
-                        &fm.src[data_idx..end]
-                    } else {
-                        &fm.src[data_idx..]
-                    }
+                let text = comments.iter().rev().find_map(|c| {
+                    let idx = c.text.rfind(s)?;
+                    let (_, url) = c.text.split_at(idx + s.len());
+
+                    Some(url.trim())
                 });
 
-                match read_inline_sourcemap(data_url) {
+                match read_inline_sourcemap(text) {
                     Ok(r) => r,
                     Err(err) => {
                         // Load original source map if possible
-                        match read_file_sourcemap(data_url) {
+                        match read_file_sourcemap(text) {
                             Ok(v) => v,
                             Err(_) => {
                                 tracing::error!("failed to read input source map: {:?}", err);
@@ -697,7 +698,16 @@ impl Compiler {
             let config = config.with_pass(|pass| chain!(pass, after_pass));
 
             let orig = if config.source_maps.enabled() {
-                self.get_orig_src_map(&fm, &config.input_source_map, false)?
+                self.get_orig_src_map(
+                    &fm,
+                    &config.input_source_map,
+                    config
+                        .comments
+                        .get_trailing(config.program.span_hi())
+                        .as_deref()
+                        .unwrap_or_default(),
+                    false,
+                )?
             } else {
                 None
             };


Test patch:
diff --git a/crates/swc/tests/fixture/issues-8xxx/8869/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8869/input/.swcrc
new file mode 100644
index 0000000000..92ca8d486d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8869/input/.swcrc
@@ -0,0 +1,9 @@
+{
+    "sourceMaps": "inline",
+    "jsc": {
+        "target": "es2021",
+        "parser": {
+            "syntax": "ecmascript"
+        }
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8869/input/1.js b/crates/swc/tests/fixture/issues-8xxx/8869/input/1.js
new file mode 100644
index 0000000000..a960269792
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8869/input/1.js
@@ -0,0 +1,1 @@
+var a = "//# sourceMappingURL=[file].map"
diff --git a/crates/swc/tests/fixture/issues-8xxx/8869/output/1.js b/crates/swc/tests/fixture/issues-8xxx/8869/output/1.js
new file mode 100644
index 0000000000..4d9de5a713
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8869/output/1.js
@@ -0,0 +1,3 @@
+var a = "//# sourceMappingURL=[file].map";
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2lucHV0LzEuanMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGEgPSBcIi8vIyBzb3VyY2VNYXBwaW5nVVJMPVtmaWxlXS5tYXBcIlxuIl0sIm5hbWVzIjpbImEiXSwicmFuZ2VNYXBwaW5ncyI6IiIsIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFJIn0=