Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/check_sast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ jobs:
persist-credentials: false

- name: Initialize CodeQL
uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
languages: ${{ matrix.language }}
build-mode: none
config-file: .github/codeql/codeql-config.yml

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
category: '/language:${{ matrix.language }}'
upload: False
Expand Down Expand Up @@ -127,7 +127,7 @@ jobs:
continue-on-error: true

- name: Upload SARIF
uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
sarif_file: sarif-results/${{ matrix.language }}.sarif
continue-on-error: true
2 changes: 1 addition & 1 deletion .github/workflows/scorecards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
sarif_file: results.sarif
1 change: 1 addition & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ jobs:

- name: Install libraries with vcpkg
run: |
git -C "%VCPKG_INSTALLATION_ROOT%" pull --quiet
vcpkg install
working-directory: src
if: ${{ ! steps.restore-vcpkg.outputs.cache-hit }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zjit-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
rustup install ${{ matrix.rust_version }} --profile minimal
rustup default ${{ matrix.rust_version }}

- uses: taiki-e/install-action@25435dc8dd3baed7417e0c96d3fe89013a5b2e09 # v2.81.3
- uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2.81.5
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
ruby-version: '3.1'
bundler: none

- uses: taiki-e/install-action@25435dc8dd3baed7417e0c96d3fe89013a5b2e09 # v2.81.3
- uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2.81.5
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
13 changes: 13 additions & 0 deletions benchmark/string_inspect.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
prelude: |
ascii = "Hello, World! This is a benchmark test string." * 100
utf8 = "こんにちは世界。これはベンチマーク用のテスト文字列です。" * 100
mixed = ("Hello World! " + "テスト" + " is great! ") * 100
binary = ("\xE3\x81\x82" * 100).b
escapy = "\n\t\"\\\#" * 100
benchmark:
inspect_ascii: ascii.inspect
inspect_utf8: utf8.inspect
inspect_mixed: mixed.inspect
inspect_binary: binary.inspect
inspect_escapy: escapy.inspect
18 changes: 8 additions & 10 deletions doc/file/filename_globbing.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
# Filename Globbing

Filename globbing is a pattern-matching feature implemented in certain Ruby methods.

Filename-globbing methods find filesystem entries (files and directories)
that match certain patterns;
these methods are:
Filename globbing is a pattern-matching feature implemented in certain Ruby methods:

- Dir.glob.
- [`Dir[]`](https://docs.ruby-lang.org/en/master/Dir.html#method-c-5B-5D).
- Pathname.glob.
- Pathname#glob.

These methods are quite different from filename-matching methods (not discussed here),
which match patterns against string paths, and do not access the filesystem;
those methods are:
Each `glob` method finds filesystem entries (files and directories)
that match certain patterns.

These methods are quite different
from [filename-matching](rdoc-ref:filename_matching.md) methods,
which match patterns against string paths, and do not access the filesystem.

- File.fnmatch.
- Pathname#fnmatch.
## Patterns

These are the basic elements of filename-globbing patterns;
see the sections below for details:
Expand Down
41 changes: 19 additions & 22 deletions doc/file/filename_matching.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Filename Matching
# Filename Matching

Filename matching is a pattern-matching feature implemented in certain Ruby methods:

Expand All @@ -8,14 +8,11 @@ Filename matching is a pattern-matching feature implemented in certain Ruby meth
Each `fnmatch` method matches a pattern against a string _path_;
these methods operate only on strings, and do not access the file system.

These are quite different from filename globbing methods (not discussed here),
which match patterns against string paths found in the actual file system:
These methods are quite different
from [filename-globbing](rdoc-ref:filename_globbing.md) methods,
which match patterns against string paths found in the actual file system.

- Dir.glob.
- Pathname.glob.
- Pathname#glob.

### Patterns
## Patterns

These are the basic elements of filename matching patterns;
see the sections below for details:
Expand All @@ -36,7 +33,7 @@ There are two other patterns that are disabled by default:
- Alternatives (`'{ , }'`);
see [`File::FNM_EXTGLOB`](#constant-filefnmextglob) below.

#### Simple \String
### Simple \String

A "simple string" is one that does not contain special filename-matching patterns;
see the table above.
Expand Down Expand Up @@ -78,7 +75,7 @@ File.fnmatch('PROGRAM~1', 'Program Files') # => false

It may be enabled by flag [`File::FNM_SHORTNAME`](#constant-filefnmshortname).

#### Any Sequence of Characters (`'*'`)
### Any Sequence of Characters (`'*'`)

The asterisk pattern (`'*'`) matches any sequence of characters:

Expand All @@ -105,7 +102,7 @@ File.fnmatch('*.rb', 'lib/test.rb') # => true

That matching may be disabled by flag [`File::FNM_PATHNAME`](#constant-filefnmpathname).

#### Single Character (`'?'`)
### Single Character (`'?'`)

The question-mark pattern (`'?'`) matches any single character:

Expand All @@ -125,7 +122,7 @@ File.fnmatch('foo?boo', 'foo/boo') # => true

That matching may be disabled by flag [`File::FNM_PATHNAME`](#constant-filefnmpathname).

#### Single Character from a Set (`'[abc]'`, `'[^abc]'`)
### Single Character from a Set (`'[abc]'`, `'[^abc]'`)

Characters enclosed in square brackets define a set of characters,
any of which matches a single character:
Expand All @@ -145,7 +142,7 @@ File.fnmatch('[^ruby]', 'r') # => false
File.fnmatch('[^ruby]', 'u') # => false
```

#### Single Character from a \Range (`'[a-c]'`, `'[^a-c]'`)
### Single Character from a \Range (`'[a-c]'`, `'[^a-c]'`)

A range of characters enclosed in square brackets defines a set of characters,
any of which matches a single character:
Expand All @@ -165,7 +162,7 @@ File.fnmatch('[^a-c]', 'b') # => false
File.fnmatch('[^a-c]', 'd') # => true
```

#### Escape (`'\'`)
### Escape (`'\'`)

The backslash character (`'\'`) may be used to escape any of the characters
that filename matching treats as special:
Expand All @@ -191,7 +188,7 @@ File.fnmatch('\\\\', '\\') # => true
By default escape pattern `'\'` is enabled;
it may be disabled by flag [`File::FNM_NOESCAPE`](#constant-filefnmnoescape).

### Flags
## Flags

Optional argument `flags` (defaults to `0`) may be the bitwise OR
of the constants `File::FNM*`.
Expand All @@ -210,7 +207,7 @@ see the sections below for details:
| [`File::FNM_SYSCASE`](#constant-filefnmsyscase) | Make the pattern use OS's case sensitivity. |


#### Constant File::FNM_CASEFOLD
### Constant File::FNM_CASEFOLD

By default, filename matching is case-sensitive;
use constant [`File::FNM_CASEFOLD`](#constant-filefnmcasefold)
Expand All @@ -221,7 +218,7 @@ File.fnmatch('abc', 'ABC') # => false
File.fnmatch('abc', 'ABC', File::FNM_CASEFOLD) # => true
```

#### Constant File::FNM_DOTMATCH
### Constant File::FNM_DOTMATCH

By default, filename matching does not allow pattern `'*'` to match a dotfile name
(i.e, a filename beginning with a dot);
Expand All @@ -232,7 +229,7 @@ to enable the match:
File.fnmatch('*', '.document') # => false
File.fnmatch('*', '.document', File::FNM_DOTMATCH) # => true
```
#### Constant File::FNM_EXTGLOB
### Constant File::FNM_EXTGLOB

By default, filename matching has the alternative notation disabled;
use constant [`File::FNM_EXTGLOB`](#constant-filefnmextglob)
Expand Down Expand Up @@ -261,7 +258,7 @@ File.fnmatch('{*ELLO,?????}', 'hello', File::FNM_EXTGLOB) # => true
File.fnmatch('R{ub,foo,bar}y', 'Ruby') # => false
```

#### Constant File::FNM_NOESCAPE
### Constant File::FNM_NOESCAPE

By default filename matching has escaping enabled;
use constant [`File::FNM_NOESCAPE`](#constant-filefnmnoescape)
Expand All @@ -272,7 +269,7 @@ File.fnmatch('\*\?\*\*', '*?**') # => true
File.fnmatch('\*\?\*\*', '*?**', File::FNM_NOESCAPE) # => false
```

#### Constant File::FNM_PATHNAME
### Constant File::FNM_PATHNAME

Flag [`File::FNM_PATHNAME`](#constant-filefnmpathname) affects
patterns `'**'`, `'*'`, and `'?'`.
Expand Down Expand Up @@ -316,7 +313,7 @@ File.fnmatch('foo?boo', 'foo/boo') # => true
File.fnmatch('foo?boo', 'foo/boo', File::FNM_PATHNAME) # => false
```

#### Constant File::FNM_SHORTNAME
### Constant File::FNM_SHORTNAME

By default, Windows shortname matching is disabled;
use constant [`File::FNM_SHORTNAME`](#constant-filefnmshortname)
Expand All @@ -339,7 +336,7 @@ File.fnmatch('PROGRAM~1', 'Program Files') # => false
File.fnmatch('PROGRAM~1', 'Program Files', File::FNM_SHORTNAME) # => true
```

#### Constant File::FNM_SYSCASE
### Constant File::FNM_SYSCASE

By default, filename matching uses Ruby's own case-sensitivity rules;
use constant [`File::FNM_SYSCASE`](#constant-filefnmsyscase)
Expand Down
34 changes: 17 additions & 17 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -3653,11 +3653,12 @@ has_drive_letter(const char *buf)
}

#ifndef _WIN32
static char*
static VALUE
getcwdofdrv(int drv)
{
char drive[4];
char *drvcwd, *oldcwd;
char *oldcwd;
VALUE drvcwd;

drive[0] = drv;
drive[1] = ':';
Expand All @@ -3669,13 +3670,13 @@ getcwdofdrv(int drv)
*/
oldcwd = ruby_getcwd();
if (chdir(drive) == 0) {
drvcwd = ruby_getcwd();
drvcwd = rb_dir_getwd_ospath();
chdir(oldcwd);
xfree(oldcwd);
}
else {
/* perhaps the drive is not exist. we return only drive letter */
drvcwd = strdup(drive);
drvcwd = rb_enc_str_new_cstr(drive, rb_filesystem_encoding());
}
return drvcwd;
}
Expand Down Expand Up @@ -4045,16 +4046,19 @@ ospath_new(const char *ptr, long len, rb_encoding *fsenc)
}

static char *
append_fspath(VALUE result, VALUE fname, char *dir, rb_encoding **enc, rb_encoding *fsenc)
append_fspath(VALUE result, VALUE fname, VALUE dirname, rb_encoding **enc, rb_encoding *fsenc)
{
char *buf, *cwdp = dir;
VALUE dirname = Qnil;
size_t dirlen = strlen(dir), buflen = rb_str_capacity(result);
if (RB_UNLIKELY(!rb_enc_asciicompat(fsenc) || rb_enc_str_coderange(dirname) != ENC_CODERANGE_7BIT)) {
dirname = rb_str_new_shared(dirname);
rb_enc_associate(dirname, fsenc);
}

char *buf, *cwdp;
size_t dirlen = RSTRING_LEN(dirname);
size_t buflen = rb_str_capacity(result);

if (NORMALIZE_UTF8PATH || *enc != fsenc) {
dirname = ospath_new(dir, dirlen, fsenc);
if (!rb_enc_compatible(fname, dirname)) {
xfree(dir);
/* rb_enc_check must raise because the two encodings are not
* compatible. */
rb_enc_check(fname, dirname);
Expand All @@ -4063,19 +4067,15 @@ append_fspath(VALUE result, VALUE fname, char *dir, rb_encoding **enc, rb_encodi
rb_encoding *direnc = fs_enc_check(fname, dirname);
if (direnc != fsenc) {
dirname = rb_str_conv_enc(dirname, fsenc, direnc);
RSTRING_GETMEM(dirname, cwdp, dirlen);
}
else if (NORMALIZE_UTF8PATH) {
RSTRING_GETMEM(dirname, cwdp, dirlen);
}
*enc = direnc;
}

RSTRING_GETMEM(dirname, cwdp, dirlen);
do {buflen *= 2;} while (dirlen > buflen);
rb_str_resize(result, buflen);
buf = RSTRING_PTR(result);
memcpy(buf, cwdp, dirlen);
xfree(dir);
if (!NIL_P(dirname)) rb_str_resize(dirname, 0);
rb_enc_associate(result, *enc);
return buf + dirlen;
}
Expand Down Expand Up @@ -4177,7 +4177,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
p = pend;
}
else {
char *e = append_fspath(result, fname, ruby_getcwd(), &enc, fsenc);
char *e = append_fspath(result, fname, rb_dir_getwd_ospath(), &enc, fsenc);
BUFINIT();
p = e;
}
Expand Down
6 changes: 4 additions & 2 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1856,10 +1856,12 @@ os_each_obj(int argc, VALUE *argv, VALUE os)

/*
* call-seq:
* ObjectSpace.undefine_finalizer(obj)
* ObjectSpace.undefine_finalizer(obj) -> obj
*
* Removes all finalizers for <i>obj</i>.
* Removes all finalizers registered for +obj+ with
* ObjectSpace.define_finalizer, and returns +obj+.
*
* Does nothing if +obj+ has no finalizers.
*/

static VALUE
Expand Down
16 changes: 16 additions & 0 deletions lib/bundler/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -456,11 +456,27 @@ def cooldown_hint(specs)
def cooldown_excluded?(spec)
return false unless spec.respond_to?(:created_at) && spec.created_at
return false unless spec.respond_to?(:remote) && spec.remote
return false if pinned_by_lockfile_floor?(spec)
days = spec.remote.effective_cooldown
return false if days.nil? || days <= 0
(cooldown_now - spec.created_at) < (days * 86_400)
end

# A spec sitting exactly at a `>= locked_version` prevent-downgrade floor is
# the version the lockfile currently pins. `bundle update` and `bundle
# outdated` install that floor so resolution never moves a gem backwards.
# Filtering it out for cooldown would then make resolution impossible
# whenever the locked version is itself inside the cooldown window, which is
# exactly what happens to a lockfile written before cooldown was enabled.
# Keep it eligible; gems being explicitly updated carry an exact `=`
# requirement instead and stay subject to the cooldown filter.
def pinned_by_lockfile_floor?(spec)
return false unless defined?(@base) && @base
requirement = base_requirements[spec.name]
return false unless requirement && !requirement.exact?
requirement.requirements.any? {|op, version| op == ">=" && version == spec.version }
end

def cooldown_now
@cooldown_now ||= Time.now
end
Expand Down
Loading