Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion .github/workflows/shstk-amd64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ jobs:
runuser -u ruby -- ./miniruby -e '
line = File.foreach("/proc/self/status").find { |entry| entry.start_with?("x86_Thread_features:") }
features = line&.split(":", 2)&.last&.split || []
abort "SHSTK is not active (x86_Thread_features: #{features.join(" ")})" unless features.include?("shstk")
unless features.include?("shstk")
warn "::notice::SHSTK is not active (x86_Thread_features: #{features.join(" ")})"
cpuinfo = File.read("/proc/cpuinfo")
model = cpuinfo[/^model name.*/]
flags = cpuinfo[/^flags.*/]
puts model, flags, ENV["GLIBC_TUNABLES"]
exit !/\buser_shstk\b/.match?(flags)
end
'
- name: make check
Expand Down
4 changes: 4 additions & 0 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "internal.h"
#include "internal/box.h"
#include "internal/class.h"
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/gc.h"
#include "internal/hash.h"
Expand Down Expand Up @@ -3000,6 +3001,9 @@ singleton_class_of(VALUE obj, bool ensure_eigenclass)
return klass;
}

#if RUBY_VERSION_SINCE(4, 2)
RBIMPL_TODO("make rb_freeze_singleton_class internal; remove from fl_type.h")
#endif
void
rb_freeze_singleton_class(VALUE attached_object)
{
Expand Down
2 changes: 1 addition & 1 deletion doc/NEWS/NEWS-4.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ Note: We're only listing outstanding class updates.
* Ruby::Box

* A new (experimental) feature to provide separation about definitions.
For the detail of "Ruby Box", see [doc/language/box.md](doc/language/box.md).
For the detail of "Ruby Box", see [box.md](rdoc-ref:language/box.md).
[[Feature #21311]] [[Misc #21385]]

* Set
Expand Down
17 changes: 16 additions & 1 deletion include/ruby/internal/fl_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
#define FL_USER19 RBIMPL_CAST((VALUE)(unsigned int)RUBY_FL_USER19) /**< @old{RUBY_FL_USER19} */

#define ELTS_SHARED RUBY_ELTS_SHARED /**< @old{RUBY_ELTS_SHARED} */
#define RB_OBJ_FREEZE rb_obj_freeze_inline /**< @alias{rb_obj_freeze_inline} */

/** @cond INTERNAL_MACRO */
#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED
Expand All @@ -105,6 +104,7 @@
#define RB_FL_TEST_RAW RB_FL_TEST_RAW
#define RB_FL_UNSET RB_FL_UNSET
#define RB_FL_UNSET_RAW RB_FL_UNSET_RAW
#define RB_OBJ_FREEZE RB_OBJ_FREEZE
#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
#define RB_OBJ_FROZEN RB_OBJ_FROZEN
#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
Expand Down Expand Up @@ -355,6 +355,8 @@ ruby_fl_type {
#undef RBIMPL_HAVE_ENUM_ATTRIBUTE

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_DEPRECATED_EXT(("only for internal use"))
/**
* This is an implementation detail of #RB_OBJ_FREEZE(). People don't use it
* directly.
Expand All @@ -363,6 +365,7 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
* @post `klass` gets frozen.
*/
void rb_freeze_singleton_class(VALUE klass);

RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Expand Down Expand Up @@ -743,4 +746,16 @@ RB_OBJ_FREEZE_RAW(VALUE obj)
rb_obj_freeze_inline(obj);
}

RBIMPL_ATTR_ARTIFICIAL()
/**
* Freeze the given object if it is not frozen yet.
*
* @param[out] obj Object in question.
*/
static inline void
RB_OBJ_FREEZE(VALUE obj)
{
if (!RB_OBJ_FROZEN(obj)) RB_OBJ_FREEZE_RAW(obj);
}

#endif /* RBIMPL_FL_TYPE_H */
6 changes: 2 additions & 4 deletions include/ruby/internal/intern/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,7 @@ VALUE rb_obj_dup(VALUE obj);
VALUE rb_obj_init_copy(VALUE src, VALUE dst);

/**
* Just calls rb_obj_freeze_inline() inside. Does this make any sens to
* extension libraries?
* Same as RB_OBJ_FREEZE(), but returns the given object.
*
* @param[out] obj Object to freeze.
* @return Verbatim `obj`.
Expand All @@ -213,8 +212,7 @@ VALUE rb_obj_freeze(VALUE obj);

RBIMPL_ATTR_PURE()
/**
* Just calls RB_OBJ_FROZEN() inside. Does this make any sens to extension
* libraries?
* Same as RB_OBJ_FROZEN(), but returns #Qtrue/#Qfalse instead of #bool.
*
* @param[in] obj Object in question.
* @retval RUBY_Qtrue Yes it is.
Expand Down
1 change: 1 addition & 0 deletions internal/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ VALUE rb_keyword_error_new(const char *, VALUE);
rb_classext_t *rb_class_unlink_classext(VALUE klass, const rb_box_t *box);
void rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime);
void rb_iclass_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime);
void rb_freeze_singleton_class(VALUE attached_object);

RUBY_SYMBOL_EXPORT_BEGIN

Expand Down
2 changes: 2 additions & 0 deletions internal/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ PRINTF_ARGS(void rb_warn_deprecated_to_remove(const char *removal, const char *f
PRINTF_ARGS(void rb_warn_reserved_name(const char *removal, const char *fmt, ...), 2, 3);
#if RUBY_DEBUG
# include "ruby/version.h"
#endif
#ifdef RUBY_API_VERSION_CODE
# define RUBY_VERSION_SINCE(major, minor) (RUBY_API_VERSION_CODE >= (major) * 10000 + (minor) * 100)
# define RUBY_VERSION_BEFORE(major, minor) (RUBY_API_VERSION_CODE < (major) * 10000 + (minor) * 100)
# if defined(RBIMPL_WARNING_PRAGMA0)
Expand Down
7 changes: 1 addition & 6 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1370,12 +1370,7 @@ rb_obj_dummy1(VALUE _x, VALUE _y)
VALUE
rb_obj_freeze(VALUE obj)
{
if (!OBJ_FROZEN(obj)) {
OBJ_FREEZE(obj);
if (SPECIAL_CONST_P(obj)) {
rb_bug("special consts should be frozen.");
}
}
OBJ_FREEZE(obj);
return obj;
}

Expand Down
32 changes: 32 additions & 0 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -11736,6 +11736,12 @@ rb_str_lstrip_bang(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
str_modify_keep_cr(str);
enc = STR_ENC_GET(str);
RSTRING_GETMEM(str, start, olen);

loffset = lstrip_offset_table(str, start, start+olen, enc, table, del, nodel);
}
else {
Expand Down Expand Up @@ -11792,6 +11798,10 @@ rb_str_lstrip(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
RSTRING_GETMEM(str, start, len);

loffset = lstrip_offset_table(str, start, start+len, STR_ENC_GET(str), table, del, nodel);
}
else {
Expand Down Expand Up @@ -11880,6 +11890,12 @@ rb_str_rstrip_bang(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
str_modify_keep_cr(str);
enc = STR_ENC_GET(str);
RSTRING_GETMEM(str, start, olen);

roffset = rstrip_offset_table(str, start, start+olen, enc, table, del, nodel);
}
else {
Expand Down Expand Up @@ -11936,6 +11952,11 @@ rb_str_rstrip(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
enc = STR_ENC_GET(str);

RSTRING_GETMEM(str, start, olen);
roffset = rstrip_offset_table(str, start, start+olen, enc, table, del, nodel);
}
else {
Expand Down Expand Up @@ -11974,6 +11995,12 @@ rb_str_strip_bang(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
str_modify_keep_cr(str);
enc = STR_ENC_GET(str);
RSTRING_GETMEM(str, start, olen);

loffset = lstrip_offset_table(str, start, start+olen, enc, table, del, nodel);
roffset = rstrip_offset_table(str, start+loffset, start+olen, enc, table, del, nodel);
}
Expand Down Expand Up @@ -12037,6 +12064,11 @@ rb_str_strip(int argc, VALUE *argv, VALUE str)
VALUE del = 0, nodel = 0;

tr_setup_table_multi(table, &del, &nodel, str, argc, argv);

/* the selector conversion may have modified str */
enc = STR_ENC_GET(str);
RSTRING_GETMEM(str, start, olen);

loffset = lstrip_offset_table(str, start, start+olen, enc, table, del, nodel);
roffset = rstrip_offset_table(str, start+loffset, start+olen, enc, table, del, nodel);
}
Expand Down
17 changes: 17 additions & 0 deletions test/ruby/test_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,23 @@ def test_rstrip_bang_with_chars
assert_equal(S("abc"), a)
end

def test_strip_selector_modifying_receiver
[:strip, :strip!, :lstrip, :lstrip!, :rstrip, :rstrip!].each do |m|
s = S("-" * 100 + "abc" + "-" * 100)
obj = Object.new
obj.define_singleton_method(:to_str) do
s.clear
"-"
end

if m.end_with?("!")
assert_nil(s.public_send(m, obj), "String##{m}")
else
assert_equal("", s.public_send(m, obj), "String##{m}")
end
end
end

def test_sub
assert_equal(S("h*llo"), S("hello").sub(/[aeiou]/, S('*')))
assert_equal(S("h<e>llo"), S("hello").sub(/([aeiou])/, S('<\1>')))
Expand Down