shell mis-interprets unicode args of child_process.spawn

22 Views Asked by At

A simple C++ test_program opens file specified by argv[1] for reading:

#include <fstream>
#include <iostream>

int main(int argc, char *argv[]) {
  for (int i = 0; i < argc; i++)
    std::cout << "argv[" << i << "]: " << argv[i] << '\n';

  std::ifstream ifs;
  ifs.open(argv[1], std::ifstream::in);
  if (!ifs.is_open()) {
    std::cerr << "could not open file\n";
    return 1;
  }

  return 0;
}

and a nodejs module calls it with an argument:

let spawn = require("child_process").spawn;

module.exports.test = (file) => {
  return new Promise(function (resolve, reject) {
    let bat = spawn("C:\\test_program", [file]);
    bat.stdout.on("data", (data) => console.log(`stdout: ${data}`));
    bat.stderr.on("data", (e) => console.log(`stderr: ${e}`));
    bat.on("error", (e) => console.log(`error: ${e}`));
    bat.on("exit", (code) => {
      console.log(`exit code: ${code}`)
      resolve()
    });
    bat.stdin.end()
  })
}

call command:

node -e "require('./main').test('C:\\test.txt').then(() => {})"

prints as expected:

argv[0]: C:\test_program
argv[1]: C:\test.txt

exit code: 0

The problem is if I call with a path containing arabic characters, it won't work:

node -e "require('./main').test('C:\\مثال.txt').then(() => {})"

prints unexpected result:

argv[0]: C:\test_program
argv[1]: C:\????.txt      <--- see this change
argv[2]: C:\test.txt      <--- this arg is added by shell
                               after interpreting 
                               and puts all files in path 
                               that match pattern of C:\????.txt 

stderr: could not open file

exit code: 1

how to solve this?

NOTE: this behavior occurs in Windows OS. linux works as expected.

0

There are 0 best solutions below