Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It's possible to create a zip file with backslash path seperators, and if you do, ggez won't let you load a file from inside a folder inside a zip #1264

Open
m-r-hunt opened this issue Dec 8, 2023 · 1 comment

Comments

@m-r-hunt
Copy link

m-r-hunt commented Dec 8, 2023

This was a weird problem to debug. It manifested as not being able to load a file inside a folder when using a zip resources folder, even though it worked fine in "loose files resource folder" mode.

FWIW other programs seem to be fine with either style of path seperator in the zip. For example, just opening the zip in windows file explorer doesn't show a difference. I don't know enough about zips to know if this is correct behaviour or if I accidentally created a cursed zip file.

I created the zip with the rust zip crate which was happy to let me use either style of path seperator and apparently embed it in the zip fine. It's easy to use backslashes on windows since that's the system path seperator.

In the function sanitize_path_for_zip() in vfs.rs, the code is reprocessing zip file paths and always inserts forward slash seperators. There is a comment:

/// We need to return a string.
/// The reason is that the path in zip is `/` delimited, but the path
/// delimiter in rust is environment dependent.
/// For example, on Windows, `PathBuf` to str in rust make "foo\\bar.txt".

But this appears to be wrong, as evidenced above.

Here's the output of ctx.fs.print_all(); on my backslash path zip:

Source <PhysicalFS root: [redacted]\game\target\debug\resources> Could not read source: IOError(Os { code: 3, kind: NotFound, message: "The system cannot find the path specified." })Source ZipFS { source: Some("[redacted]\\game\\target\\debug\\resources.zip"), archive: RefCell { value: <ZipArchiveAccess> }, index: ["0.png", "1.png", "2.png", "3.png", "4.png", "5.png", "6.png", "7.png", "8.png", "9.png", "bar.png", "beginning.scene", "code_room.scene", "code_room_dark.png", "code_room_lit.png", "code_room_transition.actor", "entry.png", "entry.scene", "entry_transition.actor", "foo.png", "light_switch.actor", "light_switch.rhai", "script_modules/", "script_modules\\codes.rhai", "test_actor.actor", "test_actor.rhai", "test_transition.actor", "wall_number.actor", "wall_number.rhai"] }Source <PhysicalFS root: [redacted]\data> Could not read source: IOError(Os { code: 3, kind: NotFound, message: "The system cannot find the path specified." })Source <PhysicalFS root: [redacted]\config> Could not read source: IOError(Os { code: 3, kind: NotFound, message: "The system cannot find the path specified." })

The key being "script_modules\\codes.rhai" with a backslash.

Update: I looked into it, and the official zip standard is that you should only use forward slashes as path seperator. Backslashes would be interpreted as just embedded backslashes in a file name on Unixish systems. However there's some history of zippers on windows using backslashes and/or interpreting them as path seperators, some programs will treat that as a path seperator or give you a warning or whatever. Nothing in the zip crate stops you from using a backslash, and my crappy code accidentally was using them.

So now I'm not sure what to do with this issue. I guess it's a non-bug that was just my problem, and this is a blog post about how I discovered this quirk of zip files. Maybe some documentation would be nice? It is impossible to access a file with a backslash in the name via ggez, even though that's a wierd thing to want to do.

@m-r-hunt
Copy link
Author

m-r-hunt commented Dec 8, 2023

Maybe a warning if you load a zip file with backslashes in some of the filenames would be nice?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant