bootsnap 1.21.0 → 1.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/ext/bootsnap/bootsnap.c +38 -4
- data/lib/bootsnap/load_path_cache/path_scanner.rb +7 -0
- data/lib/bootsnap/version.rb +1 -1
- data/lib/bootsnap.rb +3 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ca69038da7071534a7279f36d694ec5bcf5687272d091b314372b1f3195831b
|
|
4
|
+
data.tar.gz: c5dc747c2c66a71881d99af980085c06bfc378134d25712c51221b7fb6a6c03a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9da2aa5050b26d377f46d1de5e8424168e0a60b00160d43ebdaf9f93c4a9006931bf6463a24afa6dd76559ccedc4ce3798d48733d5000a7a5eac08d7c7a03510
|
|
7
|
+
data.tar.gz: 17a8da7a372189c22f400f5c059947f98c6aa7836390965c92e6e173970a61e2e6aa57d77d3dd11a9ecea0afd729512a115fd38a21c7a30850d1e9bd662b7d26
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 1.21.1
|
|
4
|
+
|
|
5
|
+
* Prevent a Ruby crash while scanning load path if `opendir` fails without setting `errno`.
|
|
6
|
+
According to the C spec this should not happen, but according to user reports, it did.
|
|
7
|
+
|
|
3
8
|
# 1.21.0
|
|
4
9
|
|
|
5
10
|
* Fix the `require` decorator to handle `Bootsnap.unload_cache!` being called.
|
data/ext/bootsnap/bootsnap.c
CHANGED
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
#include <sys/stat.h>
|
|
22
22
|
#include <dirent.h>
|
|
23
23
|
|
|
24
|
+
#ifndef RBIMPL_ATTR_NORETURN
|
|
25
|
+
#define RBIMPL_ATTR_NORETURN()
|
|
26
|
+
#endif
|
|
27
|
+
|
|
24
28
|
#ifdef __APPLE__
|
|
25
29
|
// The symbol is present, however not in the headers
|
|
26
30
|
// See: https://github.com/rails/bootsnap/issues/470
|
|
@@ -152,6 +156,21 @@ bs_rb_get_path(VALUE self, VALUE fname)
|
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
#ifdef HAVE_FSTATAT
|
|
159
|
+
|
|
160
|
+
RBIMPL_ATTR_NORETURN()
|
|
161
|
+
static void
|
|
162
|
+
bs_syserr_fail_path(const char *func_name, int n, VALUE path)
|
|
163
|
+
{
|
|
164
|
+
rb_syserr_fail_str(n, rb_sprintf("%s @ %s", func_name, RSTRING_PTR(path)));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
RBIMPL_ATTR_NORETURN()
|
|
168
|
+
static void
|
|
169
|
+
bs_syserr_fail_dir_entry(const char *func_name, int n, VALUE dir, const char *d_name)
|
|
170
|
+
{
|
|
171
|
+
rb_syserr_fail_str(n, rb_sprintf("%s @ %s/%s", func_name, RSTRING_PTR(dir), d_name));
|
|
172
|
+
}
|
|
173
|
+
|
|
155
174
|
static VALUE
|
|
156
175
|
bs_rb_scan_dir(VALUE self, VALUE abspath)
|
|
157
176
|
{
|
|
@@ -167,7 +186,17 @@ bs_rb_scan_dir(VALUE self, VALUE abspath)
|
|
|
167
186
|
if (errno == ENOTDIR || errno == ENOENT) {
|
|
168
187
|
return result;
|
|
169
188
|
}
|
|
170
|
-
|
|
189
|
+
|
|
190
|
+
// BUG: Some users reported a crash here because Ruby's syserr trigger
|
|
191
|
+
// a crash if called with `errno == 0`.
|
|
192
|
+
// The opendir spec is quite clear that if it returns NULL, then `errno` must
|
|
193
|
+
// be set, and yet here we are.
|
|
194
|
+
// So turning no errno into EINVAL, and from there I hope to get to the bottom of things.
|
|
195
|
+
if (errno == 0) {
|
|
196
|
+
errno = EINVAL;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
bs_syserr_fail_path("opendir", errno, abspath);
|
|
171
200
|
return Qundef;
|
|
172
201
|
}
|
|
173
202
|
|
|
@@ -185,7 +214,9 @@ bs_rb_scan_dir(VALUE self, VALUE abspath)
|
|
|
185
214
|
if (dfd < 0) {
|
|
186
215
|
dfd = dirfd(dirp);
|
|
187
216
|
if (dfd < 0) {
|
|
188
|
-
|
|
217
|
+
int err = errno;
|
|
218
|
+
closedir(dirp);
|
|
219
|
+
bs_syserr_fail_path("dirfd", err, abspath);
|
|
189
220
|
return Qundef;
|
|
190
221
|
}
|
|
191
222
|
}
|
|
@@ -193,9 +224,12 @@ bs_rb_scan_dir(VALUE self, VALUE abspath)
|
|
|
193
224
|
if (fstatat(dfd, entry->d_name, &st, 0)) {
|
|
194
225
|
if (errno == ENOENT) {
|
|
195
226
|
// Broken symlinK
|
|
227
|
+
errno = 0;
|
|
196
228
|
continue;
|
|
197
229
|
}
|
|
198
|
-
|
|
230
|
+
int err = errno;
|
|
231
|
+
closedir(dirp);
|
|
232
|
+
bs_syserr_fail_dir_entry("fstatat", err, abspath, entry->d_name);
|
|
199
233
|
return Qundef;
|
|
200
234
|
}
|
|
201
235
|
|
|
@@ -226,7 +260,7 @@ bs_rb_scan_dir(VALUE self, VALUE abspath)
|
|
|
226
260
|
}
|
|
227
261
|
|
|
228
262
|
if (closedir(dirp)) {
|
|
229
|
-
|
|
263
|
+
bs_syserr_fail_path("closedir", errno, abspath);
|
|
230
264
|
return Qundef;
|
|
231
265
|
}
|
|
232
266
|
return result;
|
|
@@ -102,6 +102,13 @@ module Bootsnap
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
all_requirables
|
|
105
|
+
rescue SystemCallError => error
|
|
106
|
+
if ENV["BOOTSNAP_DEBUG"]
|
|
107
|
+
raise
|
|
108
|
+
else
|
|
109
|
+
Bootsnap.logger&.call("Unexpected error: #{error.class}: #{error.message}")
|
|
110
|
+
ruby_call(root_path)
|
|
111
|
+
end
|
|
105
112
|
end
|
|
106
113
|
alias_method :call, :native_call
|
|
107
114
|
else
|
data/lib/bootsnap/version.rb
CHANGED
data/lib/bootsnap.rb
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "bootsnap/version"
|
|
4
4
|
require_relative "bootsnap/bundler"
|
|
5
|
-
require_relative "bootsnap/compile_cache"
|
|
6
|
-
require_relative "bootsnap/load_path_cache"
|
|
7
5
|
|
|
8
6
|
module Bootsnap
|
|
9
7
|
InvalidConfiguration = Class.new(StandardError)
|
|
@@ -164,3 +162,6 @@ module Bootsnap
|
|
|
164
162
|
end
|
|
165
163
|
end
|
|
166
164
|
end
|
|
165
|
+
|
|
166
|
+
require_relative "bootsnap/compile_cache"
|
|
167
|
+
require_relative "bootsnap/load_path_cache"
|