diff --git a/.github/workflows/pr-playground.yml b/.github/workflows/pr-playground.yml index 097c14bd5cb758..dc4f075a384293 100644 --- a/.github/workflows/pr-playground.yml +++ b/.github/workflows/pr-playground.yml @@ -29,7 +29,7 @@ jobs: && github.event.workflow_run.event == 'pull_request') }} steps: - - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index 2e736673991aea..888a0ec8009a9f 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -93,7 +93,7 @@ jobs: rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - - uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1 + - uses: taiki-e/install-action@b8be7f5e140177087325943c4a8e169d01c59b3d # v2.75.3 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index a0adec6652ac1a..79d1b7bea4558e 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -119,7 +119,7 @@ jobs: ruby-version: '3.1' bundler: none - - uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1 + - uses: taiki-e/install-action@b8be7f5e140177087325943c4a8e169d01c59b3d # v2.75.3 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/benchmark/file_expand_path.yml b/benchmark/file_expand_path.yml new file mode 100644 index 00000000000000..9e503ab0032ccb --- /dev/null +++ b/benchmark/file_expand_path.yml @@ -0,0 +1,4 @@ +prelude: | + # frozen_string_literal: true +benchmark: + expand_path: File.expand_path("../../foo.txt", __FILE__) diff --git a/file.c b/file.c index b4560bea630c03..79d46b2de9670c 100644 --- a/file.c +++ b/file.c @@ -3707,8 +3707,9 @@ skipprefixroot(const char *path, const char *end, rb_encoding *enc) #endif } -char * -rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc) + +static char * +enc_path_last_separator(const char *path, const char *end, bool mb_enc, rb_encoding *enc) { char *last = NULL; while (path < end) { @@ -3719,17 +3720,22 @@ rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc) last = (char *)tmp; } else { - Inc(path, end, true, enc); + Inc(path, end, mb_enc, enc); } } return last; } +char * +rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc) +{ + return enc_path_last_separator(path, end, true, enc); +} static inline char * strrdirsep(const char *path, const char *end, bool mb_enc, rb_encoding *enc) { if (RB_UNLIKELY(mb_enc)) { - return rb_enc_path_last_separator(path, end, enc); + return enc_path_last_separator(path, end, mb_enc, enc); } const char *cursor = end - 1; @@ -4021,7 +4027,12 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na s = StringValuePtr(fname); fend = s + RSTRING_LEN(fname); - enc = rb_enc_get(fname); + enc = rb_str_enc_get(fname); + bool mb_enc = !rb_str_encindex_fastpath(rb_enc_to_index(enc)); + if (!mb_enc && RTEST(dname)) { + mb_enc = !rb_str_encindex_fastpath(rb_enc_to_index(rb_str_enc_get(dname))); + } + BUFINIT(); if (s < fend && s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */ @@ -4115,7 +4126,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na } else #endif /* defined DOSISH || defined __CYGWIN__ */ - p = chompdirsep(skiproot(buf, p), p, true, enc); + p = chompdirsep(skiproot(buf, p), p, mb_enc, enc); } else { size_t len; @@ -4139,7 +4150,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na rb_str_set_len(result, p-buf+1); BUFCHECK(bdiff + 1 >= buflen); p[1] = 0; - root = skipprefix(buf, p+1, true, enc); + root = skipprefix(buf, p+1, mb_enc, enc); b = s; while (s < fend) { @@ -4156,7 +4167,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na /* We must go back to the parent */ char *n; *p = '\0'; - if (!(n = strrdirsep(root, p, true, enc))) { + if (!(n = strrdirsep(root, p, mb_enc, enc))) { *p = '/'; } else { @@ -4219,7 +4230,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na } } #endif /* __APPLE__ */ - Inc(s, fend, true, enc); + Inc(s, fend, mb_enc, enc); break; } }