diff --git a/doc/jit/zjit.md b/doc/jit/zjit.md
index 38124cb7374fed..a284fce8115869 100644
--- a/doc/jit/zjit.md
+++ b/doc/jit/zjit.md
@@ -1,3 +1,7 @@
+
+
+
+
# ZJIT: ADVANCED RUBY JIT PROTOTYPE
ZJIT is a method-based just-in-time (JIT) compiler for Ruby. It uses profile
diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c
index 6b7e96f622b18b..747f065fbaae3f 100644
--- a/ext/coverage/coverage.c
+++ b/ext/coverage/coverage.c
@@ -52,17 +52,29 @@ rb_coverage_supported(VALUE self, VALUE _mode)
/*
* call-seq:
- * Coverage.setup => nil
- * Coverage.setup(:all) => nil
- * Coverage.setup(lines: bool, branches: bool, methods: bool, eval: bool) => nil
- * Coverage.setup(oneshot_lines: true) => nil
+ * Coverage.setup -> nil
+ * Coverage.setup(type) -> nil
+ * Coverage.setup(lines: false, branches: false, methods: false, eval: false, oneshot_lines: false) -> nil
*
- * Set up the coverage measurement.
+ * Performs setup for coverage measurement, but does not start coverage measurement.
+ * To start coverage measurement, use Coverage.resume.
*
- * Note that this method does not start the measurement itself.
- * Use Coverage.resume to start the measurement.
+ * To perform both setup and start coverage measurement, Coverage.start can be used.
*
- * You may want to use Coverage.start to setup and then start the measurement.
+ * With argument +type+ given and +type+ is symbol +:all+, enables all types of coverage
+ * (lines, branches, methods, and eval).
+ *
+ * Keyword arguments or hash +type+ can be given with each of the following keys:
+ *
+ * - +lines+: Enables line coverage that records the number of times each line was executed.
+ * If +lines+ is enabled, +oneshot_lines+ cannot be enabled.
+ * See {Lines Coverage}[rdoc-ref:Coverage@Lines+Coverage].
+ * - +branches+: Enables branch coverage that records the number of times each
+ * branch in each conditional was executed. See {Branches Coverage}[rdoc-ref:Coverage@Branch+Coverage].
+ * - +methods+: Enables method coverage that records the number of times each method was exectued.
+ * See {Methods Coverage}[rdoc-ref:Coverage@Methods+Coverage].
+ * - +eval+: Enables coverage for evaluations (e.g. Kernel#eval, Module#class_eval).
+ * See {Eval Coverage}[rdoc-ref:Coverage@Eval+Coverage].
*/
static VALUE
rb_coverage_setup(int argc, VALUE *argv, VALUE klass)
diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb
index f619d93252d950..2f6db44227e4bf 100644
--- a/ext/json/lib/json.rb
+++ b/ext/json/lib/json.rb
@@ -6,6 +6,15 @@
#
# \JSON is a lightweight data-interchange format.
#
+# \JSON is easy for us humans to read and write,
+# and equally simple for machines to read (parse) and write (generate).
+#
+# \JSON is language-independent, making it an ideal interchange format
+# for applications in differing programming languages
+# and on differing operating systems.
+#
+# == \JSON Values
+#
# A \JSON value is one of the following:
# - Double-quoted text: "foo".
# - Number: +1+, +1.0+, +2.0e2+.
diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb
index e5008a24dbf4a6..0fcb635394c433 100644
--- a/lib/rubygems/specification_policy.rb
+++ b/lib/rubygems/specification_policy.rb
@@ -436,6 +436,7 @@ def validate_values
warning "deprecated autorequire specified" if @specification.autorequire
@specification.executables.each do |executable|
+ validate_executable(executable)
validate_shebang_line_in(executable)
end
@@ -449,6 +450,13 @@ def validate_attribute_present(attribute)
warning("no #{attribute} specified") if value.nil? || value.empty?
end
+ def validate_executable(executable)
+ separators = [File::SEPARATOR, File::ALT_SEPARATOR, File::PATH_SEPARATOR].compact.map {|sep| Regexp.escape(sep) }.join
+ return unless executable.match?(/[\s#{separators}]/)
+
+ error "executable \"#{executable}\" contains invalid characters"
+ end
+
def validate_shebang_line_in(executable)
executable_path = File.join(@specification.bindir, executable)
return if File.read(executable_path, 2) == "#!"
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index e8c2c0eb47027f..7675ade415c608 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -3013,6 +3013,65 @@ def test_validate_executables
assert_match "#{w}: bin/exec is missing #! line\n", @ui.error, "error"
end
+ def test_validate_executables_with_space
+ util_setup_validate
+
+ FileUtils.mkdir_p File.join(@tempdir, "bin")
+ File.write File.join(@tempdir, "bin", "echo hax"), "#!/usr/bin/env ruby\n"
+
+ @a1.executables = ["echo hax"]
+
+ e = assert_raise Gem::InvalidSpecificationException do
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @a1.validate
+ end
+ end
+ end
+
+ assert_match "executable \"echo hax\" contains invalid characters", e.message
+ end
+
+ def test_validate_executables_with_path_separator
+ util_setup_validate
+
+ FileUtils.mkdir_p File.join(@tempdir, "bin")
+ File.write File.join(@tempdir, "exe"), "#!/usr/bin/env ruby\n"
+
+ @a1.executables = Gem.win_platform? ? ["..\\exe"] : ["../exe"]
+
+ e = assert_raise Gem::InvalidSpecificationException do
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @a1.validate
+ end
+ end
+ end
+
+ assert_match "executable \"#{Gem.win_platform? ? "..\\exe" : "../exe"}\" contains invalid characters", e.message
+ end
+
+ def test_validate_executables_with_path_list_separator
+ sep = Gem.win_platform? ? ";" : ":"
+
+ util_setup_validate
+
+ FileUtils.mkdir_p File.join(@tempdir, "bin")
+ File.write File.join(@tempdir, "bin", "foo#{sep}bar"), "#!/usr/bin/env ruby\n"
+
+ @a1.executables = ["foo#{sep}bar"]
+
+ e = assert_raise Gem::InvalidSpecificationException do
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @a1.validate
+ end
+ end
+ end
+
+ assert_match "executable \"foo#{sep}bar\" contains invalid characters", e.message
+ end
+
def test_validate_empty_require_paths
util_setup_validate
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index 1729d4404143a6..8714518866c3b4 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -2276,6 +2276,9 @@ fn gen_guard_type_not(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, g
/// Compile an identity check with a side exit
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, reason: SideExitReason, state: &FrameState) -> lir::Opnd {
+ if matches!(reason, SideExitReason::GuardShape(_) ) {
+ gen_incr_counter(asm, Counter::guard_shape_count);
+ }
let expected_opnd: Opnd = match expected {
crate::hir::Const::Value(v) => { Opnd::Value(v) }
crate::hir::Const::CInt64(v) => { v.into() }