summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/file/filename_matching.md208
-rw-r--r--ext/json/json.h8
-rw-r--r--ext/json/parser/parser.c22
-rw-r--r--io.c4
-rw-r--r--io_buffer.c12
-rw-r--r--sprintf.c44
-rw-r--r--test/.excludes-mmtk/TestObjSpace.rb1
-rw-r--r--test/ruby/test_io_buffer.rb9
-rw-r--r--test/ruby/test_sprintf.rb6
9 files changed, 237 insertions, 77 deletions
diff --git a/doc/file/filename_matching.md b/doc/file/filename_matching.md
index cf5b60bac2..fca02f1d83 100644
--- a/doc/file/filename_matching.md
+++ b/doc/file/filename_matching.md
@@ -41,17 +41,30 @@ see the table above.
A simple string matches itself:
```ruby
-File.fnmatch('xyzzy', 'xyzzy') # => true
-File.fnmatch('one_two_three', 'one_two_three') # => true
-File.fnmatch('123', '123') # => true
-File.fnmatch('Form 27B/6', 'Form 27B/6') # => true
-File.fnmatch('bcd', 'abcde') # => false # Must be exact.
+File.fnmatch('xyzzy', 'xyzzy') # => true
+File.fnmatch('one_two_three', 'one_two_three') # => true
+File.fnmatch('123', '123') # => true
+File.fnmatch('Form 27B/6', 'Form 27B/6') # => true
+
+Pathname('xyzzy').fnmatch('xyzzy') # => true
+Pathname('one_two_three').fnmatch('one_two_three') # => true
+Pathname('123').fnmatch('123') # => true
+Pathname('Form 27B/6').fnmatch('Form 27B/6') # => true
+
+# Must be exact.
+pattern = 'abcde'
+path = 'abc'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
By default, the matching is case-sensitive:
```ruby
-File.fnmatch('abc', 'ABC') # => false
+pattern = 'abc'
+path = 'ABC'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
Case-sensitivity may be modified by flags:
@@ -61,8 +74,11 @@ Case-sensitivity may be modified by flags:
By default, the alternatives pattern is disabled:
-```rutby
-File.fnmatch('R{ub,foo}y', 'Ruby') # => false
+```ruby
+pattern = 'R{ub,foo}y'
+path = 'Ruby'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
It may be enabled by flag [`File::FNM_EXTGLOB`](#constant-filefnmextglob).
@@ -70,7 +86,10 @@ It may be enabled by flag [`File::FNM_EXTGLOB`](#constant-filefnmextglob).
By default, the Windows short name pattern is disabled:
```ruby
-File.fnmatch('PROGRAM~1', 'Program Files') # => false
+pattern ='PROGRAM~1'
+path = 'Program Files'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
It may be enabled by flag [`File::FNM_SHORTNAME`](#constant-filefnmshortname).
@@ -80,16 +99,31 @@ It may be enabled by flag [`File::FNM_SHORTNAME`](#constant-filefnmshortname).
The asterisk pattern (`'*'`) matches any sequence of characters:
```ruby
-File.fnmatch('*', 'foo') # => true
-File.fnmatch('*', '') # => true
-File.fnmatch('*', '*') # => true
-File.fnmatch('\*', 'foo') # => false # Escaped.
+pattern = '*'
+File.fnmatch(pattern, 'foo') # => true
+File.fnmatch(pattern, '') # => true
+File.fnmatch(pattern, 'foo') # => true
+
+Pathname('foo').fnmatch(pattern) # => true
+Pathname('').fnmatch(pattern) # => true
+Pathname('*').fnmatch(pattern) # => true
+```
+
+The pattern may be escaped:
+
+```ruby
+pattern = '\*'
+File.fnmatch(pattern, 'foo') # => false
+Pathname('foo').fnmatch(pattern) # => false
```
By default, the asterisk pattern does not match a leading period (as in a dot-file):
```ruby
-File.fnmatch('*', '.document') # => false
+pattern = '*'
+path = '.document'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
That matching may be enabled by flag [`File::FNM_DOTMATCH`](#constant-filefnmdotmatch).
@@ -97,7 +131,10 @@ That matching may be enabled by flag [`File::FNM_DOTMATCH`](#constant-filefnmdot
By default, the asterisk pattern matches across file separators:
```ruby
-File.fnmatch('*.rb', 'lib/test.rb') # => true
+pattern = '*.rb'
+path = 'lib/test.rb'
+File.fnmatch(pattern, path) # => true
+Pathname(path).fnmatch(pattern) # => true
```
That matching may be disabled by flag [`File::FNM_PATHNAME`](#constant-filefnmpathname).
@@ -107,17 +144,37 @@ That matching may be disabled by flag [`File::FNM_PATHNAME`](#constant-filefnmpa
The question-mark pattern (`'?'`) matches any single character:
```ruby
-File.fnmatch('?', 'f') # => true
-File.fnmatch("foo-?.txt", "foo-1.txt") # => true
-File.fnmatch('?', 'foo') # => false
-File.fnmatch('?', '') # => false
-File.fnmatch('\?', 'f') # => false # Escaped.
+pattern = '?'
+File.fnmatch(pattern, 'f') # => true
+File.fnmatch(pattern, '') # => false
+File.fnmatch(pattern, 'foo') # => false
+
+Pathname('f').fnmatch(pattern) # => true
+Pathname('').fnmatch(pattern) # => false
+Pathname('foo').fnmatch(pattern) # => false
+
+pattern = 'foo-?.txt'
+path = 'foo-1.txt'
+File.fnmatch(pattern, path) # => true
+Pathname(path).fnmatch(pattern) # => true
+```
+
+The pattern may be escaped:
+
+```ruby
+pattern = '\?'
+path = 'f'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
By default, pattern `'?'` matches the file separator:
```ruby
-File.fnmatch('foo?boo', 'foo/boo') # => true
+pattern = 'foo?bar'
+path = 'foo/bar'
+File.fnmatch(pattern, path) # => true
+Pathname(path).fnmatch(pattern) # => true
```
That matching may be disabled by flag [`File::FNM_PATHNAME`](#constant-filefnmpathname).
@@ -128,18 +185,40 @@ Characters enclosed in square brackets define a set of characters,
any of which matches a single character:
```ruby
-File.fnmatch('[ruby]', 'r') # => true
-File.fnmatch('[ruby]', 'u') # => true
-File.fnmatch('[ruby]', 'y') # => true
-File.fnmatch('[ruby]', 'ruby') # => false
-File.fnmatch('\[ruby]', 'r') # => false # Escaped.
+pattern = '[ruby]'
+File.fnmatch(pattern, 'r') # => true
+File.fnmatch(pattern, 'u') # => true
+File.fnmatch(pattern, 'y') # => true
+
+Pathname('r').fnmatch(pattern) # => true
+Pathname('u').fnmatch(pattern) # => true
+Pathname('y').fnmatch(pattern) # => true
+
+# Matches a single character.
+pattern = '[ruby]'
+path = 'ruby'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
+```
+
+The pattern may be escaped:
+
+```ruby
+pattern = '\[ruby]'
+path = 'r'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
The character set may be negated:
```ruby
-File.fnmatch('[^ruby]', 'r') # => false
-File.fnmatch('[^ruby]', 'u') # => false
+pattern = '[^ruby]'
+File.fnmatch(pattern, 'r') # => false
+File.fnmatch(pattern, 'u') # => false
+
+Pathname('r').fnmatch(pattern) # => false
+Pathname('u').fnmatch(pattern) # => false
```
### Single Character from a \Range (`'[a-c]'`, `'[^a-c]'`)
@@ -148,18 +227,42 @@ A range of characters enclosed in square brackets defines a set of characters,
any of which matches a single character:
```ruby
-File.fnmatch('[a-c]', 'b') # => true
-File.fnmatch('[a-c]', 'd') # => false
-File.fnmatch('[a-c]', 'abc') # => false
-File.fnmatch('R[t-v][a-c]y', 'Ruby') # => true # Multiple ranges allowed.
-File.fnmatch('\[a-c]', 'b') # => false # Escaped.
+pattern = '[a-c]'
+File.fnmatch(pattern, 'b') # => true
+File.fnmatch(pattern, 'd') # => false
+File.fnmatch(pattern, 'abc') # => false
+
+Pathname('b').fnmatch(pattern) # => true
+Pathname('d').fnmatch(pattern) # => false
+Pathname('abc').fnmatch(pattern) # => false
+```
+
+The pattern may be escaped:
+
+```ruby
+pattern = '\[a-c]'
+path = 'b'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
+
+```
+
+Multiple ranges are allowed:
+
+```ruby
+pattern = 'R[t-v][a-c]y'
+path = 'Ruby'
+File.fnmatch(pattern, path) # => true
+Pathname(path).fnmatch(pattern) # => true
```
The range may be negated:
```ruby
-File.fnmatch('[^a-c]', 'b') # => false
-File.fnmatch('[^a-c]', 'd') # => true
+pattern = '[^a-c]'
+path = 'b'
+File.fnmatch(pattern, path) # => false
+Pathname(path).fnmatch(pattern) # => false
```
### Escape (`'\'`)
@@ -168,21 +271,36 @@ The backslash character (`'\'`) may be used to escape any of the characters
that filename matching treats as special:
```ruby
-File.fnmatch('[a-c]', 'b') # => true
-File.fnmatch('\[a-c]', 'b') # => false
-File.fnmatch('[a-c\]', 'b') # => false
-File.fnmatch('[a\-c]', 'b') # => false
-
-File.fnmatch('{a,b}', 'b', File::FNM_EXTGLOB) # => true
-File.fnmatch('\{a,b}', 'b', File::FNM_EXTGLOB) # => false
-File.fnmatch('{a\,b}', 'b', File::FNM_EXTGLOB) # => false
-File.fnmatch('{a,b\}', 'b', File::FNM_EXTGLOB) # => false
+path = 'b'
+File.fnmatch('[a-c]', path) # => true
+File.fnmatch('\[a-c]', path) # => false
+File.fnmatch('[a-c\]', path) # => false
+File.fnmatch('[a\-c]', path) # => false
+
+Pathname(path).fnmatch('[a-c]') # => true
+Pathname(path).fnmatch('\[a-c]') # => false
+Pathname(path).fnmatch('[a-c\]') # => false
+Pathname(path).fnmatch('[a\-c]') # => false
+
+File.fnmatch('{a,b}', path, File::FNM_EXTGLOB) # => true
+File.fnmatch('\{a,b}', path, File::FNM_EXTGLOB) # => false
+File.fnmatch('{a\,b}', path, File::FNM_EXTGLOB) # => false
+File.fnmatch('{a,b\}', path, File::FNM_EXTGLOB) # => false
+
+Pathname(path).fnmatch('{a,b}', File::FNM_EXTGLOB) # => true
+Pathname(path).fnmatch('\{a,b}', File::FNM_EXTGLOB) # => false
+Pathname(path).fnmatch('{a,b\}', File::FNM_EXTGLOB) # => false
+Pathname(path).fnmatch('{a\,b}', File::FNM_EXTGLOB) # => false
+
```
Use a double-backslash to represent an ordinary backslash:
```ruby
-File.fnmatch('\\\\', '\\') # => true
+pattern = '\\\\'
+path = '\\'
+File.fnmatch(pattern, path) # => true
+Pathname(path).fnmatch(pattern) # => true
```
By default escape pattern `'\'` is enabled;
diff --git a/ext/json/json.h b/ext/json/json.h
index cf9420d4dd..78b0eee0a4 100644
--- a/ext/json/json.h
+++ b/ext/json/json.h
@@ -11,6 +11,9 @@
#if defined(RUBY_DEBUG) && RUBY_DEBUG
# define JSON_ASSERT RUBY_ASSERT
+# ifndef JSON_DEBUG
+# define JSON_DEBUG 1
+# endif
#else
# ifdef JSON_DEBUG
# include <assert.h>
@@ -20,6 +23,11 @@
# endif
#endif
+#ifdef JSON_DEBUG
+# define JSON_UNREACHABLE_RETURN(val) rb_bug("Unreachable")
+#else
+# define JSON_UNREACHABLE_RETURN UNREACHABLE_RETURN
+#endif
/* shims */
#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG
diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c
index c0631728c3..6b8164c062 100644
--- a/ext/json/parser/parser.c
+++ b/ext/json/parser/parser.c
@@ -488,7 +488,7 @@ static const rb_data_type_t JSON_Parser_frame_stack_type = {
.dfree = json_frame_stack_free,
.dsize = json_frame_stack_memsize,
},
- .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE,
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE,
};
static json_frame_stack *json_frame_stack_spill(json_frame_stack *old_stack, VALUE *handle, json_frame_stack **stack_ref)
@@ -1489,7 +1489,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
case JSON_PHASE_OBJECT_KEY: goto JSON_PHASE_OBJECT_KEY;
case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON;
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
JSON_PHASE_DONE: {
// The root document value is parsed; it is the lone survivor on
@@ -1623,10 +1623,10 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA;
case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA;
case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE;
- case JSON_PHASE_OBJECT_KEY: UNREACHABLE_RETURN(Qundef);
+ case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(Qundef);
case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON;
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
JSON_PHASE_OBJECT_KEY: {
@@ -1648,7 +1648,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
raise_parse_error("expected object key, got: %s", state);
}
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
JSON_PHASE_OBJECT_COLON: {
@@ -1669,7 +1669,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
raise_parse_error("expected ':' after object key, got: %s", state);
}
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
JSON_PHASE_ARRAY_COMMA: {
@@ -1705,13 +1705,13 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA;
case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA;
case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE;
- case JSON_PHASE_OBJECT_KEY: UNREACHABLE_RETURN(Qundef);
+ case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(Qundef);
case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON;
}
} else {
raise_parse_error("expected ',' or ']' after array value", state);
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
JSON_PHASE_OBJECT_COMMA: {
@@ -1754,16 +1754,16 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA;
case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA;
case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE;
- case JSON_PHASE_OBJECT_KEY: UNREACHABLE_RETURN(Qundef);
+ case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(Qundef);
case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON;
}
} else {
raise_parse_error("expected ',' or '}' after object value, got: %s", state);
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
- UNREACHABLE_RETURN(Qundef);
+ JSON_UNREACHABLE_RETURN(Qundef);
}
static void json_ensure_eof(JSON_ParserState *state)
diff --git a/io.c b/io.c
index effcb349c3..f121167102 100644
--- a/io.c
+++ b/io.c
@@ -8798,14 +8798,14 @@ rb_io_print(int argc, const VALUE *argv, VALUE out)
*
* Writes the given objects to <tt>$stdout</tt>; returns +nil+.
* Appends the output record separator <tt>$OUTPUT_RECORD_SEPARATOR</tt>
- * <tt>$\\</tt>), if it is not +nil+.
+ * (<tt>$\\</tt>), if it is not +nil+.
*
* With argument +objects+ given, for each object:
*
* - Converts via its method +to_s+ if not a string.
* - Writes to <tt>stdout</tt>.
* - If not the last object, writes the output field separator
- * <tt>$OUTPUT_FIELD_SEPARATOR</tt> (<tt>$,</tt> if it is not +nil+.
+ * <tt>$OUTPUT_FIELD_SEPARATOR</tt> (<tt>$,</tt>) if it is not +nil+.
*
* With default separators:
*
diff --git a/io_buffer.c b/io_buffer.c
index faa5304248..d9f50fc234 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -3625,6 +3625,10 @@ io_buffer_and_inplace(VALUE self, VALUE mask)
size_t size;
io_buffer_get_bytes_for_writing(buffer, &base, &size);
+ const void *mask_base;
+ size_t mask_size;
+ io_buffer_get_bytes_for_reading(mask_buffer, &mask_base, &mask_size);
+
memory_and_inplace(base, size, mask_buffer->base, mask_buffer->size);
return self;
@@ -3671,6 +3675,10 @@ io_buffer_or_inplace(VALUE self, VALUE mask)
size_t size;
io_buffer_get_bytes_for_writing(buffer, &base, &size);
+ const void *mask_base;
+ size_t mask_size;
+ io_buffer_get_bytes_for_reading(mask_buffer, &mask_base, &mask_size);
+
memory_or_inplace(base, size, mask_buffer->base, mask_buffer->size);
return self;
@@ -3717,6 +3725,10 @@ io_buffer_xor_inplace(VALUE self, VALUE mask)
size_t size;
io_buffer_get_bytes_for_writing(buffer, &base, &size);
+ const void *mask_base;
+ size_t mask_size;
+ io_buffer_get_bytes_for_reading(mask_buffer, &mask_base, &mask_size);
+
memory_xor_inplace(base, size, mask_buffer->base, mask_buffer->size);
return self;
diff --git a/sprintf.c b/sprintf.c
index 234aff76f5..b91d758957 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -65,18 +65,30 @@ sign_bits(int base, const char *p)
#define FPREC 64
#define FPREC0 128
+static long
+expand_result(VALUE result, long bsiz, long blen, long l)
+{
+ int cr = ENC_CODERANGE(result);
+ RUBY_ASSERT(bsiz >= blen);
+ while (l > bsiz - blen) {
+ bsiz *= 2;
+ if (bsiz < 0) rb_raise(rb_eArgError, "too big specifier");
+ }
+ rb_str_resize(result, bsiz);
+ ENC_CODERANGE_SET(result, cr);
+ return bsiz;
+}
+
#define CHECK(l) do {\
- int cr = ENC_CODERANGE(result);\
- RUBY_ASSERT(bsiz >= blen); \
- while ((l) > bsiz - blen) {\
- bsiz*=2;\
- if (bsiz<0) rb_raise(rb_eArgError, "too big specifier");\
- }\
- rb_str_resize(result, bsiz);\
- ENC_CODERANGE_SET(result, cr);\
+ bsiz = expand_result(result, bsiz, blen, l);\
buf = RSTRING_PTR(result);\
} while (0)
+#define CHECK_WIDTH(l, w) do { \
+ if ((l) > INT_MAX - (w)) rb_raise(rb_eArgError, "width too big");\
+ CHECK((l)+(w));\
+} while (0)
+
#define PUSH(s, l) do { \
CHECK(l);\
PUSH_(s, l);\
@@ -469,19 +481,13 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
rb_enc_mbcput(c, &buf[blen], enc);
blen += n;
}
- else if ((flags & FMINUS)) {
- --width;
- CHECK(n + (width > 0 ? width : 0));
- rb_enc_mbcput(c, &buf[blen], enc);
- blen += n;
- if (width > 0) FILL_(' ', width);
- }
else {
--width;
- CHECK(n + (width > 0 ? width : 0));
- if (width > 0) FILL_(' ', width);
+ CHECK_WIDTH(n, (width > 0 ? width : 0));
+ if (!(flags & FMINUS) && (width > 0)) FILL_(' ', width);
rb_enc_mbcput(c, &buf[blen], enc);
blen += n;
+ if ((flags & FMINUS) && (width > 0)) FILL_(' ', width);
}
}
break;
@@ -518,7 +524,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
/* need to adjust multi-byte string pos */
if ((flags&FWIDTH) && (width > slen)) {
width -= (int)slen;
- CHECK(len + width);
+ CHECK_WIDTH(len, width);
if (!(flags&FMINUS)) {
FILL_(' ', width);
width = 0;
@@ -832,7 +838,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (sign || (flags&FSPACE)) ++len;
if (prec > 0) ++len; /* period */
fill = width > len ? width - len : 0;
- CHECK(fill + len);
+ CHECK(fill + len); /* max(width, len) */
if (fill && !(flags&(FMINUS|FZERO))) {
FILL_(' ', fill);
}
diff --git a/test/.excludes-mmtk/TestObjSpace.rb b/test/.excludes-mmtk/TestObjSpace.rb
index 94eb2c436d..feb05063df 100644
--- a/test/.excludes-mmtk/TestObjSpace.rb
+++ b/test/.excludes-mmtk/TestObjSpace.rb
@@ -2,3 +2,4 @@ exclude(:test_dump_all_full, "testing behaviour specific to default GC")
exclude(:test_dump_flag_age, "testing behaviour specific to default GC")
exclude(:test_dump_flags, "testing behaviour specific to default GC")
exclude(:test_dump_objects_dumps_page_slot_sizes, "testing behaviour specific to default GC")
+exclude(:test_trace_object_allocations_does_not_reuse_freed_allocation_info, "hang up")
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index b6372f25b8..327a3ece9c 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -712,6 +712,10 @@ class TestIOBuffer < Test::Unit::TestCase
assert_raise(IO::Buffer::InvalidatedError) { slice | mask }
assert_raise(IO::Buffer::InvalidatedError) { slice ^ mask }
assert_raise(IO::Buffer::InvalidatedError) { ~slice }
+
+ assert_raise(IO::Buffer::InvalidatedError) { slice.and!(mask) }
+ assert_raise(IO::Buffer::InvalidatedError) { slice.or!(mask) }
+ assert_raise(IO::Buffer::InvalidatedError) { slice.xor!(mask) }
end
def test_operators_raise_on_freed_mask
@@ -723,6 +727,11 @@ class TestIOBuffer < Test::Unit::TestCase
assert_raise(IO::Buffer::InvalidatedError) { source & mask_slice }
assert_raise(IO::Buffer::InvalidatedError) { source | mask_slice }
assert_raise(IO::Buffer::InvalidatedError) { source ^ mask_slice }
+
+ source = source.dup
+ assert_raise(IO::Buffer::InvalidatedError) { source.and!(mask_slice) }
+ assert_raise(IO::Buffer::InvalidatedError) { source.or!(mask_slice) }
+ assert_raise(IO::Buffer::InvalidatedError) { source.xor!(mask_slice) }
end
def test_bit_count
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index 1c7e89c265..bbbe6e7ec3 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
+require 'rbconfig/sizeof'
class TestSprintf < Test::Unit::TestCase
def test_positional
@@ -539,6 +540,11 @@ class TestSprintf < Test::Unit::TestCase
def test_width_underflow
bug = 'https://github.com/mruby/mruby/issues/3347'
assert_equal("!", sprintf("%*c", 0, ?!.ord), bug)
+
+ int_max = RbConfig::LIMITS["INT_MAX"]
+ assert_raise_with_message(ArgumentError, /width too big/) {
+ sprintf "%*c", int_max, 0x80
+ }
end
def test_negative_width_overflow