Skip to content

Special characters in filenames cause incorrect operation #642

@zhangjiuyi

Description

@zhangjiuyi

Version: 4.1.0

Issue Description:

I have a GLB file that, when uploaded and viewed for textures on the [BabylonJS Sandbox](https://sandbox.babylonjs.com/) and subsequently exported (as GLB), results in the internal texture names being renamed to the format blob:https:__sandbox image.png. This poses a problem when I use the command gltf-pipeline -i xxx.glb -t -o xx.gltf.

On macOS, filenames containing the : character get replaced with /, which leads to an error when running gltf-pipeline -i output.gltf -o output.glb, as the actual filename doesn't match the one inside the .gltf file. However, this can be manually fixed by adjusting the .gltf file itself.

On Windows, executing gltf-pipeline -i xxx.glb -t -o xx.gltf results in an error: (node:2128) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'C:\Users\test\Desktop\glb\blob:https:__sandbox image_3.png’.

The probable cause seems to be the incompatibility of the : character with the Windows file system.

Expected Result:

I'd like the process to handle glb file unpacking and packing smoothly, even when filenames contain special characters.

Possible Solution:

I attempted to access the source code:

In bin/gltf-pipeline.js, I adjusted the saveSeparateResources method:

tsxCopy code
if (Object.prototype.hasOwnProperty.call(separateResources, relativePath)) {
  const resource = separateResources[relativePath];

  // Replace special characters
  const dirname = path.dirname(relativePath);
  const basename = path.basename(relativePath).replace(/[<>:"/\\|?*#]/g, '_');
  const sanitizedPath = path.join(dirname, basename);

  const resourcePath = path.join(outputDirectory, sanitizedPath);
  resourcePromises.push(fsExtra.outputFile(resourcePath, resource));
}

I also made changes in lib/addPipelineExtras.js:

tsxCopy code
//before
function addPipelineExtras(gltf) {
  ForEach.shader(gltf, function (shader) {
    addExtras(shader);
  });
  ForEach.buffer(gltf, function (buffer) {
    addExtras(buffer);
  });
  ForEach.image(gltf, function (image) {
    addExtras(image);
  });

  addExtras(gltf);

  return gltf;
}

// after
function addPipelineExtras(gltf) {
  ForEach.shader(gltf, function (shader) {
    addExtras(shader);
  });
  ForEach.buffer(gltf, function (buffer) {
    addExtras(buffer);
  });
  ForEach.image(gltf, function (image) {
    if (image.name) {
      image.name = image.name.replace(/[<>:"/\\|?*#]/g, '_');
    }
    addExtras(image);
  });

  addExtras(gltf);

  return gltf;
}

This approach provisionally addressed the issues I encountered. Perhaps another potential solution could be to use the encodeURIComponent(fileName) and decode method? But who's to say?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions