Fix loading of nonascii script name on Windows

Since the prism parser was enabled by default, loading scripts with nonascii characters somewhere in the script path is no longer working.
It only works when the codepage was switched to 65001 (UTF-8).

This patch doesn't change the encoding of __FILE__. It is still in locale encoding.
That's why pm_load_file() is called with UTF-8 script name and pm_parse_file() with locale encoding.

The loading of nonascii script names is part of the test-all, but it doesn't trigger the failure on GHA, since it is using cp 65001.
On other codepages it fails with:

[53/71] TestRubyOptions#test_command_line_progname_nonascii = 0.04 s
  1) Failure:
TestRubyOptions#test_command_line_progname_nonascii [C:/Users/Administrator/ruby/test/ruby/test_rubyoptions.rb:1086]:
[ruby-dev:48752] [Bug #10555]
pid 1736 exit 1
| C:\Users\Administrator\ruby\ruby.exe: No such file or directory -- �.rb (LoadError)
.

1. [1/2] Assertion for "stdout"
   | <["\xFF.rb"]> expected but was
   | <[]>.

2. [2/2] Assertion for "stderr"
   | <[]> expected but was
   | <["C:\\Users\\Administrator\\ruby\\ruby.exe: No such file or directory -- \xFF.rb (LoadError)"]>.
This commit is contained in:
Lars Kanis 2024-09-28 20:59:02 +02:00 коммит произвёл Jean Boussier
Родитель a0838a3902
Коммит 9b4a497456
1 изменённых файлов: 4 добавлений и 2 удалений

6
ruby.c
Просмотреть файл

@ -2193,10 +2193,12 @@ prism_script(ruby_cmdline_options_t *opt, pm_parse_result_t *result)
error = pm_parse_string(result, opt->e_script, rb_str_new2("-e"), NULL);
}
else {
VALUE script_name = rb_str_encode_ospath(opt->script_name);
pm_options_command_line_set(options, command_line);
pm_options_shebang_callback_set(options, prism_script_shebang_callback, (void *) opt);
error = pm_load_file(result, opt->script_name, true);
error = pm_load_file(result, script_name, true);
// If reading the file did not error, at that point we load the command
// line options. We do it in this order so that if the main script fails
@ -2217,7 +2219,7 @@ prism_script(ruby_cmdline_options_t *opt, pm_parse_result_t *result)
// contents after the marker.
if (NIL_P(error) && result->parser.data_loc.start != NULL) {
int xflag = opt->xflag;
VALUE file = open_load_file(opt->script_name, &xflag);
VALUE file = open_load_file(script_name, &xflag);
const pm_parser_t *parser = &result->parser;
size_t offset = parser->data_loc.start - parser->start + 7;