Shizuma5 opened a new issue, #39969:
URL: https://github.com/apache/beam/issues/39969

   ### What happened?
   
   **Beam version:** 2.75.0 through current `master` (2.77.0-SNAPSHOT). 
**SDK:** Go. **Filesystem:** GCS (`gs://`).
   
   ### Summary
   
   `fileio.MatchAll` fails to return existing GCS objects when the glob pattern 
contains non-ASCII (multi-byte) characters. When empty matches are allowed, it 
returns no error at all; the affected objects are simply missing from the 
results.
   This is a regression in 2.75.0 (#38099); the same patterns worked correctly 
in 2.74.0 and earlier.
   
   ### Examples
   
   A bucket `gs://my-bucket` containing:
   
   ```
   gs://my-bucket/
   ├── singlebyte/
   │   ├── english1.txt
   │   └── english2.txt
   ├── multibyte/
   │   ├── japanese.txt
   │   └── 日本語.txt
   └── multibytepath_é/
       ├── singlebyte_file1.txt
       └── singlebyte_file2.txt
   ```
   
   ```go
   patterns := beam.Create(s,
       "gs://my-bucket/singlebyte/*.txt",                      // all ASCII → OK
       "gs://my-bucket/multibyte/*.txt",                       // ASCII 
pattern, non-ASCII object names → OK
       "gs://my-bucket/multibyte/日本語.txt",                   // non-ASCII file 
name → broken
       "gs://my-bucket/multibytepath_é/*.txt",                 // non-ASCII 
directory → broken
       "gs://my-bucket/multibytepath_é/singlebyte_file1.txt",  // non-ASCII 
directory, exact path → broken
   )
   matched := fileio.MatchAll(s, patterns)  // PCollection<fileio.FileMetadata>
   ```
   
   | glob passed to `MatchAll` | returned on 2.74 | returned on 2.75+ |
   |---|---|---|
   | `.../singlebyte/*.txt` | english1.txt, english2.txt | english1.txt, 
english2.txt |
   | `.../multibyte/*.txt` | japanese.txt, 日本語.txt | japanese.txt, 日本語.txt |
   | `.../multibyte/日本語.txt` | 日本語.txt | *(none)* |
   | `.../multibytepath_é/*.txt` | singlebyte_file1.txt, singlebyte_file2.txt | 
*(none)* |
   | `.../multibytepath_é/singlebyte_file1.txt` | singlebyte_file1.txt | 
*(none)* |
   
   When empty matches are allowed, no error is raised at all, so the missing 
objects are a silent data loss.
   
   ### Root cause (summary)
   
   `globToRegex()` in 
[`sdks/go/pkg/beam/io/filesystem/gcs/gcs.go`](https://github.com/apache/beam/blob/master/sdks/go/pkg/beam/io/filesystem/gcs/gcs.go#L42-L110)
 iterates over the glob pattern byte by byte instead of rune by rune. In its 
`default` branch, it passes each byte `c` to `regexp.QuoteMeta(string(c))`.
   
   For a multi-byte UTF-8 character, converting each byte separately with 
`string(c)` changes its encoding. As a result, `globToRegex()` produces a 
corrupted regular expression that does not match the original GCS object name.
   
   This behavior was introduced by #38099 in version 2.75.0. Earlier versions 
used the rune-aware `filepath.Match`, so version 2.74.0 and earlier are 
unaffected.
   
   
   
   ### Issue Priority
   
   Priority: 2 (default / most bugs should be filed as P2)
   
   ### Issue Components
   
   - [ ] Component: Python SDK
   - [ ] Component: Java SDK
   - [x] Component: Go SDK
   - [ ] Component: Typescript SDK
   - [ ] Component: IO connector
   - [ ] Component: Beam YAML
   - [ ] Component: Beam examples
   - [ ] Component: Beam playground
   - [ ] Component: Beam katas
   - [ ] Component: Website
   - [ ] Component: Infrastructure
   - [ ] Component: Spark Runner
   - [ ] Component: Flink Runner
   - [ ] Component: Prism Runner
   - [ ] Component: Twister2 Runner
   - [ ] Component: Hazelcast Jet Runner
   - [ ] Component: Google Cloud Dataflow Runner


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to