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
38 changes: 31 additions & 7 deletions ext/strscan/lib/strscan/strscan.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
# frozen_string_literal: true

class StringScanner
# :markup: markdown
#
# call-seq:
# scan_integer(base: 10)
# scan_integer(base: 10) -> integer or nil
#
# Returns an integer scanned from `self`,
# beginning at the current position;
# returns `nil` if no such integer was available.
#
# When `base` is `10` (the default),
# equivalent to calling #scan with argument +pattern+
# as `'[+-]?\d+'`:
#
# ```ruby
# scanner = StringScanner.new('Form 27B/6')
# scanner.scan_integer # => nil # No integer at position 0.
# scanner.pos = 5
# scanner.scan_integer # => 27
# scanner.matched # => "27"
# scanner.pos # => 7
# ```
#
# If `base` isn't provided or is `10`, then it is equivalent to calling `#scan` with a `[+-]?\d+` pattern,
# and returns an Integer or nil.
# When `base` is `16` (the only other value allowed),
# equivalent to calling #scan with argument `pattern`
# as `'[+-]?(0x)?[0-9a-fA-F]+'`:
#
# If `base` is `16`, then it is equivalent to calling `#scan` with a `[+-]?(0x)?[0-9a-fA-F]+` pattern,
# and returns an Integer or nil.
# ```ruby
# scanner.pos = 5
# scanner.scan_integer(base: 16) # => 635
# scanner.matched # => "27B"
# scanner.pos # => 8
# ```
#
# The scanned string must be encoded with an ASCII compatible encoding, otherwise
# Encoding::CompatibilityError will be raised.
# Raises Encoding::CompatibilityError if `self` does not have
# an ASCII compatible encoding.
def scan_integer(base: 10)
case base
when 10
Expand Down
8 changes: 4 additions & 4 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -5471,10 +5471,10 @@ rb_file_join_ary(VALUE ary)
}
else {
tail = chompdirsep(name, name + len, true, rb_enc_get(result));
if (RSTRING_PTR(tmp) && isdirsep(RSTRING_PTR(tmp)[0])) {
if (RSTRING_LEN(tmp) > 0 && isdirsep(RSTRING_PTR(tmp)[0])) {
rb_str_set_len(result, tail - name);
}
else if (!*tail) {
else if (tail == name + len) {
rb_str_cat(result, "/", 1);
}
}
Expand Down Expand Up @@ -5518,15 +5518,15 @@ rb_file_join_fastpath(long argc, VALUE *args)
long tmp_len;
RSTRING_GETMEM(tmp, tmp_s, tmp_len);

if (isdirsep(tmp_s[0])) {
if (tmp_len > 0 && isdirsep(tmp_s[0])) {
// right side has a leading separator, remove left side separators.
long trailing_seps = 0;
while (isdirsep(name[len - trailing_seps - 1])) {
trailing_seps++;
}
rb_str_set_len(result, len - trailing_seps);
}
else if (!isdirsep(name[len - 1])) {
else if (len < 1 || !isdirsep(name[len - 1])) {
// neither side have a separator, append one;
rb_str_cat(result, "/", 1);
}
Expand Down
14 changes: 11 additions & 3 deletions io_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3509,13 +3509,21 @@ io_buffer_xor(VALUE self, VALUE mask)
struct rb_io_buffer *mask_buffer = NULL;
TypedData_Get_Struct(mask, struct rb_io_buffer, &rb_io_buffer_type, mask_buffer);

io_buffer_check_mask_size(mask_buffer->size);
const void *base;
size_t size;
io_buffer_get_bytes_for_reading(buffer, &base, &size);

VALUE output = rb_io_buffer_new(NULL, buffer->size, io_flags_for_size(buffer->size));
const void *mask_base;
size_t mask_size;
io_buffer_get_bytes_for_reading(mask_buffer, &mask_base, &mask_size);

io_buffer_check_mask_size(mask_size);

VALUE output = rb_io_buffer_new(NULL, size, io_flags_for_size(size));
struct rb_io_buffer *output_buffer = NULL;
TypedData_Get_Struct(output, struct rb_io_buffer, &rb_io_buffer_type, output_buffer);

memory_xor(output_buffer->base, buffer->base, buffer->size, mask_buffer->base, mask_buffer->size);
memory_xor(output_buffer->base, base, size, mask_base, mask_size);

return output;
}
Expand Down
2 changes: 2 additions & 0 deletions test/ruby/test_io_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ def test_operators_raise_on_freed_self
mask = IO::Buffer.for("ABCDEFGH")
assert_raise(IO::Buffer::InvalidatedError) { slice & mask }
assert_raise(IO::Buffer::InvalidatedError) { slice | mask }
assert_raise(IO::Buffer::InvalidatedError) { slice ^ mask }
end

def test_operators_raise_on_freed_mask
Expand All @@ -720,6 +721,7 @@ def test_operators_raise_on_freed_mask
source = IO::Buffer.for("ABCDEFGH")
assert_raise(IO::Buffer::InvalidatedError) { source & mask_slice }
assert_raise(IO::Buffer::InvalidatedError) { source | mask_slice }
assert_raise(IO::Buffer::InvalidatedError) { source ^ mask_slice }
end

def test_bit_count
Expand Down