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
16 changes: 12 additions & 4 deletions .github/workflows/check_misc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ jobs:
# Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN
checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)

- name: Re-generate Makefiles
run: |
# config.status needs to run as a shell script
{ echo ':&&exit'; cat tool/prereq.status; } > config.status
: # same as actions/setup/directories/action.yml
for mk in Makefile GNUmakefile; do
sed -f tool/prereq.status template/$mk.in > $mk
done

- name: Check for code styles
run: |
set -x
Expand Down Expand Up @@ -74,7 +83,6 @@ jobs:
run: |
set -- $(sed 's/#.*//;/^rdoc /!d' gems/bundled_gems)
{ echo version=$2; echo ref=$4; } >> $GITHUB_OUTPUT
echo RDOC='ruby -W0 --disable-gems tool/rdoc-srcdir -q' >> $GITHUB_ENV

- name: Checkout rdoc
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -84,7 +92,7 @@ jobs:
path: .bundle/gems/rdoc-${{ steps.rdoc.outputs.version }}
if: ${{ steps.rdoc.outputs.ref != '' }}

- name: Generate rdoc
- name: Generate rdoc scripts
run: |
set -x
gempath=$(ruby -e 'print Gem.user_dir, "/bin"')
Expand All @@ -98,12 +106,12 @@ jobs:

- name: Core docs coverage
run: |
$RDOC -C -x ^ext -x ^lib .
make XRUBY=ruby RDOC_DEPENDS= RBCONFIG=update-rbconfig rdoc-coverage

- name: Generate docs
id: docs
run: |
$RDOC --op html .
make XRUBY=ruby RDOC_DEPENDS= RBCONFIG=update-rbconfig html
echo htmlout=ruby-html-${GITHUB_SHA:0:10} >> $GITHUB_OUTPUT
# Generate only when document commit/PR
if: >-
Expand Down
13 changes: 8 additions & 5 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ HTMLOUT = $(EXTOUT)/html
CAPIOUT = doc/capi
INSTALL_DOC_OPTS = --rdoc-output="$(RDOCOUT)" --html-output="$(HTMLOUT)"
RDOC_GEN_OPTS = --no-force-update \
--exclude '^lib/rubygems/core_ext/kernel_require\.rb$$' \
$(empty)

INITOBJS = dmyext.$(OBJEXT) dmyenc.$(OBJEXT)
Expand Down Expand Up @@ -608,23 +609,24 @@ post-install-dbg::

srcs-doc: prepare-gems

rdoc: PHONY main srcs-doc
RDOC_DEPENDS = main srcs-doc
rdoc: PHONY $(RDOC_DEPENDS) $(RBCONFIG)
@echo Generating RDoc documentation
$(Q) $(RDOC) --ri --op "$(RDOCOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) .

html: PHONY main srcs-doc
html: PHONY $(RDOC_DEPENDS) $(RBCONFIG)
@echo Generating RDoc HTML files
$(Q) $(RDOC) --op "$(HTMLOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) .

RDOC_COVERAGE_EXCLUDES = -x ^ext/json -x ^ext/openssl -x ^ext/psych \
-x ^lib/bundler -x ^lib/rubygems \
-x ^lib/did_you_mean -x ^lib/error_highlight -x ^lib/syntax_suggest

rdoc-coverage: PHONY main srcs-doc
rdoc-coverage: PHONY $(RDOC_DEPENDS) $(RBCONFIG)
@echo Generating RDoc coverage report
$(Q) $(RDOC) --quiet -C $(RDOCFLAGS) $(RDOC_COVERAGE_EXCLUDES) .

undocumented: PHONY main srcs-doc
undocumented: PHONY $(RDOC_DEPENDS) $(RBCONFIG)
$(Q) $(RDOC) --quiet -C $(RDOCFLAGS) $(RDOC_COVERAGE_EXCLUDES) . | \
sed -n \
-e '/^ *# in file /{' -e 's///;N;s/\n/: /p' -e '}' \
Expand Down Expand Up @@ -1643,7 +1645,8 @@ test-bundler: $(TEST_RUNNABLE)-test-bundler
yes-test-bundler: $(PREPARE_BUNDLER)
$(gnumake_recursive)$(XRUBY) \
-r./$(arch)-fake \
-C $(srcdir) -Ispec/bundler -Ispec/lib spec/bin/rspec \
-I$(srcdir)/spec/bundler -I$(srcdir)/spec/lib \
-e 'Dir.chdir(ARGV.shift); load("spec/bin/rspec")' $(srcdir) \
-r spec_helper $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS)
no-test-bundler:

Expand Down
3 changes: 1 addition & 2 deletions doc/language/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ the option may be given more than once:
$ ruby -e 'p defined?(JSON); p defined?(CSV)'
nil
nil
$ ruby -r CSV -r JSON -e 'p defined?(JSON); p defined?(CSV)'
$ ruby -r csv -r json -e 'p defined?(JSON); p defined?(CSV)'
"constant"
"constant"
```
Expand Down Expand Up @@ -685,4 +685,3 @@ and disables input from `$stdin`.
### `--version`: Print Ruby Version

Option `--version` prints the version of the Ruby interpreter, then exits.

4 changes: 4 additions & 0 deletions ext/json/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ typedef unsigned char _Bool;
#endif

#ifndef NORETURN
#if defined(__has_attribute) && __has_attribute(noreturn)
#define NORETURN(x) __attribute__((noreturn)) x
#else
#define NORETURN(x) x
#endif
#endif

#ifndef NOINLINE
#if defined(__has_attribute) && __has_attribute(noinline)
Expand Down
76 changes: 39 additions & 37 deletions ext/json/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,7 @@ static void emit_parse_warning(const char *message, JSON_ParserState *state)

#define PARSE_ERROR_FRAGMENT_LEN 32

#ifdef RBIMPL_ATTR_NORETURN
RBIMPL_ATTR_NORETURN()
#endif
static void raise_parse_error(const char *format, JSON_ParserState *state)
NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state)
{
unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3];
long line, column;
Expand Down Expand Up @@ -449,10 +446,7 @@ static void raise_parse_error(const char *format, JSON_ParserState *state)
rb_exc_raise(exc);
}

#ifdef RBIMPL_ATTR_NORETURN
RBIMPL_ATTR_NORETURN()
#endif
static void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at)
NORETURN(static) void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at)
{
state->cursor = at;
raise_parse_error(format, state);
Expand Down Expand Up @@ -776,20 +770,39 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser
}

#define MAX_FAST_INTEGER_SIZE 18
#define MAX_NUMBER_STACK_BUFFER 128

typedef VALUE (*json_number_decode_func_t)(const char *ptr);

static VALUE json_decode_large_integer(const char *start, long len)
static inline VALUE json_decode_large_number(const char *start, long len, json_number_decode_func_t func)
{
VALUE buffer_v;
char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1);
MEMCPY(buffer, start, char, len);
buffer[len] = '\0';
VALUE number = rb_cstr2inum(buffer, 10);
RB_ALLOCV_END(buffer_v);
return number;
if (RB_LIKELY(len < MAX_NUMBER_STACK_BUFFER)) {
char buffer[MAX_NUMBER_STACK_BUFFER];
MEMCPY(buffer, start, char, len);
buffer[len] = '\0';
return func(buffer);
} else {
VALUE buffer_v = rb_str_tmp_new(len);
char *buffer = RSTRING_PTR(buffer_v);
MEMCPY(buffer, start, char, len);
buffer[len] = '\0';
VALUE number = func(buffer);
RB_GC_GUARD(buffer_v);
return number;
}
}

static inline VALUE
json_decode_integer(uint64_t mantissa, int mantissa_digits, bool negative, const char *start, const char *end)
static VALUE json_decode_inum(const char *buffer)
{
return rb_cstr2inum(buffer, 10);
}

NOINLINE(static) VALUE json_decode_large_integer(const char *start, long len)
{
return json_decode_large_number(start, len, json_decode_inum);
}

static inline VALUE json_decode_integer(uint64_t mantissa, int mantissa_digits, bool negative, const char *start, const char *end)
{
if (RB_LIKELY(mantissa_digits < MAX_FAST_INTEGER_SIZE)) {
if (negative) {
Expand All @@ -801,22 +814,14 @@ json_decode_integer(uint64_t mantissa, int mantissa_digits, bool negative, const
return json_decode_large_integer(start, end - start);
}

static VALUE json_decode_large_float(const char *start, long len)
static VALUE json_decode_dnum(const char *buffer)
{
if (RB_LIKELY(len < 64)) {
char buffer[64];
MEMCPY(buffer, start, char, len);
buffer[len] = '\0';
return DBL2NUM(rb_cstr_to_dbl(buffer, 1));
}
return DBL2NUM(rb_cstr_to_dbl(buffer, 1));
}

VALUE buffer_v;
char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1);
MEMCPY(buffer, start, char, len);
buffer[len] = '\0';
VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 1));
RB_ALLOCV_END(buffer_v);
return number;
NOINLINE(static) VALUE json_decode_large_float(const char *start, long len)
{
return json_decode_large_number(start, len, json_decode_dnum);
}

/* Ruby JSON optimized float decoder using vendored Ryu algorithm
Expand Down Expand Up @@ -868,7 +873,7 @@ static VALUE json_find_duplicated_key(size_t count, const VALUE *pairs)
return Qfalse;
}

static void emit_duplicate_key_warning(JSON_ParserState *state, VALUE duplicate_key)
NOINLINE(static) void emit_duplicate_key_warning(JSON_ParserState *state, VALUE duplicate_key)
{
VALUE message = rb_sprintf(
"detected duplicate key %"PRIsVALUE" in JSON object. This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`",
Expand All @@ -879,10 +884,7 @@ static void emit_duplicate_key_warning(JSON_ParserState *state, VALUE duplicate_
RB_GC_GUARD(message);
}

#ifdef RBIMPL_ATTR_NORETURN
RBIMPL_ATTR_NORETURN()
#endif
static void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_key)
NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_key)
{
VALUE message = rb_sprintf(
"duplicate key %"PRIsVALUE,
Expand Down
7 changes: 4 additions & 3 deletions lib/rubygems/gemcutter_utilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,11 @@ def update_scope(scope)

def sign_in(sign_in_host = nil, scope: nil)
sign_in_host ||= host
return if api_key

pretty_host = pretty_host(sign_in_host)

if api_key
say "You are already signed in on #{pretty_host}."
return
end
say "Enter your #{pretty_host} credentials."
say "Don't have an account yet? " \
"Create one at #{sign_in_host}/sign_up"
Expand Down
6 changes: 6 additions & 0 deletions spec/bundler/commands/clean_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -934,5 +934,11 @@ def should_not_have_gems(*gems)
bundle :clean

should_have_gems "bundler-#{version}"
ensure
["bundler-#{version}.gem", "bundler-#{version}.gemspec"].each do |filename|
Pathname(vendored_gems(filename)).tap do |path|
FileUtils.rm_rf(path.basename)
end
end
end
end
4 changes: 4 additions & 0 deletions test/json/json_parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ def test_parse_bignum
bignum = Integer('1234567890' * 10)
assert_equal(bignum, JSON.parse(bignum.to_s))
assert_equal(bignum.to_f, JSON.parse(bignum.to_s + ".0"))

bignum = Integer('1234567890' * 50)
assert_equal(bignum, JSON.parse(bignum.to_s))
assert_equal(bignum.to_f, JSON.parse(bignum.to_s + ".0"))
end

def test_parse_bigdecimals
Expand Down
4 changes: 2 additions & 2 deletions test/rubygems/test_gem_gemcutter_utilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ def test_sign_in_skips_with_existing_credentials

util_sign_in

assert_equal "", @sign_in_ui.output
assert_match(/You are already signed in/, @sign_in_ui.output)
end

def test_sign_in_skips_with_key_override
Gem.configuration.api_keys[:KEY] = "other"
@cmd.options[:key] = :KEY
util_sign_in

assert_equal "", @sign_in_ui.output
assert_match(/You are already signed in/, @sign_in_ui.output)
end

def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
Expand Down
Loading