Fix MJZ decoder Windows path separator issue

On Windows, std::filesystem::path::string() returns backslashes while
zip entries use forward slashes. This caused lookup mismatches making
MJZ decoding fail on Windows with 'could not decode content'.

Use generic_string() (which always returns forward slashes) for all
path operations used in zip entry lookups, and normalize the archive
name at construction time.

PiperOrigin-RevId: 943538265
Change-Id: I50cafff82fd7f5f315ccfc890f660e138e4448a2
This commit is contained in:
Sam Haves
2026-07-06 15:52:46 -07:00
committed by Copybara-Service
parent 528e791d6e
commit 19e175c063
+6 -4
View File
@@ -61,7 +61,8 @@ class ZipArchiveProvider : public mjpResourceProvider {
public:
ZipArchiveProvider(std::string name, const void* buffer, int nbuffer,
char* error, int error_sz)
: name_(std::move(name)), buffer_((char*)buffer, (char*)buffer + nbuffer) {
: name_(std::filesystem::path(name).generic_string()),
buffer_((char*)buffer, (char*)buffer + nbuffer) {
mjp_defaultResourceProvider(this);
std::memset(&archive_, 0, sizeof(archive_));
@@ -92,7 +93,8 @@ class ZipArchiveProvider : public mjpResourceProvider {
const std::filesystem::path path(name_);
root_model_ = (path / path.stem()).generic_string() + ".xml";
if (!Contains(root_model_)) {
root_model_ = (path / path.stem() / path.stem()).string() + ".xml";
root_model_ =
(path / path.stem() / path.stem()).generic_string() + ".xml";
if (!Contains(root_model_)) {
SetError(error, error_sz, "Zip error: no root XML file found.");
return;
@@ -111,13 +113,13 @@ class ZipArchiveProvider : public mjpResourceProvider {
open = [](mjResource* resource) {
ZipArchiveProvider* self = (ZipArchiveProvider*)resource->provider;
auto path = std::filesystem::path(resource->name).lexically_normal();
const bool found = self->Contains(path.string());
const bool found = self->Contains(path.generic_string());
return found ? 1 : 0;
};
read = [](mjResource* resource, const void** buffer) {
ZipArchiveProvider* self = (ZipArchiveProvider*)resource->provider;
auto path = std::filesystem::path(resource->name).lexically_normal();
std::span<char> bytes = self->Read(path.string());
std::span<char> bytes = self->Read(path.generic_string());
*buffer = bytes.data();
return static_cast<int>(bytes.size());
};