From 63330ae4ac4b153f2ef370a5d25e93231e15f064 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Thu, 26 May 2022 15:39:07 -0400 Subject: [PATCH 001/142] Change ROBJECT_TRANSIENT_FLAG to use FL_USER2 --- internal/variable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/variable.h b/internal/variable.h index 4b67bef9078556..1a19e8964b9f8e 100644 --- a/internal/variable.h +++ b/internal/variable.h @@ -16,7 +16,7 @@ /* global variable */ -#define ROBJECT_TRANSIENT_FLAG FL_USER13 +#define ROBJECT_TRANSIENT_FLAG FL_USER2 /* variable.c */ void rb_gc_mark_global_tbl(void); From 382cde96fa34c776717925e7598bc32dde549195 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 16:54:11 +0000 Subject: [PATCH 002/142] [rubygems/rubygems] Bump rb-sys Bumps [rb-sys](https://github.com/oxidize-rb/rb-sys) from 0.9.20 to 0.9.26. - [Release notes](https://github.com/oxidize-rb/rb-sys/releases) - [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.20...v0.9.26) --- updated-dependencies: - dependency-name: rb-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] https://github.com/rubygems/rubygems/commit/fe76234cf1 --- .../rust_ruby_example/Cargo.lock | 12 ++++++------ .../rust_ruby_example/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock index 497686123119b1..376d11cf3e4861 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -98,9 +98,9 @@ dependencies = [ [[package]] name = "linkify" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d9967eb7d0bc31c39c6f52e8fce42991c0cd1f7a2078326f0b7a399a584c8d" +checksum = "96dd5884008358112bc66093362197c7248ece00d46624e2cf71e50029f8cff5" dependencies = [ "memchr", ] @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.20" +version = "0.9.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe4bf82794b8d3c995847a710da279afcd3bee40b993cd3296af259e5933c4" +checksum = "723f7560e878bec9d1d49538a17fb6a4e3a04688c1dc6f14eef17918634a54e4" dependencies = [ "bindgen", "linkify", @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "rb-sys-build" -version = "0.9.20" +version = "0.9.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb614fa1ac5a7a96685537f123201b727dfa39e7e54e46c1027b3477266be93d" +checksum = "2ccd93f0d9767385cd7a23076c47e3dca4c86144e510ea4c61d04dbce0cbac7e" dependencies = [ "regex", "shell-words", diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml index 357e5f60e405f4..7d3cd133a81b67 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = { version = "0.9.20", features = ["gem"] } +rb-sys = { version = "0.9.26", features = ["gem"] } From 43c11f6c4973e5e79043c90faee1ffc2019becc2 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Mon, 25 Jul 2022 14:58:41 -0500 Subject: [PATCH 003/142] For rdoc, copy doc/rdoc to doc/ (#6181) --- tool/sync_default_gems.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index e5821898afa766..47f6f1c840025a 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -128,6 +128,7 @@ def sync_default_gems(gem) when "rdoc" rm_rf(%w[lib/rdoc lib/rdoc.rb test/rdoc libexec/rdoc libexec/ri]) cp_r(Dir.glob("#{upstream}/lib/rdoc*"), "lib") + cp_r("#{upstream}/doc/rdoc", "doc") cp_r("#{upstream}/test/rdoc", "test") cp_r("#{upstream}/rdoc.gemspec", "lib/rdoc") cp_r("#{upstream}/Gemfile", "lib/rdoc") From 8fa66467de82f787ead9dd901ad06694c79d88dc Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 25 Jul 2022 15:49:11 -0400 Subject: [PATCH 004/142] Fix sync_default_gems.rb to use absolute path --- tool/sync_default_gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index 47f6f1c840025a..a33c056861c417 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -88,7 +88,7 @@ def sync_default_gems(gem) repo = REPOSITORIES[gem.to_sym] puts "Sync #{repo}" - upstream = File.join("..", "..", repo) + upstream = File.join(__dir__, "../..", repo) case gem when "rubygems" From ba098fa151bd842215d4840107b57fc0253c7ecf Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 25 Jul 2022 15:51:08 -0400 Subject: [PATCH 005/142] Sync RDoc --- doc/rdoc/markup_reference.rb | 916 +++++++++++++++++++++++++++++++++++ lib/rdoc/rdoc.gemspec | 5 - 2 files changed, 916 insertions(+), 5 deletions(-) create mode 100644 doc/rdoc/markup_reference.rb diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb new file mode 100644 index 00000000000000..74594e54833029 --- /dev/null +++ b/doc/rdoc/markup_reference.rb @@ -0,0 +1,916 @@ +require 'rdoc' + +# \Class \RDoc::MarkupReference exists only to provide a suitable home +# for a reference document for \RDoc markup. +# +# All objects defined in this class -- classes, modules, methods, aliases, +# attributes, and constants -- are solely for illustrating \RDoc markup, +# and have no other legitimate use. +# +# = \RDoc Markup Reference +# +# [Note] +# +# Examples in this reference are Ruby code and comments. +# Certain differences among the sources are noted. +# +# \RDoc-generated documentation is derived from and controlled by: +# +# - Single-line or multi-line comments that precede certain definitions. +# - \RDoc directives in trailing comments (on the same line as code). +# - The Ruby code itself. +# +# == Markup in Comments +# +# A single-line or multi-line comment that immediately precedes +# the definition of a class, module, method, alias, constant, or attribute +# becomes the documentation for that defined object. +# +# (\RDoc ignores other such comments that do not precede definitions.) +# +# === Margins +# +# In a multi-line comment, +# \RDoc looks for the comment's natural left margin, +# which becomes the base margin for the comment +# and is the initial current margin for for the comment. +# +# The current margin can change, and does so, for example in a list. +# +# === Blocks +# +# It's convenient to think of markup input as a sequence of _blocks_, +# such as: +# +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Bullet lists}[rdoc-ref:RDoc::MarkupReference@Bullet+Lists]. +# - {Numbered lists}[rdoc-ref:RDoc::MarkupReference@Numbered+Lists]. +# - {Lettered lists}[rdoc-ref:RDoc::MarkupReference@Lettered+Lists]. +# - {Labeled lists}[rdoc-ref:RDoc::MarkupReference@Labeled+Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. +# +# All of these except paragraph blocks are distinguished by indentation, +# or by unusual initial or embedded characters. +# +# ==== Paragraphs +# +# A paragraph consists of one or more non-empty lines of ordinary text, +# each beginning at the current margin. +# +# Note: Here, ordinary text means text that is not identified +# by indentation, or by unusual initial or embedded characters. +# See below. +# +# Paragraphs are separated by one or more empty lines. +# +# Example input: +# +# # \RDoc produces HTML and command-line documentation for Ruby projects. +# # \RDoc includes the rdoc and ri tools for generating and displaying +# # documentation from the command-line. +# # +# # You'll love it. +# +# Rendered HTML: +# +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. +# +# You'll love it. +# +# A paragraph may contain nested blocks, including: +# +# - Verbatim text blocks. +# - Code blocks. +# - Lists of any type. +# +# ==== Verbatim Text Blocks +# +# Text indented farther than the current margin becomes a verbatim text block +# (or a code block, described next). +# In the rendered HTML, such text: +# +# - Is indented. +# - Has a contrasting background color. +# +# The verbatim text block ends at the first line beginning at the current margin. +# +# Example input: +# +# # This is not verbatim text. +# # +# # This is verbatim text. +# # Whitespace is honored. # See? +# # Whitespace is honored. # See? +# # +# # This is still the same verbatim text block. +# # +# # This is not verbatim text. +# +# Rendered HTML: +# +# This is not verbatim text. +# +# This is verbatim text. +# Whitespace is honored. # See? +# Whitespace is honored. # See? +# +# This is still the same verbatim text block. +# +# This is not verbatim text. +# ==== Code Blocks +# +# A special case of verbatim text is the code block, +# which is merely verbatim text that \RDoc recognizes as Ruby code: +# +# In the rendered HTML, the code block: +# +# - Is indented. +# - Has a contrasting background color. +# - Has syntax highlighting. +# +# Example: +# +# def foo(name = '', value = 0) +# @name = name # Whitespace is still honored. +# @value = value +# end +# +# Pro tip: If your indented Ruby code does not get highlighted, +# it may contain a syntax error. +# +# ==== Lists +# +# Each type of list item is marked by a special beginning: +# +# - Bullet list item: Begins with a hyphen or asterisk. +# - Numbered list item: Begins with digits and a period. +# - Lettered list item: Begins with an alphabetic character and a period. +# - Labeled list item: Begins with one of: +# - Square-bracketed text. +# - A word followed by two colons. +# +# A list begins with a list item and continues, even across blank lines, +# as long as list items of the same type are found at the same indentation level. +# +# A new list resets the current margin inward. +# Additional lines of text aligned at that margin +# are part of the continuing list item. +# +# A list item may be continued on additional lines that are aligned +# with the first line. See examples below. +# +# ===== Bullet Lists +# +# A bullet list item begins with a hyphen or asterisk. +# +# Example input: +# +# # - An item. +# # - Another. +# # - An item spanning +# # multiple lines. +# # +# # * Yet another. +# # - Last one. +# +# Rendered HTML: +# +# - An item. +# - Another. +# - An item spanning +# multiple lines. +# +# * Yet another. +# - Last one. +# +# ===== Numbered Lists +# +# A numbered list item begins with digits and a period. +# +# The items are automatically re-numbered. +# +# Example input: +# +# # 100. An item. +# # 10. Another. +# # 1. An item spanning +# # multiple lines. +# # +# # 1. Yet another. +# # 1000. Last one. +# +# Rendered HTML: +# +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. +# +# 1. Yet another. +# 1000. Last one. +# +# ===== Lettered Lists +# +# A numbered list item begins with a letters and a period. +# +# The items are automatically "re-lettered." +# +# Example input: +# +# # z. An item. +# # y. Another. +# # x. An item spanning +# # multiple lines. +# # +# # x. Yet another. +# # a. Last one. +# +# Rendered HTML: +# +# z. An item. +# y. Another. +# +# x. Yet another. +# a. Last one. +# +# ===== Labeled Lists +# +# A labeled list item begins with one of: +# +# - Square-bracketed text: the label and text are on two lines. +# - A word followed by two colons: the label and text are on the same line. +# +# Example input: +# +# # [foo] An item. +# # bat:: Another. +# # [bag] An item spanning +# # multiple lines. +# # +# # [bar baz] Yet another. +# # bam:: Last one. +# +# Rendered HTML: +# +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. +# +# [bar baz] Yet another. +# bam:: Last one. +# +# ===== Blocks Nested in Lists +# +# A list item may contain nested blocks, including: +# +# - Paragraphs. +# - Verbatim text blocks. +# - Code blocks. +# - Other lists of any type. +# +# ==== Headings +# +# A heading begins with up to six equal-signs, followed by heading text. +# Whitespace between those and the heading text is optional. +# +# Examples: +# +# # = Section 1 +# # == Section 1.1 +# # === Section 1.1.1 +# # === Section 1.1.2 +# # == Section 1.2 +# # = Section 2 +# # = Foo +# # == Bar +# # === Baz +# # ==== Bam +# # ===== Bat +# # ====== Bad +# # ============Still a Heading (Level 6) +# # \== Not a Heading +# +# ==== Horizontal Rules +# +# A horizontal rule begins with three or more hyphens. +# +# Example input: +# +# # ------ +# # Stuff between. +# # +# # \--- Not a horizontal rule. +# # +# # -- Also not a horizontal rule. +# # +# # --- +# +# Rendered HTML: +# +# ------ +# Stuff between. +# +# \--- Not a horizontal rule. +# +# -- Also not a horizontal rule. +# +# --- +# +# === Text Markup +# +# Text in a paragraph, list item (any type), or heading +# may have markup formatting. +# +# ==== Italic +# +# A single word may be italicized by prefixed and suffixed underscores. +# +# Examples: +# +# # _Word_ in paragraph. +# # - _Word_ in bullet list item. +# # 1. _Word_ in numbered list item. +# # a. _Word_ in lettered list item. +# # [_word_] _Word_ in labeled list item. +# # ====== _Word_ in heading +# +# Any text may be italicized via HTML tag +i+ or +em+. +# +# Examples: +# +# # Two words in paragraph. +# # - Two words in bullet list item. +# # 1. Two words in numbered list item. +# # a. Two words in lettered list item. +# # [Two words] Two words in labeled list item. +# # ====== Two words in heading +# +# ==== Bold +# +# A single word may be made bold by prefixed and suffixed asterisks. +# +# Examples: +# +# # *Word* in paragraph. +# # - *Word* in bullet list item. +# # 1. *Word* in numbered list item. +# # a. *Word* in lettered list item. +# # [*word*] *Word* in labeled list item. +# # ====== *Word* in heading +# +# Any text may be made bold via HTML tag +b+. +# +# Examples: +# +# # Two words in paragraph. +# # - Two words in bullet list item. +# # 1. Two words in numbered list item. +# # a. Two words in lettered list item. +# # [Two words] Two words in labeled list item. +# # ====== Two words in heading +# +# ==== Monofont +# +# A single word may be made monofont -- sometimes called "typewriter font" -- +# by prefixed and suffixed plus-signs. +# +# Examples: +# +# # +Word+ in paragraph. +# # - +Word+ in bullet list item. +# # 1. +Word+ in numbered list item. +# # a. +Word+ in lettered list item. +# # [+word+] +Word+ in labeled list item. +# # ====== +Word+ in heading +# +# Any text may be made monofont via HTML tag +tt+ or +code+. +# +# Examples: +# +# # Two words in paragraph. +# # - Two words in bullet list item. +# # 1. Two words in numbered list item. +# # a. Two words in lettered list item. +# # [Two words] Two words in labeled list item. +# # ====== Two words in heading +# +# ==== Character Conversions +# +# Certain combinations of characters may be converted to special characters; +# whether the conversion occurs depends on whether the special character +# is available in the current encoding. +# +# - (c) converts to (c) (copyright character); must be lowercase. +# +# - (r) converts to (r) (registered trademark character); must be lowercase. +# +# - 'foo' converts to 'foo' (smart single-quotes). +# +# - "foo" converts to "foo" (smart double-quotes). +# +# - foo ... bar converts to foo ... bar (1-character ellipsis). +# +# - foo -- bar converts to foo -- bar (1-character en-dash). +# +# - foo --- bar converts to foo --- bar (1-character em-dash). +# +# ==== Links +# +# Certain strings in \RDoc text are converted to links. +# Any such link may be suppressed by prefixing a backslash. +# This section shows how to link to various +# targets. +# +# [Class] +# +# - On-page: DummyClass links to DummyClass. +# - Off-page: RDoc::Alias links to RDoc::Alias. +# +# [Module] +# +# - On-page: DummyModule links to DummyModule. +# - Off-page: RDoc links to RDoc. +# +# [Constant] +# +# - On-page: DUMMY_CONSTANT links to DUMMY_CONSTANT. +# - Off-page: RDoc::Text::MARKUP_FORMAT links to RDoc::Text::MARKUP_FORMAT. +# +# [Singleton Method] +# +# - On-page: ::dummy_singleton_method links to ::dummy_singleton_method. +# - Off-pageRDoc::TokenStream::to_html links to RDoc::TokenStream::to_html. +# to \RDoc::TokenStream::to_html. +# +# Note: Occasionally \RDoc is not linked to a method whose name +# has only special characters. Check whether the links you were expecting +# are actually there. If not, you'll need to put in an explicit link; +# see below. +# +# Pro tip: The link to any method is available in the alphabetical table of contents +# at the top left of the page for the class or module. +# +# [Instance Method] +# +# - On-page: #dummy_instance_method links to #dummy_instance_method. +# - Off-page: RDoc::Alias#html_name links to RDoc::Alias#html_name. +# +# See the Note and Pro Tip immediately above. +# +# [Attribute] +# +# - On-page: #dummy_attribute links to #dummy_attribute. +# - Off-page: RDoc::Alias#name links to RDoc::Alias#name. +# +# [Alias] +# +# - On-page: #dummy_instance_alias links to #dummy_instance_alias. +# - Off-page: RDoc::Alias#new_name links to RDoc::Alias#new_name. +# +# [Protocol +http+] +# +# - Linked: http://yahoo.com links to http://yahoo.com. +# +# [Protocol +https+] +# +# - Linked: https://github.com links to https://github.com. +# +# [Protocol +www+] +# +# - Linked: www.yahoo.com links to www.yahoo.com. +# +# [Protocol +ftp+] +# +# - Linked: ftp://nosuch.site links to ftp://nosuch.site. +# +# [Protocol +mailto+] +# +# - Linked: mailto:/foo@bar.com links to mailto://foo@bar.com. +# +# [Protocol +irc+] +# +# - link: irc://irc.freenode.net/ruby links to irc://irc.freenode.net/ruby. +# +# [Image Filename Extensions] +# +# - Link: https://www.ruby-lang.org/images/header-ruby-logo@2x.png is +# converted to an in-line HTML +img+ tag, which displays the image in the HTML: +# +# https://www.ruby-lang.org/images/header-ruby-logo@2x.png +# +# Also works for +bmp+, +gif+, +jpeg+, and +jpg+ files. +# +# Note: Works only for a fully qualified URL. +# +# [Heading] +# +# - Link: RDoc::RD@LICENSE links to RDoc::RDoc::RD@LICENSE. +# +# Note that spaces in the actual heading are represented by + characters +# in the linkable text. +# +# - Link: RDoc::Options@Saved+Options +# links to RDoc::Options@Saved+Options. +# +# Punctuation and other special characters must be escaped like CGI.escape. +# +# Pro tip: The link to any heading is available in the alphabetical table of contents +# at the top left of the page for the class or module. +# +# [Section] +# +# See {Directives for Organizing Documentation}[#class-RDoc::MarkupReference-label-Directives+for+Organizing+Documentation]. +# +# - Link: RDoc::Markup::ToHtml@Visitor links to RDoc::Markup::ToHtml@Visitor. +# +# If a section and a heading share the same name, the link target is the section. +# +# [Single-Word Text Link] +# +# Use square brackets to create single-word text link: +# +# - GitHub[https://github.com] links to GitHub[https://github.com]. +# +# [Multi-Word Text Link] +# +# Use square brackets and curly braces to create a multi-word text link. +# +# - {GitHub home page}[https://github.com] links to +# {GitHub home page}[https://github.com]. +# +# [rdoc-ref Scheme] +# +# A link with the rdoc-ref: scheme links to the referenced item, +# if that item exists. +# The referenced item may be a class, module, method, file, etc. +# +# - Class: Alias[rdoc-ref:RDoc::Alias] links to Alias[rdoc-ref:RDoc::Alias]. +# - Module: RDoc[rdoc-ref:RDoc] links to RDoc[rdoc-ref:RDoc]. +# - Method: foo[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK] +# links to foo[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]. +# - Constant: bar[rdoc-ref:RDoc::Markup::ToHtml::LIST_TYPE_TO_HTML] +# links to bar[rdoc-ref:RDoc::Markup::ToHtml::LIST_TYPE_TO_HTML]. +# - Attribute: baz[rdoc-ref:RDoc::Markup::ToHtml#code_object] +# links to baz[rdoc-ref:RDoc::Markup::ToHtml#code_object]. +# - Alias: bad[rdoc-ref:RDoc::MarkupReference#dummy_instance_alias] links to +# bad[rdoc-ref:RDoc::MarkupReference#dummy_instance_alias]. +# +# If the referenced item does not exist, no link is generated +# and entire rdoc-ref: square-bracketed clause is removed +# from the resulting text. +# +# - Nosuch[rdoc-ref:RDoc::Nosuch] is rendered as +# Nosuch[rdoc-ref:RDoc::Nosuch]. +# +# +# [rdoc-label Scheme] +# +# [Simple] +# +# You can specify a link target using this form, +# where the second part cites the id of an HTML element. +# +# This link refers to the constant +DUMMY_CONSTANT+ on this page: +# +# - {DUMMY_CONSTANT}[rdoc-label:DUMMY_CONSTANT] +# +# Thus: +# +# {DUMMY_CONSTANT}[rdoc-label:DUMMY_CONSTANT] +# +# [With Return] +# +# You can specify both a link target and a local label +# that can be used as the target for a return link. +# These two links refer to each other: +# +# - {go to addressee}[rdoc-label:addressee:sender] +# - {return to sender}[rdoc-label:sender:addressee] +# +# Thus: +# +# {go to addressee}[rdoc-label:addressee:sender] +# +# Some text. +# +# {return to sender}[rdoc-label:sender:addressee] +# +# [link: Scheme] +# +# - link:README_rdoc.html links to link:README_rdoc.html. +# +# [rdoc-image Scheme] +# +# Use the rdoc-image scheme to display an image that is also a link: +# +# # {rdoc-image:path/to/image}[link_target] +# +# - Link: {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[https://www.ruby-lang.org] +# displays image https://www.ruby-lang.org/images/header-ruby-logo@2x.png +# as a link to https://www.ruby-lang.org. +# +# {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[https://www.ruby-lang.org] +# +# A relative path as the target also works: +# +# - Link: {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] links to ./Alias.html +# +# {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] +# +# === Directives +# +# ==== Directives for Allowing or Suppressing Documentation +# +# Each directive described in this section must appear on a line by itself. +# +# - [:stopdoc:] +# Specifies that \RDoc should ignore markup +# until next :startdoc: directive or end-of-file. +# - [:startdoc:] +# Specifies that \RDoc should resume parsing markup. +# - [:enddoc:] +# Specifies that \RDoc should ignore markup to end-of-file +# regardless of other directives. +# +# For Ruby code, but not for other \RDoc sources, +# there is a shorthand for [:stopdoc:] and [:startdoc:]: +# +# # Documented. +# #-- +# # Not documented. +# #++ +# # Documented. +# +# ==== Directive for Specifying \RDoc Source Format +# +# This directive described must appear on a line by itself. +# +# - [:markup: _type_] +# Specifies the format for the \RDoc input. +# Parameter +type+ is one of +markdown+, +rd+, +rdoc+, +tomdoc+. +# +# ==== Directives for HTML Output +# +# Each directive described in this section must appear on a line by itself. +# +# - [:title: _text_] +# Specifies the title for the HTML output. +# - [:main: _file_name_] +# Specifies the HTML file to be displayed first. +# +# ==== Directives for Method Documentation +# +# - [:call-seq:] +# For the given method, specifies the calling sequence to be reported in the HTML, +# overriding the actual calling sequence in the Ruby code. +# See method #call_seq_directive. +# - [:args: _arg_names_ (aliased as :arg)] +# For the given method, specifies the arguments to be reported in the HTML, +# overriding the actual arguments in the Ruby code. +# See method #args_directive. +# - [:yields: _arg_names_ (aliased as :yield:)] +# For the given method, specifies the yield arguments to be reported in the HTML, +# overriding the actual yield in the Ruby code. +# See method #yields_directive. +# +# Note that \RDoc can build the calling sequence for a Ruby-coded method, +# but not for other languages. +# You may want to override that by explicitly giving a :call-seq: +# directive if you want to include: +# +# - A return type, which is not automatically inferred. +# - Multiple calling sequences. +# +# ==== Directives for Organizing Documentation +# +# By default, \RDoc groups: +# +# - Singleton methods together in alphabetical order. +# - Instance methods and their aliases together in alphabetical order. +# - Attributes and their aliases together in alphabetical order. +# +# You can use directives to modify those behaviors. +# +# - [:section: _section_title_] +# +# Directive :section: section_title specifies that +# following methods are to be grouped into a section +# with the given section_title as its heading. +# This directive remains in effect until another such directive is given, +# but may be temporarily overridden by directive :category:. +# See below. +# +# Directive :section: with no title reverts to the default section. +# +# The comment block containing this directive: +# +# - Must be separated by a blank line from the documentation for the next item. +# - May have one or more lines preceding the directive. +# These will be removed, along with any trailing lines that match them. +# Such lines may be visually helpful. +# - Lines of text that are not so removed become the descriptive text +# for the section. +# +# Example: +# +# # ---------------------------------------- +# # :section: My Section +# # This is the section that I wrote. +# # See it glisten in the noon-day sun. +# # ---------------------------------------- +# +# ## +# # Comment for some_method +# def some_method +# # ... +# end +# +# You can use directive :category: to temporarily +# override the current section. +# +# - [:category: _section_title_] +# +# Directive :category: section_title specifies that +# just one following method is to be included in the given section. +# Subsequent methods are to be grouped into the current section. +# +# Directive :category: with no title specifies that just one +# following method is to be included in the default section. +# +# ==== Directive for Including a File +# +# - [:include: _filename_] +# +# Include the contents of the named file at this point. +# This directive must appear alone on one line, possibly preceded by spaces. +# In this position, it can be escaped with a backslash in front of the first colon. +# +# The file is searched for in the directories +# given with the --include command-line option, +# or in the current directory by default. +# The file content is shifted to have the same indentation as the colon +# at the start of the directive. +# +# == Markup in Code +# +# === Directives in Trailing Comments +# +# Each \RDoc directive in this section appears in a trailing +# comment in a line of code. +# +# - [:nodoc:] +# - Appears in a trailing comment on a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies that the defined object should not be documented. +# - [:nodoc: all] +# - Appears in a trailing comment on a line of code +# that defines a class or module. +# - Specifies that the class or module should not be documented. +# By default, however, a nested class or module _will_ be documented +# - [:doc:] +# - Appears in a trailing comment on a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies the defined object should be documented, even if otherwise +# would not be documented. +# - [:notnew: (aliased as :not_new and :not-new:)] +# - Appears in a trailing comment on a line of code +# that defines instance method +initialize+. +# - Specifies that singleton method +new+ should not be documented. +# By default, Ruby fakes a corresponding singleton method +new+, +# which \RDoc includes in the documentaton. +# Note that instance method +initialize+ is private, and so by default +# is not documented. +# +# == Documentation Derived from Ruby Code +# +# [Class] +# +# By default, \RDoc documents: +# +# - \Class name. +# - Parent class. +# - Singleton methods. +# - Instance methods. +# - Aliases. +# - Constants. +# - Attributes. +# +# [Module] +# +# By default, \RDoc documents: +# +# - \Module name. +# - \Singleton methods. +# - Instance methods. +# - Aliases. +# - Constants. +# - Attributes. +# +# [Method] +# +# By default, \RDoc documents: +# +# - \Method name. +# - Arguments. +# - Yielded values. +# +# See #method. +# +# [Alias] +# +# By default, \RDoc documents: +# +# - Alias name. +# - Aliased name. +# +# See #dummy_instance_alias and #dummy_instance_method. +# +# [Constant] +# +# By default, \RDoc documents: +# +# - \Constant name. +# +# See DUMMY_CONSTANT. +# +# [Attribute] +# +# By default, \RDoc documents: +# +# - Attribute name. +# - Attribute type ([R], [W], or [RW]) +# +# See #dummy_attribute. +# +class RDoc::MarkupReference + + class DummyClass; end + module DummyModule; end + def self.dummy_singleton_method(foo, bar); end + def dummy_instance_method(foo, bar); end; + alias dummy_instance_alias dummy_instance_method + attr_accessor :dummy_attribute + alias dummy_attribute_alias dummy_attribute + DUMMY_CONSTANT = '' + + # :call-seq: + # call_seq_directive(foo, bar) + # Can be anything -> bar + # Also anything more -> baz or bat + # + # The :call-seq: directive overrides the actual calling sequence + # found in the Ruby code. + # + # - It can specify anything at all. + # - It can have multiple calling sequences. + # + # This one includes Can be anything -> foo, which is nonsense. + # + # Note that the "arrow" is two characters, hyphen and right angle-bracket, + # which is made into a single character in the HTML. + # + # Click on the calling sequence to see the code. + # + # Here is the :call-seq: directive given for the method: + # + # # :call-seq: + # # call_seq_directive(foo, bar) + # # Can be anything -> bar + # # Also anything more -> baz or bat + # + def call_seq_directive + nil + end + + # The :args: directive overrides the actual arguments found in the Ruby code. + # + # Click on the calling sequence to see the code. + # + def args_directive(foo, bar) # :args: baz + nil + end + + # The :yields: directive overrides the actual yield found in the Ruby code. + # + # Click on the calling sequence to see the code. + # + def yields_directive(foo, bar) # :yields: 'bat' + yield 'baz' + end + + # This method is documented only by \RDoc, except for these comments. + # + # Click on the calling sequence to see the code. + # + def method(foo, bar) + yield 'baz' + end + +end \ No newline at end of file diff --git a/lib/rdoc/rdoc.gemspec b/lib/rdoc/rdoc.gemspec index 547a67b04bb8de..3c96f7deb11e51 100644 --- a/lib/rdoc/rdoc.gemspec +++ b/lib/rdoc/rdoc.gemspec @@ -38,16 +38,12 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat "CVE-2013-0256.rdoc", "ExampleMarkdown.md", "ExampleRDoc.rdoc", - "Gemfile", "History.rdoc", "LEGAL.rdoc", "LICENSE.rdoc", "README.rdoc", "RI.rdoc", - "Rakefile", "TODO.rdoc", - "bin/console", - "bin/setup", "exe/rdoc", "exe/ri", "lib/rdoc.rb", @@ -223,7 +219,6 @@ RDoc includes the +rdoc+ and +ri+ tools for generating and displaying documentat "lib/rdoc/top_level.rb", "lib/rdoc/version.rb", "man/ri.1", - "rdoc.gemspec", ] # files from .gitignore s.files << "lib/rdoc/rd/block_parser.rb" << "lib/rdoc/rd/inline_parser.rb" << "lib/rdoc/markdown.rb" << "lib/rdoc/markdown/literals.rb" From d7868c79e2dd891e19fd2de25cdcd62526d995b2 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 26 Jul 2022 05:29:28 +0900 Subject: [PATCH 006/142] * append newline at EOF. [ci skip] --- doc/rdoc/markup_reference.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 74594e54833029..9a66517d90d2c4 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -913,4 +913,4 @@ def method(foo, bar) yield 'baz' end -end \ No newline at end of file +end From cc29b43c7a8079c0c9e308f049390dfaab5acbd9 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Mon, 25 Jul 2022 16:31:33 -0500 Subject: [PATCH 007/142] [ruby/rdoc] Move section Directives into section Blocks (https://github.com/ruby/rdoc/pull/901) https://github.com/ruby/rdoc/commit/e48e07ef53 --- doc/rdoc/markup_reference.rb | 326 +++++++++++++++++------------------ 1 file changed, 162 insertions(+), 164 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 9a66517d90d2c4..77e34cfb37ee44 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -323,6 +323,168 @@ # # --- # +# ==== Directives +# +# ===== Directives for Allowing or Suppressing Documentation +# +# Each directive described in this section must appear on a line by itself. +# +# - [:stopdoc:] +# Specifies that \RDoc should ignore markup +# until next :startdoc: directive or end-of-file. +# - [:startdoc:] +# Specifies that \RDoc should resume parsing markup. +# - [:enddoc:] +# Specifies that \RDoc should ignore markup to end-of-file +# regardless of other directives. +# +# For Ruby code, but not for other \RDoc sources, +# there is a shorthand for [:stopdoc:] and [:startdoc:]: +# +# # Documented. +# #-- +# # Not documented. +# #++ +# # Documented. +# +# ===== Directive for Specifying \RDoc Source Format +# +# This directive described must appear on a line by itself. +# +# - [:markup: _type_] +# Specifies the format for the \RDoc input. +# Parameter +type+ is one of +markdown+, +rd+, +rdoc+, +tomdoc+. +# +# ===== Directives for HTML Output +# +# Each directive described in this section must appear on a line by itself. +# +# - [:title: _text_] +# Specifies the title for the HTML output. +# - [:main: _file_name_] +# Specifies the HTML file to be displayed first. +# +# ===== Directives for Method Documentation +# +# - [:call-seq:] +# For the given method, specifies the calling sequence to be reported in the HTML, +# overriding the actual calling sequence in the Ruby code. +# See method #call_seq_directive. +# - [:args: _arg_names_ (aliased as :arg)] +# For the given method, specifies the arguments to be reported in the HTML, +# overriding the actual arguments in the Ruby code. +# See method #args_directive. +# - [:yields: _arg_names_ (aliased as :yield:)] +# For the given method, specifies the yield arguments to be reported in the HTML, +# overriding the actual yield in the Ruby code. +# See method #yields_directive. +# +# Note that \RDoc can build the calling sequence for a Ruby-coded method, +# but not for other languages. +# You may want to override that by explicitly giving a :call-seq: +# directive if you want to include: +# +# - A return type, which is not automatically inferred. +# - Multiple calling sequences. +# +# ===== Directives for Organizing Documentation +# +# By default, \RDoc groups: +# +# - Singleton methods together in alphabetical order. +# - Instance methods and their aliases together in alphabetical order. +# - Attributes and their aliases together in alphabetical order. +# +# You can use directives to modify those behaviors. +# +# - [:section: _section_title_] +# +# Directive :section: section_title specifies that +# following methods are to be grouped into a section +# with the given section_title as its heading. +# This directive remains in effect until another such directive is given, +# but may be temporarily overridden by directive :category:. +# See below. +# +# Directive :section: with no title reverts to the default section. +# +# The comment block containing this directive: +# +# - Must be separated by a blank line from the documentation for the next item. +# - May have one or more lines preceding the directive. +# These will be removed, along with any trailing lines that match them. +# Such lines may be visually helpful. +# - Lines of text that are not so removed become the descriptive text +# for the section. +# +# Example: +# +# # ---------------------------------------- +# # :section: My Section +# # This is the section that I wrote. +# # See it glisten in the noon-day sun. +# # ---------------------------------------- +# +# ## +# # Comment for some_method +# def some_method +# # ... +# end +# +# You can use directive :category: to temporarily +# override the current section. +# +# - [:category: _section_title_] +# +# Directive :category: section_title specifies that +# just one following method is to be included in the given section. +# Subsequent methods are to be grouped into the current section. +# +# Directive :category: with no title specifies that just one +# following method is to be included in the default section. +# +# ===== Directive for Including a File +# +# - [:include: _filename_] +# +# Include the contents of the named file at this point. +# This directive must appear alone on one line, possibly preceded by spaces. +# In this position, it can be escaped with a backslash in front of the first colon. +# +# The file is searched for in the directories +# given with the --include command-line option, +# or in the current directory by default. +# The file content is shifted to have the same indentation as the colon +# at the start of the directive. +# +# ===== Directives in Trailing Comments +# +# Each \RDoc directive in this section appears in a trailing +# comment in a line of code. +# +# - [:nodoc:] +# - Appears in a trailing comment on a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies that the defined object should not be documented. +# - [:nodoc: all] +# - Appears in a trailing comment on a line of code +# that defines a class or module. +# - Specifies that the class or module should not be documented. +# By default, however, a nested class or module _will_ be documented +# - [:doc:] +# - Appears in a trailing comment on a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies the defined object should be documented, even if otherwise +# would not be documented. +# - [:notnew: (aliased as :not_new and :not-new:)] +# - Appears in a trailing comment on a line of code +# that defines instance method +initialize+. +# - Specifies that singleton method +new+ should not be documented. +# By default, Ruby fakes a corresponding singleton method +new+, +# which \RDoc includes in the documentaton. +# Note that instance method +initialize+ is private, and so by default +# is not documented. +# # === Text Markup # # Text in a paragraph, list item (any type), or heading @@ -624,170 +786,6 @@ # # {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] # -# === Directives -# -# ==== Directives for Allowing or Suppressing Documentation -# -# Each directive described in this section must appear on a line by itself. -# -# - [:stopdoc:] -# Specifies that \RDoc should ignore markup -# until next :startdoc: directive or end-of-file. -# - [:startdoc:] -# Specifies that \RDoc should resume parsing markup. -# - [:enddoc:] -# Specifies that \RDoc should ignore markup to end-of-file -# regardless of other directives. -# -# For Ruby code, but not for other \RDoc sources, -# there is a shorthand for [:stopdoc:] and [:startdoc:]: -# -# # Documented. -# #-- -# # Not documented. -# #++ -# # Documented. -# -# ==== Directive for Specifying \RDoc Source Format -# -# This directive described must appear on a line by itself. -# -# - [:markup: _type_] -# Specifies the format for the \RDoc input. -# Parameter +type+ is one of +markdown+, +rd+, +rdoc+, +tomdoc+. -# -# ==== Directives for HTML Output -# -# Each directive described in this section must appear on a line by itself. -# -# - [:title: _text_] -# Specifies the title for the HTML output. -# - [:main: _file_name_] -# Specifies the HTML file to be displayed first. -# -# ==== Directives for Method Documentation -# -# - [:call-seq:] -# For the given method, specifies the calling sequence to be reported in the HTML, -# overriding the actual calling sequence in the Ruby code. -# See method #call_seq_directive. -# - [:args: _arg_names_ (aliased as :arg)] -# For the given method, specifies the arguments to be reported in the HTML, -# overriding the actual arguments in the Ruby code. -# See method #args_directive. -# - [:yields: _arg_names_ (aliased as :yield:)] -# For the given method, specifies the yield arguments to be reported in the HTML, -# overriding the actual yield in the Ruby code. -# See method #yields_directive. -# -# Note that \RDoc can build the calling sequence for a Ruby-coded method, -# but not for other languages. -# You may want to override that by explicitly giving a :call-seq: -# directive if you want to include: -# -# - A return type, which is not automatically inferred. -# - Multiple calling sequences. -# -# ==== Directives for Organizing Documentation -# -# By default, \RDoc groups: -# -# - Singleton methods together in alphabetical order. -# - Instance methods and their aliases together in alphabetical order. -# - Attributes and their aliases together in alphabetical order. -# -# You can use directives to modify those behaviors. -# -# - [:section: _section_title_] -# -# Directive :section: section_title specifies that -# following methods are to be grouped into a section -# with the given section_title as its heading. -# This directive remains in effect until another such directive is given, -# but may be temporarily overridden by directive :category:. -# See below. -# -# Directive :section: with no title reverts to the default section. -# -# The comment block containing this directive: -# -# - Must be separated by a blank line from the documentation for the next item. -# - May have one or more lines preceding the directive. -# These will be removed, along with any trailing lines that match them. -# Such lines may be visually helpful. -# - Lines of text that are not so removed become the descriptive text -# for the section. -# -# Example: -# -# # ---------------------------------------- -# # :section: My Section -# # This is the section that I wrote. -# # See it glisten in the noon-day sun. -# # ---------------------------------------- -# -# ## -# # Comment for some_method -# def some_method -# # ... -# end -# -# You can use directive :category: to temporarily -# override the current section. -# -# - [:category: _section_title_] -# -# Directive :category: section_title specifies that -# just one following method is to be included in the given section. -# Subsequent methods are to be grouped into the current section. -# -# Directive :category: with no title specifies that just one -# following method is to be included in the default section. -# -# ==== Directive for Including a File -# -# - [:include: _filename_] -# -# Include the contents of the named file at this point. -# This directive must appear alone on one line, possibly preceded by spaces. -# In this position, it can be escaped with a backslash in front of the first colon. -# -# The file is searched for in the directories -# given with the --include command-line option, -# or in the current directory by default. -# The file content is shifted to have the same indentation as the colon -# at the start of the directive. -# -# == Markup in Code -# -# === Directives in Trailing Comments -# -# Each \RDoc directive in this section appears in a trailing -# comment in a line of code. -# -# - [:nodoc:] -# - Appears in a trailing comment on a line of code -# that defines a class, module, method, alias, constant, or attribute. -# - Specifies that the defined object should not be documented. -# - [:nodoc: all] -# - Appears in a trailing comment on a line of code -# that defines a class or module. -# - Specifies that the class or module should not be documented. -# By default, however, a nested class or module _will_ be documented -# - [:doc:] -# - Appears in a trailing comment on a line of code -# that defines a class, module, method, alias, constant, or attribute. -# - Specifies the defined object should be documented, even if otherwise -# would not be documented. -# - [:notnew: (aliased as :not_new and :not-new:)] -# - Appears in a trailing comment on a line of code -# that defines instance method +initialize+. -# - Specifies that singleton method +new+ should not be documented. -# By default, Ruby fakes a corresponding singleton method +new+, -# which \RDoc includes in the documentaton. -# Note that instance method +initialize+ is private, and so by default -# is not documented. -# # == Documentation Derived from Ruby Code # # [Class] From 649bfbe00d8032fa2c0536e596a284f69926e87f Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Mon, 11 Jul 2022 14:51:44 +0100 Subject: [PATCH 008/142] Fix `rb_profile_frames` output includes dummy main thread frame The `rb_profile_frames` API did not skip the two dummy frames that each thread has at its beginning. This was unlike `backtrace_each` and `rb_ec_parcial_backtrace_object`, which do skip them. This does not seem to be a problem for non-main thread frames, because both `VM_FRAME_RUBYFRAME_P(cfp)` and `rb_vm_frame_method_entry(cfp)` are NULL for them. BUT, on the main thread `VM_FRAME_RUBYFRAME_P(cfp)` was true and thus the dummy thread was still included in the output of `rb_profile_frames`. I've now made `rb_profile_frames` skip this extra frame (like `backtrace_each` and friends), as well as add a test that asserts the size and contents of `rb_profile_frames`. Fixes [Bug #18907] () --- ext/-test-/debug/profile_frames.c | 1 + test/-ext-/debug/test_profile_frames.rb | 24 ++++++++++++++++++++++++ vm_backtrace.c | 3 +++ 3 files changed, 28 insertions(+) diff --git a/ext/-test-/debug/profile_frames.c b/ext/-test-/debug/profile_frames.c index 5f14755ce755d1..d2bba7d1834e1b 100644 --- a/ext/-test-/debug/profile_frames.c +++ b/ext/-test-/debug/profile_frames.c @@ -29,6 +29,7 @@ profile_frames(VALUE self, VALUE start_v, VALUE num_v) rb_ary_push(ary, rb_profile_frame_singleton_method_p(buff[i])); rb_ary_push(ary, rb_profile_frame_method_name(buff[i])); rb_ary_push(ary, rb_profile_frame_qualified_method_name(buff[i])); + rb_ary_push(ary, INT2NUM(lines[i])); rb_ary_push(result, ary); } diff --git a/test/-ext-/debug/test_profile_frames.rb b/test/-ext-/debug/test_profile_frames.rb index e0152247e7c245..d6ae953dd298c7 100644 --- a/test/-ext-/debug/test_profile_frames.rb +++ b/test/-ext-/debug/test_profile_frames.rb @@ -137,6 +137,30 @@ def test_profile_frames } end + def test_matches_backtrace_locations_main_thread + assert_equal(Thread.current, Thread.main) + + # Keep these in the same line, so the backtraces match exactly + backtrace_locations, profile_frames = [Thread.current.backtrace_locations, Bug::Debug.profile_frames(0, 100)] + + assert_equal(backtrace_locations.size, profile_frames.size) + + # The first entries are not going to match, since one is #backtrace_locations and the other #profile_frames + backtrace_locations.shift + profile_frames.shift + + # The rest of the stack is expected to look the same... + backtrace_locations.zip(profile_frames).each.with_index do |(location, (path, absolute_path, _, base_label, _, _, _, _, _, _, lineno)), i| + next if absolute_path == "" # ...except for cfunc frames + + err_msg = "#{i}th frame" + assert_equal(location.absolute_path, absolute_path, err_msg) + assert_equal(location.base_label, base_label, err_msg) + assert_equal(location.lineno, lineno, err_msg) + assert_equal(location.path, path, err_msg) + end + end + def test_ifunc_frame bug11851 = '[ruby-core:72409] [Bug #11851]' assert_ruby_status([], <<~'end;', bug11851) # do diff --git a/vm_backtrace.c b/vm_backtrace.c index ee749deb144f54..5bd588df127e85 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -1551,6 +1551,9 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines) const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec); const rb_callable_method_entry_t *cme; + // Skip dummy frame; see `rb_ec_partial_backtrace_object` for details + end_cfp = RUBY_VM_NEXT_CONTROL_FRAME(end_cfp); + for (i=0; i 0) { From b404a5f106d13e25708c163c91e117b2e106b70c Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 26 Jul 2022 13:41:51 +0900 Subject: [PATCH 009/142] 8fa66467de is broken with rubygems/rubygems and flori/json. Revert "Fix sync_default_gems.rb to use absolute path" This reverts commit 8fa66467de82f787ead9dd901ad06694c79d88dc. --- tool/sync_default_gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index a33c056861c417..47f6f1c840025a 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -88,7 +88,7 @@ def sync_default_gems(gem) repo = REPOSITORIES[gem.to_sym] puts "Sync #{repo}" - upstream = File.join(__dir__, "../..", repo) + upstream = File.join("..", "..", repo) case gem when "rubygems" From 9e6d07f3462d29f340114650da9f13a36b866d5f Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 26 Jul 2022 13:43:48 +0900 Subject: [PATCH 010/142] Merge rubygems/bundler HEAD Merge from https://github.com/rubygems/rubygems/commit/2af2520b4a7ab1c6eb1fdc3d2ef4d8c062d96ad7 --- lib/bundler.rb | 3 +- lib/bundler/definition.rb | 33 +++++++++---- lib/bundler/dependency.rb | 5 +- lib/bundler/force_platform.rb | 18 ------- lib/bundler/incomplete_specification.rb | 12 +++++ lib/bundler/lazy_specification.rb | 33 ++++++------- lib/bundler/remote_specification.rb | 9 ++-- lib/bundler/resolver.rb | 5 +- lib/bundler/rubygems_ext.rb | 22 ++++++++- lib/bundler/spec_set.rb | 52 +++++++++++--------- spec/bundler/install/gemfile/sources_spec.rb | 39 +++++++++++++++ spec/bundler/install/yanked_spec.rb | 6 +-- spec/bundler/resolver/basic_spec.rb | 2 +- spec/bundler/runtime/platform_spec.rb | 52 +++++++++++++++----- spec/bundler/runtime/setup_spec.rb | 1 + spec/bundler/support/builders.rb | 4 +- spec/bundler/support/indexes.rb | 1 + 17 files changed, 199 insertions(+), 98 deletions(-) delete mode 100644 lib/bundler/force_platform.rb create mode 100644 lib/bundler/incomplete_specification.rb diff --git a/lib/bundler.rb b/lib/bundler.rb index 9fb9ce3e822383..7df22ab3a54813 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -53,6 +53,7 @@ module Bundler autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) autoload :Graph, File.expand_path("bundler/graph", __dir__) + autoload :IncompleteSpecification, File.expand_path("bundler/incomplete_specification", __dir__) autoload :Index, File.expand_path("bundler/index", __dir__) autoload :Injector, File.expand_path("bundler/injector", __dir__) autoload :Installer, File.expand_path("bundler/installer", __dir__) @@ -455,7 +456,7 @@ def unbundled_exec(*args) end def local_platform - return Gem::Platform::RUBY if settings[:force_ruby_platform] + return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY] Gem::Platform.local end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 8f43befe35c996..4cb829470a7cb0 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -138,13 +138,13 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti @unlock[:gems] ||= @dependencies.map(&:name) else eager_unlock = expand_dependencies(@unlock[:gems] || [], true) - @unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name) + @unlock[:gems] = @locked_specs.for(eager_unlock, false, platforms).map(&:name) end @dependency_changes = converge_dependencies @local_changes = converge_locals - @locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true) + @reresolve = nil @requires = compute_requires end @@ -279,11 +279,8 @@ def resolve end end else - last_resolve = converge_locked_specs - # Run a resolve against the locally available gems Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") - expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true) - Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) + @reresolve = reresolve end end @@ -468,7 +465,7 @@ def most_specific_locked_platform private :sources def nothing_changed? - !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform + !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes end def unlocking? @@ -477,8 +474,14 @@ def unlocking? private + def reresolve + last_resolve = converge_locked_specs + expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true) + Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) + end + def filter_specs(specs, deps) - SpecSet.new(specs).for(expand_dependencies(deps, true), false, false) + SpecSet.new(specs).for(expand_dependencies(deps, true), false, platforms) end def materialize(dependencies) @@ -502,6 +505,17 @@ def materialize(dependencies) raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}" end + if @reresolve.nil? + incomplete_specs = specs.incomplete_specs + + if incomplete_specs.any? + Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies") + @unlock[:gems].concat(incomplete_specs.map(&:name)) + @resolve = reresolve + specs = resolve.materialize(dependencies) + end + end + unless specs["bundler"].any? bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last specs["bundler"] = bundler @@ -549,7 +563,6 @@ def change_reason [@new_platform, "you added a new platform to your gemfile"], [@path_changes, "the gemspecs for path gems changed"], [@local_changes, "the gemspecs for git local gems changed"], - [@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"], ].select(&:first).map(&:last).join(", ") end @@ -725,7 +738,7 @@ def converge_specs(specs) # if we won't need the source (according to the lockfile), # don't error if the path/git source isn't available next if specs. - for(requested_dependencies, false, true). + for(requested_dependencies, false). none? {|locked_spec| locked_spec.source == s.source } raise diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index 2449cb64119f48..7f94079e096f26 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -1,14 +1,11 @@ # frozen_string_literal: true require "rubygems/dependency" -require_relative "force_platform" require_relative "shared_helpers" require_relative "rubygems_ext" module Bundler class Dependency < Gem::Dependency - include ForcePlatform - attr_reader :autorequire attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref, :force_ruby_platform @@ -112,7 +109,7 @@ def initialize(name, version, options = {}, &blk) @env = options["env"] @should_include = options.fetch("should_include", true) @gemfile = options["gemfile"] - @force_ruby_platform = options.fetch("force_ruby_platform", default_force_ruby_platform) + @force_ruby_platform = options["force_ruby_platform"] @autorequire = Array(options["require"] || []) if options.key?("require") end diff --git a/lib/bundler/force_platform.rb b/lib/bundler/force_platform.rb deleted file mode 100644 index 0648ea9737a07d..00000000000000 --- a/lib/bundler/force_platform.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Bundler - module ForcePlatform - private - - # The `:force_ruby_platform` value used by dependencies for resolution, and - # by locked specifications for materialization is `false` by default, except - # for TruffleRuby. TruffleRuby generally needs to force the RUBY platform - # variant unless the name is explicitly allowlisted. - - def default_force_ruby_platform - return false unless Bundler.current_ruby.truffleruby? - - !Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY.include?(name) - end - end -end diff --git a/lib/bundler/incomplete_specification.rb b/lib/bundler/incomplete_specification.rb new file mode 100644 index 00000000000000..6d0b9b901c061c --- /dev/null +++ b/lib/bundler/incomplete_specification.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Bundler + class IncompleteSpecification + attr_reader :name, :platform + + def initialize(name, platform) + @name = name + @platform = platform + end + end +end diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 89b21efc04df15..21e75d2126aab0 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -1,16 +1,13 @@ # frozen_string_literal: true -require_relative "force_platform" require_relative "match_platform" module Bundler class LazySpecification - include ForcePlatform include MatchPlatform attr_reader :name, :version, :dependencies, :platform - attr_writer :force_ruby_platform - attr_accessor :source, :remote + attr_accessor :source, :remote, :force_ruby_platform def initialize(name, version, platform, source = nil) @name = name @@ -19,23 +16,16 @@ def initialize(name, version, platform, source = nil) @platform = platform || Gem::Platform::RUBY @source = source @specification = nil - @force_ruby_platform = nil end def full_name - if platform == Gem::Platform::RUBY || platform.nil? + if platform == Gem::Platform::RUBY "#{@name}-#{@version}" else "#{@name}-#{@version}-#{platform}" end end - def force_ruby_platform - return @force_ruby_platform unless @force_ruby_platform.nil? - - default_force_ruby_platform - end - def ==(other) identifier == other.identifier end @@ -71,7 +61,7 @@ def satisfies?(dependency) def to_lock out = String.new - if platform == Gem::Platform::RUBY || platform.nil? + if platform == Gem::Platform::RUBY out << " #{name} (#{version})\n" else out << " #{name} (#{version}-#{platform})\n" @@ -85,7 +75,17 @@ def to_lock out end - def __materialize__ + def materialize_for_installation + __materialize__(ruby_platform_materializes_to_ruby_platform? ? platform : Bundler.local_platform) + end + + def materialize_for_resolution + return self unless Gem::Platform.match_spec?(self) + + __materialize__(platform) + end + + def __materialize__(platform) @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name source.gemspec.tap {|s| s.source = source } else @@ -94,10 +94,9 @@ def __materialize__ else ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version) end - platform_object = ruby_platform_materializes_to_ruby_platform? ? Gem::Platform.new(platform) : Gem::Platform.local candidates = source.specs.search(search_object) same_platform_candidates = candidates.select do |spec| - MatchPlatform.platforms_match?(spec.platform, platform_object) + MatchPlatform.platforms_match?(spec.platform, platform) end installable_candidates = same_platform_candidates.select do |spec| spec.is_a?(StubSpecification) || @@ -115,7 +114,7 @@ def respond_to?(*args) end def to_s - @__to_s ||= if platform == Gem::Platform::RUBY || platform.nil? + @__to_s ||= if platform == Gem::Platform::RUBY "#{name} (#{version})" else "#{name} (#{version}-#{platform})" diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb index 4e966b820aa565..b5d7e3a6c9a61b 100644 --- a/lib/bundler/remote_specification.rb +++ b/lib/bundler/remote_specification.rb @@ -16,7 +16,8 @@ class RemoteSpecification def initialize(name, version, platform, spec_fetcher) @name = name @version = Gem::Version.create version - @platform = platform + @original_platform = platform || Gem::Platform::RUBY + @platform = Gem::Platform.new(platform) @spec_fetcher = spec_fetcher @dependencies = nil end @@ -35,10 +36,10 @@ def required_rubygems_version end def full_name - if platform == Gem::Platform::RUBY || platform.nil? + if @original_platform == Gem::Platform::RUBY "#{@name}-#{@version}" else - "#{@name}-#{@version}-#{platform}" + "#{@name}-#{@version}-#{@original_platform}" end end @@ -105,7 +106,7 @@ def to_ary end def _remote_specification - @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform]) + @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @original_platform]) @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \ " missing from the server! Try installing with `--full-index` as a workaround.") end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 972a4c254dc1f0..33f232e184767b 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -22,17 +22,16 @@ def self.resolve(requirements, source_requirements = {}, base = [], gem_version_ metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") } resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements) result = resolver.start(requirements) - SpecSet.new(SpecSet.new(result).for(regular_requirements)) + SpecSet.new(SpecSet.new(result).for(regular_requirements, false, platforms)) end def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements) @source_requirements = source_requirements @metadata_requirements = metadata_requirements - @base = base @resolver = Molinillo::Resolver.new(self, self) @search_for = {} @base_dg = Molinillo::DependencyGraph.new - @base.each do |ls| + @base = base.materialized_for_resolution do |ls| dep = Dependency.new(ls.name, ls.version) @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true) end diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index d679d20c21efa2..a47692d1f25dfe 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -222,9 +222,27 @@ class Platform MINGW = Gem::Platform.new("x86-mingw32") X64_MINGW = [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw-ucrt")].freeze + end + + Platform.singleton_class.module_eval do + unless Platform.singleton_methods.include?(:match_spec?) + def match_spec?(spec) + match_gem?(spec.platform, spec.name) + end + + def match_gem?(platform, gem_name) + match_platforms?(platform, Gem.platforms) + end + + private - if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY) - REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 sorbet-static].freeze + def match_platforms?(platform, platforms) + platforms.any? do |local_platform| + platform.nil? || + local_platform == platform || + (local_platform != Gem::Platform::RUBY && local_platform =~ platform) + end + end end end diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 06257ac93fd324..a7a95e49bc80b2 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -11,30 +11,27 @@ def initialize(specs) @specs = specs end - def for(dependencies, check = false, match_current_platform = false) - # dep.name => [list, of, deps] - handled = Hash.new {|h, k| h[k] = [] } - deps = dependencies.dup + def for(dependencies, check = false, platforms = [nil]) + handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h + deps = dependencies.product(platforms).map {|dep, platform| [dep.name, platform && dep.force_ruby_platform ? Gem::Platform::RUBY : platform] } specs = [] loop do break unless dep = deps.shift - next if handled[dep.name].any? {|d| match_current_platform || d.__platform == dep.__platform } || dep.name == "bundler" + next if handled.key?(dep) - # use a hash here to ensure constant lookup time in the `any?` call above - handled[dep.name] << dep + handled[dep] = true - specs_for_dep = specs_for_dependency(dep, match_current_platform) + specs_for_dep = specs_for_dependency(*dep) if specs_for_dep.any? specs.concat(specs_for_dep) specs_for_dep.first.dependencies.each do |d| next if d.type == :development - d = DepProxy.get_proxy(Dependency.new(d.name, d.requirement), dep.__platform) unless match_current_platform - deps << d + deps << [d.name, dep[1]] end elsif check - return false + specs << IncompleteSpecification.new(*dep) end end @@ -42,9 +39,7 @@ def for(dependencies, check = false, match_current_platform = false) specs << spec end - specs.uniq! unless match_current_platform - - check ? true : specs + specs end def [](key) @@ -71,12 +66,12 @@ def to_hash end def materialize(deps) - materialized = self.for(deps, false, true) + materialized = self.for(deps, true).uniq materialized.map! do |s| next s unless s.is_a?(LazySpecification) s.source.local! - s.__materialize__ || s + s.materialize_for_installation || s end SpecSet.new(materialized) end @@ -89,16 +84,29 @@ def materialized_for_all_platforms next s unless s.is_a?(LazySpecification) s.source.local! s.source.remote! - spec = s.__materialize__ + spec = s.materialize_for_installation raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec spec end end + def materialized_for_resolution + materialized = @specs.map do |s| + spec = s.materialize_for_resolution + yield spec if spec + spec + end.compact + SpecSet.new(materialized) + end + def missing_specs @specs.select {|s| s.is_a?(LazySpecification) } end + def incomplete_specs + @specs.select {|s| s.is_a?(IncompleteSpecification) } + end + def merge(set) arr = sorted.dup set.each do |set_spec| @@ -173,12 +181,12 @@ def tsort_each_node @specs.sort_by(&:name).each {|s| yield s } end - def specs_for_dependency(dep, match_current_platform) - specs_for_name = lookup[dep.name] - if match_current_platform - GemHelpers.select_best_platform_match(specs_for_name, Bundler.local_platform) + def specs_for_dependency(name, platform) + specs_for_name = lookup[name] + if platform.nil? + GemHelpers.select_best_platform_match(specs_for_name.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform) else - specs_for_name_and_platform = GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : dep.__platform) + specs_for_name_and_platform = GemHelpers.select_best_platform_match(specs_for_name, platform) specs_for_name_and_platform.any? ? specs_for_name_and_platform : specs_for_name end end diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index 89c812e5d5a553..ee0aa2a34761af 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -1563,4 +1563,43 @@ L end end + + context "when mistakenly adding a top level gem already depended on and cached under the wrong source" do + before do + build_repo4 do + build_gem "some_private_gem", "0.1.0" do |s| + s.add_dependency "example", "~> 1.0" + end + end + + build_repo2 do + build_gem "example", "1.0.0" + end + + install_gemfile <<~G, :artifice => "compact_index" + source "https://gem.repo2" + + source "https://gem.repo4" do + gem "some_private_gem" + end + G + + gemfile <<~G + source "https://gem.repo2" + + source "https://gem.repo4" do + gem "some_private_gem" + gem "example" # MISTAKE, example is not available at gem.repo4 + end + G + end + + it "shows a proper error message and does not generate a corrupted lockfile" do + expect do + bundle :install, :artifice => "compact_index", :raise_on_error => false, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + end.not_to change { lockfile } + + expect(err).to include("Could not find gem 'example' in rubygems repository https://gem.repo4/") + end + end end diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb index 3acae85afdd771..44fbb0bda3a5f1 100644 --- a/spec/bundler/install/yanked_spec.rb +++ b/spec/bundler/install/yanked_spec.rb @@ -15,7 +15,7 @@ foo (10.0.0) PLATFORMS - ruby + #{lockfile_platforms} DEPENDENCIES foo (= 10.0.0) @@ -57,7 +57,7 @@ rack (0.9.1) PLATFORMS - ruby + #{lockfile_platforms} DEPENDENCIES rack (= 0.9.1) @@ -86,7 +86,7 @@ rack_middleware (1.0) PLATFORMS - ruby + #{lockfile_platforms} DEPENDENCIES rack (= 0.9.1) diff --git a/spec/bundler/resolver/basic_spec.rb b/spec/bundler/resolver/basic_spec.rb index ee62dc3577aba8..7182d1e29c6ffc 100644 --- a/spec/bundler/resolver/basic_spec.rb +++ b/spec/bundler/resolver/basic_spec.rb @@ -233,7 +233,7 @@ it "resolves foo only to latest patch - changing dependency declared case" do # bar is locked AND a declared dependency in the Gemfile, so it will not move, and therefore # foo can only move up to 1.4.4. - @base << build_spec("bar", "2.0.3").first + @base << Bundler::LazySpecification.new("bar", "2.0.3", nil) should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.4.4 bar-2.0.3] end diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb index 34dc5ba7990241..a7161c9cfea263 100644 --- a/spec/bundler/runtime/platform_spec.rb +++ b/spec/bundler/runtime/platform_spec.rb @@ -281,30 +281,59 @@ expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" - build_repo4 do - build_gem "libv8" + simulate_platform "x86_64-linux" do + build_repo4 do + build_gem "libv8" - build_gem "libv8" do |s| - s.platform = Bundler.local_platform + build_gem "libv8" do |s| + s.platform = "x86_64-linux" + end end + + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem "libv8" + G + + lockfile <<-L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + libv8 (1.0) + + PLATFORMS + ruby + + DEPENDENCIES + libv8 + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "install" + + expect(the_bundle).to include_gems "libv8 1.0 x86_64-linux" end + end + it "doesn't pull platform specific gems on truffleruby, even if lockfile only includes those", :truffleruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "libv8" + source "#{file_uri_for(gem_repo1)}" + gem "platform_specific" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: #{file_uri_for(gem_repo1)}/ specs: - libv8 (1.0) + platform_specific (1.0-x86-darwin-100) PLATFORMS - ruby + x86-darwin-100 DEPENDENCIES - libv8 + platform_specific BUNDLED WITH #{Bundler::VERSION} @@ -312,7 +341,7 @@ bundle "install" - expect(the_bundle).to include_gems "libv8 1.0 #{Bundler.local_platform}" + expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" end it "allows specifying only-ruby-platform on windows with dependency platforms" do @@ -379,6 +408,7 @@ gem "requires_platform_specific" G + expect(out).to include("lockfile does not have all gems needed for the current platform") expect(the_bundle).to include_gem "platform_specific 1.0 x64-mingw32" end end diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index fecf4cd98bb3c6..5f1657997c603f 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -634,6 +634,7 @@ def clean_load_path(lp) ruby "require '#{system_gem_path("gems/bundler-9.99.9.beta1/lib/bundler.rb")}'; Bundler.setup", :env => { "DEBUG" => "1" } expect(out).to include("Found no changes, using resolution from the lockfile") + expect(out).not_to include("lockfile does not have all gems needed for the current platform") expect(err).to be_empty end diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 285b68c047ac65..2397d74010c8e5 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -94,8 +94,8 @@ def build_repo1 end build_gem "platform_specific" do |s| - s.platform = Bundler.local_platform - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'" + s.platform = Gem::Platform.local + s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Gem::Platform.local}'" end build_gem "platform_specific" do |s| diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb index 638f394e76a70b..55d798a90a11ff 100644 --- a/spec/bundler/support/indexes.rb +++ b/spec/bundler/support/indexes.rb @@ -26,6 +26,7 @@ def resolve(args = []) end end args[0] ||= [] # base + args[0].each {|ls| ls.source = default_source } args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter args[2] ||= [] # additional_base_requirements args[3] ||= @platforms # platforms From 9a8f6e392fbd9c145566ae18fa2128ef96369430 Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Mon, 25 Jul 2022 21:04:03 -0400 Subject: [PATCH 011/142] Cheaply derive code range for String#b return value The result of String#b is a string with an ASCII_8BIT/BINARY encoding. That encoding is ASCII-compatible and has no byte sequences that are invalid for the encoding. If we know the receiver's code range, we can derive the resulting string's code range without needing to perform a full code range scan. --- string.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/string.c b/string.c index f5e089aa21a4aa..d9b5278eb6b3a4 100644 --- a/string.c +++ b/string.c @@ -10779,7 +10779,23 @@ rb_str_b(VALUE str) str2 = str_alloc_embed(rb_cString, RSTRING_EMBED_LEN(str) + TERM_LEN(str)); } str_replace_shared_without_enc(str2, str); - ENC_CODERANGE_CLEAR(str2); + + // BINARY strings can never be broken; they're either 7-bit ASCII or VALID. + // If we know the receiver's code range then we know the result's code range. + int cr = ENC_CODERANGE(str); + switch (cr) { + case ENC_CODERANGE_7BIT: + ENC_CODERANGE_SET(str2, ENC_CODERANGE_7BIT); + break; + case ENC_CODERANGE_BROKEN: + case ENC_CODERANGE_VALID: + ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID); + break; + default: + ENC_CODERANGE_CLEAR(str2); + break; + } + return str2; } From 2d1cf658eeafbd989e0b61bae08a8d0b1b49e2bd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 26 Jul 2022 18:33:21 +0900 Subject: [PATCH 012/142] Adjust indent [ci skip] --- string.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/string.c b/string.c index d9b5278eb6b3a4..85819e26a393a3 100644 --- a/string.c +++ b/string.c @@ -10784,16 +10784,16 @@ rb_str_b(VALUE str) // If we know the receiver's code range then we know the result's code range. int cr = ENC_CODERANGE(str); switch (cr) { - case ENC_CODERANGE_7BIT: - ENC_CODERANGE_SET(str2, ENC_CODERANGE_7BIT); - break; - case ENC_CODERANGE_BROKEN: - case ENC_CODERANGE_VALID: - ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID); - break; - default: - ENC_CODERANGE_CLEAR(str2); - break; + case ENC_CODERANGE_7BIT: + ENC_CODERANGE_SET(str2, ENC_CODERANGE_7BIT); + break; + case ENC_CODERANGE_BROKEN: + case ENC_CODERANGE_VALID: + ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID); + break; + default: + ENC_CODERANGE_CLEAR(str2); + break; } return str2; From 456e1d1eaa9bb11adaed1acde488d7da3c88704b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 26 Jul 2022 19:42:48 +0900 Subject: [PATCH 013/142] Try the tag without "v" prefix to checkout upstream repositories --- gems/bundled_gems | 4 ++-- tool/fetch-bundled_gems.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gems/bundled_gems b/gems/bundled_gems index ebe195f78f4605..4bf063abff3b34 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -2,9 +2,9 @@ minitest 5.16.2 https://github.com/seattlerb/minitest power_assert 2.0.1 https://github.com/ruby/power_assert rake 13.0.6 https://github.com/ruby/rake -test-unit 3.5.3 https://github.com/test-unit/test-unit 3.5.3 +test-unit 3.5.3 https://github.com/test-unit/test-unit rexml 3.2.5 https://github.com/ruby/rexml -rss 0.2.9 https://github.com/ruby/rss 0.2.9 +rss 0.2.9 https://github.com/ruby/rss net-ftp 0.1.3 https://github.com/ruby/net-ftp net-imap 0.2.3 https://github.com/ruby/net-imap net-pop 0.1.1 https://github.com/ruby/net-pop diff --git a/tool/fetch-bundled_gems.rb b/tool/fetch-bundled_gems.rb index 90c5fbff37d228..8d04892b702463 100755 --- a/tool/fetch-bundled_gems.rb +++ b/tool/fetch-bundled_gems.rb @@ -27,5 +27,5 @@ checkout = %w"git -c advice.detachedHead=false checkout" puts "checking out #{c} (v=#{v}, r=#{r}) ..." unless system(*checkout, c, "--", chdir: n) - abort + abort if r or !system(*checkout, v, "--", chdir: n) end From 3f70aa6504d4c63a3cc928c52d6cf88dafffb40d Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 25 Jul 2022 10:29:10 -0400 Subject: [PATCH 014/142] Remove ary_discard ary_discard should not be used as it should be handled by the GC. The only user of ary_discard is rb_ary_product, which doesn't neeed to use ary_discard. --- array.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/array.c b/array.c index b0c4cee0bf64b3..16c35f7934074f 100644 --- a/array.c +++ b/array.c @@ -1025,14 +1025,6 @@ rb_ary_memsize(VALUE ary) } } -static inline void -ary_discard(VALUE ary) -{ - rb_ary_free(ary); - RBASIC(ary)->flags |= RARRAY_EMBED_FLAG; - RBASIC(ary)->flags &= ~(RARRAY_EMBED_LEN_MASK | RARRAY_TRANSIENT_FLAG); -} - static VALUE ary_make_shared(VALUE ary) { @@ -6938,7 +6930,6 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary) } #define tmpary(n) rb_ary_tmp_new(n) -#define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray)) /* * Build a ruby array of the corresponding values and yield it to the @@ -7711,8 +7702,8 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary) counters[m]++; } } + done: - tmpary_discard(t0); ALLOCV_END(t1); return NIL_P(result) ? ary : result; From efb91ff19b739b759f40af2673f942e80d212857 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 25 Jul 2022 10:40:45 -0400 Subject: [PATCH 015/142] Rename rb_ary_tmp_new to rb_ary_hidden_new rb_ary_tmp_new suggests that the array is temporary in some way, but that's not true, it just creates an array that's hidden and not on the transient heap. This commit renames it to rb_ary_hidden_new. --- array.c | 10 ++++------ class.c | 6 +++--- compile.c | 22 +++++++++++----------- cont.c | 2 +- enum.c | 4 ++-- ext/fiddle/closure.c | 2 +- ext/openssl/ossl_pkey_ec.c | 2 +- gc.c | 4 ++-- hash.c | 2 +- include/ruby/internal/intern/array.h | 6 +++--- internal/array.h | 2 +- internal/imemo.h | 6 +++--- iseq.c | 4 ++-- load.c | 10 +++++----- marshal.c | 2 +- proc.c | 2 +- ruby.c | 2 +- struct.c | 4 ++-- symbol.c | 4 ++-- thread.c | 14 +++++++------- thread_sync.c | 2 +- vm.c | 2 +- vm_args.c | 6 +++--- 23 files changed, 59 insertions(+), 61 deletions(-) diff --git a/array.c b/array.c index 16c35f7934074f..af68968a0570d7 100644 --- a/array.c +++ b/array.c @@ -967,7 +967,7 @@ rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts) } VALUE -rb_ary_tmp_new(long capa) +rb_ary_hidden_new(long capa) { VALUE ary = ary_new(0, capa); rb_ary_transient_heap_evacuate(ary, TRUE); @@ -975,7 +975,7 @@ rb_ary_tmp_new(long capa) } VALUE -rb_ary_tmp_new_fill(long capa) +rb_ary_hidden_new_fill(long capa) { VALUE ary = ary_new(0, capa); ary_memfill(ary, 0, capa, Qnil); @@ -5101,7 +5101,7 @@ rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary) } else if (argc > 1) { int i; - VALUE args = rb_ary_tmp_new(argc); + VALUE args = rb_ary_hidden_new(argc); for (i = 0; i < argc; i++) { rb_ary_concat(args, argv[i]); } @@ -6929,8 +6929,6 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary) return Qnil; } -#define tmpary(n) rb_ary_tmp_new(n) - /* * Build a ruby array of the corresponding values and yield it to the * associated block. @@ -7625,7 +7623,7 @@ static VALUE rb_ary_product(int argc, VALUE *argv, VALUE ary) { int n = argc+1; /* How many arrays we're operating on */ - volatile VALUE t0 = tmpary(n); + volatile VALUE t0 = rb_ary_hidden_new(n); volatile VALUE t1 = Qundef; VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */ int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */ diff --git a/class.c b/class.c index 4306b7c0f34e70..54d9e6e17795dc 100644 --- a/class.c +++ b/class.c @@ -507,7 +507,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig) VALUE p = RCLASS_SUPER(orig); VALUE orig_origin = RCLASS_ORIGIN(orig); VALUE prev_clone_p = clone; - VALUE origin_stack = rb_ary_tmp_new(2); + VALUE origin_stack = rb_ary_hidden_new(2); VALUE origin[2]; VALUE clone_p = 0; long origin_len; @@ -1250,7 +1250,7 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super RCLASS_SET_INCLUDER(iclass, klass); add_subclass = TRUE; if (module != RCLASS_ORIGIN(module)) { - if (!origin_stack) origin_stack = rb_ary_tmp_new(2); + if (!origin_stack) origin_stack = rb_ary_hidden_new(2); VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)}; rb_ary_cat(origin_stack, origin, 2); } @@ -2310,7 +2310,7 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V continue; } } - if (NIL_P(missing)) missing = rb_ary_tmp_new(1); + if (NIL_P(missing)) missing = rb_ary_hidden_new(1); rb_ary_push(missing, keyword); } if (!NIL_P(missing)) { diff --git a/compile.c b/compile.c index c17c97adbba885..dc8ed459464a74 100644 --- a/compile.c +++ b/compile.c @@ -313,7 +313,7 @@ static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NOD LABEL_REF(le); \ LABEL_REF(lc); \ if (NIL_P(ISEQ_COMPILE_DATA(iseq)->catch_table_ary)) \ - RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, rb_ary_tmp_new(3)); \ + RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, rb_ary_hidden_new(3)); \ rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \ } while (0) @@ -627,7 +627,7 @@ decl_branch_base(rb_iseq_t *iseq, const NODE *node, const char *type) VALUE branches; if (NIL_P(branch_base)) { - branch_base = rb_ary_tmp_new(6); + branch_base = rb_ary_hidden_new(6); rb_hash_aset(structure, key, branch_base); rb_ary_push(branch_base, ID2SYM(rb_intern(type))); rb_ary_push(branch_base, INT2FIX(first_lineno)); @@ -675,7 +675,7 @@ add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NODE *n long counter_idx; if (NIL_P(branch)) { - branch = rb_ary_tmp_new(6); + branch = rb_ary_hidden_new(6); rb_hash_aset(branches, key, branch); rb_ary_push(branch, ID2SYM(rb_intern(type))); rb_ary_push(branch, INT2FIX(first_lineno)); @@ -1743,7 +1743,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *node = args->kw_args; struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); struct rb_iseq_param_keyword *keyword; - const VALUE default_values = rb_ary_tmp_new(1); + const VALUE default_values = rb_ary_hidden_new(1); const VALUE complex_mark = rb_str_tmp_new(0); int kw = 0, rkw = 0, di = 0, i; @@ -1847,7 +1847,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons if (args->opt_args) { const NODE *node = args->opt_args; LABEL *label; - VALUE labels = rb_ary_tmp_new(1); + VALUE labels = rb_ary_hidden_new(1); VALUE *opt_table; int i = 0, j; @@ -4369,7 +4369,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) { /* The literal contains only optimizable elements, or the subarray is long enough */ - VALUE ary = rb_ary_tmp_new(count); + VALUE ary = rb_ary_hidden_new(count); /* Create a hidden array */ for (; count; count--, node = node->nd_next) @@ -4420,7 +4420,7 @@ static int compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node) { if (static_literal_node_p(node, iseq)) { - VALUE ary = rb_ary_tmp_new(1); + VALUE ary = rb_ary_hidden_new(1); rb_ary_push(ary, static_literal_value(node, iseq)); OBJ_FREEZE(ary); @@ -4517,7 +4517,7 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_hash_len) { /* The literal contains only optimizable elements, or the subsequence is long enough */ - VALUE ary = rb_ary_tmp_new(count); + VALUE ary = rb_ary_hidden_new(count); /* Create a hidden hash */ for (; count; count--, node = node->nd_next->nd_next) { @@ -12077,7 +12077,7 @@ ibf_dump_iseq_list_i(st_data_t key, st_data_t val, st_data_t ptr) static void ibf_dump_iseq_list(struct ibf_dump *dump, struct ibf_header *header) { - VALUE offset_list = rb_ary_tmp_new(dump->iseq_table->num_entries); + VALUE offset_list = rb_ary_hidden_new(dump->iseq_table->num_entries); struct ibf_dump_iseq_list_arg args; args.dump = dump; @@ -12349,7 +12349,7 @@ ibf_load_object_array(const struct ibf_load *load, const struct ibf_object_heade const long len = (long)ibf_load_small_value(load, &reading_pos); - VALUE ary = header->internal ? rb_ary_tmp_new(len) : rb_ary_new_capa(len); + VALUE ary = header->internal ? rb_ary_hidden_new(len) : rb_ary_new_capa(len); int i; for (i=0; icurrent_buffer->obj_table; - VALUE offset_list = rb_ary_tmp_new(obj_table->num_entries); + VALUE offset_list = rb_ary_hidden_new(obj_table->num_entries); struct ibf_dump_object_list_arg args; args.dump = dump; diff --git a/cont.c b/cont.c index 590d6c250f4c9a..8a9aded7133318 100644 --- a/cont.c +++ b/cont.c @@ -1316,7 +1316,7 @@ cont_capture(volatile int *volatile stat) entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1); for (p=th->ec->ensure_list; p; p=p->next) { if (!p->entry.marker) - p->entry.marker = rb_ary_tmp_new(0); /* dummy object */ + p->entry.marker = rb_ary_hidden_new(0); /* dummy object */ *entry++ = p->entry; } entry->marker = 0; diff --git a/enum.c b/enum.c index 6b69fef8a1453f..e3dc177ba17729 100644 --- a/enum.c +++ b/enum.c @@ -1487,7 +1487,7 @@ enum_sort_by(VALUE obj) ary = rb_ary_new(); } RBASIC_CLEAR_CLASS(ary); - buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2); + buf = rb_ary_hidden_new(SORT_BY_BUFSIZE*2); rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil); memo = MEMO_NEW(0, 0, 0); data = (struct sort_by_data *)&memo->v1; @@ -1863,7 +1863,7 @@ rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary) rb_raise(rb_eArgError, "too big size"); data.bufmax = data.n * 4; data.curlen = 0; - data.buf = rb_ary_tmp_new(data.bufmax * (by ? 2 : 1)); + data.buf = rb_ary_hidden_new(data.bufmax * (by ? 2 : 1)); data.limit = Qundef; data.cmpfunc = by ? nmin_cmp : rb_block_given_p() ? nmin_block_cmp : diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 3679e5c9adf090..a74cc53b78938d 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -74,7 +74,7 @@ with_gvl_callback(void *ptr) VALUE rbargs = rb_iv_get(self, "@args"); VALUE ctype = rb_iv_get(self, "@ctype"); int argc = RARRAY_LENINT(rbargs); - VALUE params = rb_ary_tmp_new(argc); + VALUE params = rb_ary_hidden_new(argc); VALUE ret; VALUE cPointer; int i, type; diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index dee215447dacd5..08972e92a135cb 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -1462,7 +1462,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) "use #mul(bn) form instead"); num = RARRAY_LEN(arg1); - bns_tmp = rb_ary_tmp_new(num); + bns_tmp = rb_ary_hidden_new(num); bignums = ALLOCV_N(const BIGNUM *, tmp_b, num); for (i = 0; i < num; i++) { VALUE item = RARRAY_AREF(arg1, i); diff --git a/gc.c b/gc.c index 808b8e53993db9..a9961e92e77ca2 100644 --- a/gc.c +++ b/gc.c @@ -9135,7 +9135,7 @@ rb_gc_register_mark_object(VALUE obj) VALUE ary = rb_ary_last(0, 0, ary_ary); if (NIL_P(ary) || RARRAY_LEN(ary) >= MARK_OBJECT_ARY_BUCKET_SIZE) { - ary = rb_ary_tmp_new(MARK_OBJECT_ARY_BUCKET_SIZE); + ary = rb_ary_hidden_new(MARK_OBJECT_ARY_BUCKET_SIZE); rb_ary_push(ary_ary, ary); } @@ -14193,7 +14193,7 @@ rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self) rb_objspace_t *objspace = &rb_objspace; if (!stress_to_class) { - stress_to_class = rb_ary_tmp_new(argc); + stress_to_class = rb_ary_hidden_new(argc); } rb_ary_cat(stress_to_class, argv, argc); return self; diff --git a/hash.c b/hash.c index 989bef455c6985..69a768d4ce1cce 100644 --- a/hash.c +++ b/hash.c @@ -3294,7 +3294,7 @@ rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash) if (!RHASH_TABLE_EMPTY_P(hash)) { long i; VALUE new_keys = hash_alloc(0); - VALUE pairs = rb_ary_tmp_new(RHASH_SIZE(hash) * 2); + VALUE pairs = rb_ary_hidden_new(RHASH_SIZE(hash) * 2); rb_hash_foreach(hash, flatten_i, pairs); for (i = 0; i < RARRAY_LEN(pairs); i += 2) { VALUE key = RARRAY_AREF(pairs, i), new_key, val; diff --git a/include/ruby/internal/intern/array.h b/include/ruby/internal/intern/array.h index 17964bf810e82d..2262c6f0c621b1 100644 --- a/include/ruby/internal/intern/array.h +++ b/include/ruby/internal/intern/array.h @@ -107,14 +107,14 @@ VALUE rb_ary_new_from_args(long n, ...); VALUE rb_ary_new_from_values(long n, const VALUE *elts); /** - * Allocates a "temporary" array. This is a hidden empty array. Handy on - * occasions. + * Allocates a hidden (no class) empty array. * * @param[in] capa Designed capacity of the array. * @return A hidden, empty array. * @see rb_obj_hide() */ -VALUE rb_ary_tmp_new(long capa); +VALUE rb_ary_hidden_new(long capa); +#define rb_ary_tmp_new rb_ary_hidden_new /** * Destroys the given array for no reason. diff --git a/internal/array.h b/internal/array.h index 0de82d9f3026b0..17d91a800ba71a 100644 --- a/internal/array.h +++ b/internal/array.h @@ -26,7 +26,7 @@ VALUE rb_ary_last(int, const VALUE *, VALUE); void rb_ary_set_len(VALUE, long); void rb_ary_delete_same(VALUE, VALUE); -VALUE rb_ary_tmp_new_fill(long capa); +VALUE rb_ary_hidden_new_fill(long capa); VALUE rb_ary_at(VALUE, VALUE); size_t rb_ary_memsize(VALUE); VALUE rb_to_array_type(VALUE obj); diff --git a/internal/imemo.h b/internal/imemo.h index 53d82eb20f8b9a..91b524e0a6ae77 100644 --- a/internal/imemo.h +++ b/internal/imemo.h @@ -10,7 +10,7 @@ */ #include "ruby/internal/config.h" #include /* for size_t */ -#include "internal/array.h" /* for rb_ary_tmp_new_fill */ +#include "internal/array.h" /* for rb_ary_hidden_new_fill */ #include "internal/gc.h" /* for RB_OBJ_WRITE */ #include "ruby/internal/stdbool.h" /* for bool */ #include "ruby/ruby.h" /* for rb_block_call_func_t */ @@ -121,9 +121,9 @@ struct MEMO { #define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0)) #define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value)) #define NEW_MEMO_FOR(type, value) \ - ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value)) + ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value)) #define NEW_PARTIAL_MEMO_FOR(type, value, member) \ - ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), \ + ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), \ rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \ MEMO_FOR(type, value)) diff --git a/iseq.c b/iseq.c index 34c438e2a295ba..3d40b88a0de1bc 100644 --- a/iseq.c +++ b/iseq.c @@ -773,7 +773,7 @@ prepare_iseq_build(rb_iseq_t *iseq, } ISEQ_COVERAGE_SET(iseq, coverage); if (coverage && ISEQ_BRANCH_COVERAGE(iseq)) - ISEQ_PC2BRANCHINDEX_SET(iseq, rb_ary_tmp_new(0)); + ISEQ_PC2BRANCHINDEX_SET(iseq, rb_ary_hidden_new(0)); return Qtrue; } @@ -2391,7 +2391,7 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent) const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); VALUE *code; VALUE str = rb_str_new(0, 0); - VALUE child = rb_ary_tmp_new(3); + VALUE child = rb_ary_hidden_new(3); unsigned int size; unsigned int i; long l; diff --git a/load.c b/load.c index e3daea7d7b25ac..62b9b2d9bdd926 100644 --- a/load.c +++ b/load.c @@ -54,7 +54,7 @@ rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_rel VALUE ary; long i; - ary = rb_ary_tmp_new(RARRAY_LEN(load_path)); + ary = rb_ary_hidden_new(RARRAY_LEN(load_path)); for (i = 0; i < RARRAY_LEN(load_path); ++i) { VALUE path, as_str, expanded_path; int is_string, non_cache; @@ -1427,15 +1427,15 @@ Init_load(void) rb_alias_variable(rb_intern_const("$-I"), id_load_path); rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path); vm->load_path = rb_ary_new(); - vm->expanded_load_path = rb_ary_tmp_new(0); - vm->load_path_snapshot = rb_ary_tmp_new(0); + vm->expanded_load_path = rb_ary_hidden_new(0); + vm->load_path_snapshot = rb_ary_hidden_new(0); vm->load_path_check_cache = 0; rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1); rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0); rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0); vm->loaded_features = rb_ary_new(); - vm->loaded_features_snapshot = rb_ary_tmp_new(0); + vm->loaded_features_snapshot = rb_ary_hidden_new(0); vm->loaded_features_index = st_init_numtable(); vm->loaded_features_realpaths = rb_hash_new(); rb_obj_hide(vm->loaded_features_realpaths); @@ -1448,6 +1448,6 @@ Init_load(void) rb_define_global_function("autoload", rb_f_autoload, 2); rb_define_global_function("autoload?", rb_f_autoload_p, -1); - ruby_dln_librefs = rb_ary_tmp_new(0); + ruby_dln_librefs = rb_ary_hidden_new(0); rb_gc_register_mark_object(ruby_dln_librefs); } diff --git a/marshal.c b/marshal.c index 3bca956a09c9e5..43102a54c5b78b 100644 --- a/marshal.c +++ b/marshal.c @@ -1763,7 +1763,7 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ { VALUE path = r_unique(arg); VALUE m = rb_path_to_class(path); - if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0); + if (NIL_P(extmod)) extmod = rb_ary_hidden_new(0); if (RB_TYPE_P(m, T_CLASS)) { /* prepended */ VALUE c; diff --git a/proc.c b/proc.c index 1fa21a59ec2f46..a525562230b3c8 100644 --- a/proc.c +++ b/proc.c @@ -1491,7 +1491,7 @@ rb_sym_to_proc(VALUE sym) ID id; if (!sym_proc_cache) { - sym_proc_cache = rb_ary_tmp_new(SYM_PROC_CACHE_SIZE * 2); + sym_proc_cache = rb_ary_hidden_new(SYM_PROC_CACHE_SIZE * 2); rb_gc_register_mark_object(sym_proc_cache); rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE*2 - 1, Qnil); } diff --git a/ruby.c b/ruby.c index 87876d5160ff34..46fb019701e138 100644 --- a/ruby.c +++ b/ruby.c @@ -725,7 +725,7 @@ add_modules(VALUE *req_list, const char *mod) VALUE feature; if (!list) { - *req_list = list = rb_ary_tmp_new(0); + *req_list = list = rb_ary_hidden_new(0); } feature = rb_str_cat_cstr(rb_str_tmp_new(0), mod); rb_ary_push(list, feature); diff --git a/struct.c b/struct.c index d1c8ae24f22300..7085042b43c2b3 100644 --- a/struct.c +++ b/struct.c @@ -115,7 +115,7 @@ struct_set_members(VALUE klass, VALUE /* frozen hidden array */ members) while (mask < members_length * AREF_HASH_UNIT) mask *= 2; - back = rb_ary_tmp_new(mask + 1); + back = rb_ary_hidden_new(mask + 1); rb_ary_store(back, mask, INT2FIX(members_length)); mask -= 2; /* mask = (2**k-1)*2 */ @@ -810,7 +810,7 @@ rb_struct_new(VALUE klass, ...) size = rb_long2int(num_members(klass)); if (size > numberof(tmpargs)) { - tmpargs[0] = rb_ary_tmp_new(size); + tmpargs[0] = rb_ary_hidden_new(size); mem = RARRAY_PTR(tmpargs[0]); } va_start(args, klass); diff --git a/symbol.c b/symbol.c index e89879982f7fc2..6aceab72c1434d 100644 --- a/symbol.c +++ b/symbol.c @@ -91,7 +91,7 @@ Init_sym(void) rb_obj_hide(dsym_fstrs); symbols->str_sym = st_init_table_with_size(&symhash, 1000); - symbols->ids = rb_ary_tmp_new(0); + symbols->ids = rb_ary_hidden_new(0); rb_gc_register_mark_object(symbols->ids); Init_op_tbl(); @@ -426,7 +426,7 @@ set_id_entry(rb_symbols_t *symbols, rb_id_serial_t num, VALUE str, VALUE sym) VALUE ary, ids = symbols->ids; if (idx >= (size_t)RARRAY_LEN(ids) || NIL_P(ary = rb_ary_entry(ids, (long)idx))) { - ary = rb_ary_tmp_new(ID_ENTRY_UNIT * ID_ENTRY_SIZE); + ary = rb_ary_hidden_new(ID_ENTRY_UNIT * ID_ENTRY_SIZE); rb_ary_store(ids, (long)idx, ary); } idx = (num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE; diff --git a/thread.c b/thread.c index 87f82d0a0e5251..411b6d70841f8b 100644 --- a/thread.c +++ b/thread.c @@ -843,7 +843,7 @@ thread_create_core(VALUE thval, struct thread_create_params *params) th->priority = current_th->priority; th->thgroup = current_th->thgroup; - th->pending_interrupt_queue = rb_ary_tmp_new(0); + th->pending_interrupt_queue = rb_ary_hidden_new(0); th->pending_interrupt_queue_checked = 0; th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack); RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack); @@ -5352,9 +5352,9 @@ Init_Thread(void) struct rb_thread_sched *sched = TH_SCHED(th); thread_sched_to_running(sched, th); - th->pending_interrupt_queue = rb_ary_tmp_new(0); + th->pending_interrupt_queue = rb_ary_hidden_new(0); th->pending_interrupt_queue_checked = 0; - th->pending_interrupt_mask_stack = rb_ary_tmp_new(0); + th->pending_interrupt_mask_stack = rb_ary_hidden_new(0); } } @@ -5651,17 +5651,17 @@ rb_reset_coverages(void) VALUE rb_default_coverage(int n) { - VALUE coverage = rb_ary_tmp_new_fill(3); + VALUE coverage = rb_ary_hidden_new_fill(3); VALUE lines = Qfalse, branches = Qfalse; int mode = GET_VM()->coverage_mode; if (mode & COVERAGE_TARGET_LINES) { - lines = n > 0 ? rb_ary_tmp_new_fill(n) : rb_ary_tmp_new(0); + lines = n > 0 ? rb_ary_hidden_new_fill(n) : rb_ary_hidden_new(0); } RARRAY_ASET(coverage, COVERAGE_INDEX_LINES, lines); if (mode & COVERAGE_TARGET_BRANCHES) { - branches = rb_ary_tmp_new_fill(2); + branches = rb_ary_hidden_new_fill(2); /* internal data structures for branch coverage: * * { branch base node => @@ -5687,7 +5687,7 @@ rb_default_coverage(int n) rb_obj_hide(structure); RARRAY_ASET(branches, 0, structure); /* branch execution counters */ - RARRAY_ASET(branches, 1, rb_ary_tmp_new(0)); + RARRAY_ASET(branches, 1, rb_ary_hidden_new(0)); } RARRAY_ASET(coverage, COVERAGE_INDEX_BRANCHES, branches); diff --git a/thread_sync.c b/thread_sync.c index 09f824c622504a..5ff36dd01de7fe 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -754,7 +754,7 @@ szqueue_ptr(VALUE obj) static VALUE ary_buf_new(void) { - return rb_ary_tmp_new(1); + return rb_ary_hidden_new(1); } static VALUE diff --git a/vm.c b/vm.c index bb2888ea73adc1..3bba390e7cba18 100644 --- a/vm.c +++ b/vm.c @@ -3932,7 +3932,7 @@ Init_vm_objects(void) vm->defined_module_hash = st_init_numtable(); /* initialize mark object array, hash */ - vm->mark_object_ary = rb_ary_tmp_new(128); + vm->mark_object_ary = rb_ary_hidden_new(128); vm->loading_table = st_init_strtable(); vm->frozen_strings = st_init_table_with_size(&rb_fstring_hash_type, 10000); } diff --git a/vm_args.c b/vm_args.c index 197fdd4b95f951..35adfd94b183ec 100644 --- a/vm_args.c +++ b/vm_args.c @@ -280,7 +280,7 @@ static VALUE make_unknown_kw_hash(const VALUE *passed_keywords, int passed_keyword_len, const VALUE *kw_argv) { int i; - VALUE obj = rb_ary_tmp_new(1); + VALUE obj = rb_ary_hidden_new(1); for (i=0; i Date: Mon, 25 Jul 2022 10:47:49 -0400 Subject: [PATCH 016/142] Use rb_ary_hidden_new for rb_ary_hidden_new_fill --- array.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/array.c b/array.c index af68968a0570d7..8c7fa583e958b6 100644 --- a/array.c +++ b/array.c @@ -977,10 +977,9 @@ rb_ary_hidden_new(long capa) VALUE rb_ary_hidden_new_fill(long capa) { - VALUE ary = ary_new(0, capa); + VALUE ary = rb_ary_hidden_new(capa); ary_memfill(ary, 0, capa, Qnil); ARY_SET_LEN(ary, capa); - rb_ary_transient_heap_evacuate(ary, TRUE); return ary; } From 163e3f075f71342fa5897beedf771e3e878876de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 25 Jul 2022 18:22:56 +0200 Subject: [PATCH 017/142] [rubygems/rubygems] Use main as default branch for Bundler specs https://github.com/rubygems/rubygems/commit/482077d185 --- spec/bundler/bundler/gem_helper_spec.rb | 5 +-- spec/bundler/cache/git_spec.rb | 20 +++++------ spec/bundler/commands/info_spec.rb | 4 +-- spec/bundler/commands/open_spec.rb | 2 +- spec/bundler/commands/pristine_spec.rb | 2 +- spec/bundler/commands/remove_spec.rb | 2 +- spec/bundler/commands/show_spec.rb | 4 +-- spec/bundler/install/gemfile/git_spec.rb | 36 +++++++++---------- .../install/gemfile/specific_platform_spec.rb | 2 +- spec/bundler/install/git_spec.rb | 8 ++--- spec/bundler/lock/lockfile_spec.rb | 6 ++-- spec/bundler/plugins/source/example_spec.rb | 6 ++-- spec/bundler/runtime/setup_spec.rb | 14 ++++---- spec/bundler/support/builders.rb | 2 +- spec/bundler/update/git_spec.rb | 10 +++--- 15 files changed, 62 insertions(+), 61 deletions(-) diff --git a/spec/bundler/bundler/gem_helper_spec.rb b/spec/bundler/bundler/gem_helper_spec.rb index 5cd79de620321d..7d955007ab935c 100644 --- a/spec/bundler/bundler/gem_helper_spec.rb +++ b/spec/bundler/bundler/gem_helper_spec.rb @@ -11,6 +11,7 @@ before(:each) do global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false" + sys_exec("git config --global init.defaultBranch main") bundle "gem #{app_name}" prepare_gemspec(app_gemspec_path) end @@ -295,7 +296,7 @@ def sha512_hexdigest(path) mock_confirm_message "Tagged v#{app_version}." mock_confirm_message "Pushed git commits and release tag." - sys_exec("git push -u origin master", :dir => app_path) + sys_exec("git push -u origin main", :dir => app_path) end it "calls rubygem_push with proper arguments" do @@ -336,7 +337,7 @@ def sha512_hexdigest(path) mock_build_message app_name, app_version mock_confirm_message "Pushed git commits and release tag." - sys_exec("git push -u origin master", :dir => app_path) + sys_exec("git push -u origin main", :dir => app_path) expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s) end diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb index b88993e9b1b1fb..7ea23cd312f321 100644 --- a/spec/bundler/cache/git_spec.rb +++ b/spec/bundler/cache/git_spec.rb @@ -15,7 +15,7 @@ RSpec.describe "bundle cache with git" do it "copies repository to vendor cache and uses it" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -34,7 +34,7 @@ it "copies repository to vendor cache and uses it even when configured with `path`" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -72,7 +72,7 @@ it "tracks updates" do git = build_git "foo" - old_ref = git.ref_for("master", 11) + old_ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -86,7 +86,7 @@ s.write "lib/foo.rb", "puts :CACHE" end - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) expect(ref).not_to eq(old_ref) bundle "update", :all => true @@ -103,7 +103,7 @@ it "tracks updates when specifying the gem" do git = build_git "foo" - old_ref = git.ref_for("master", 11) + old_ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -117,7 +117,7 @@ s.write "lib/foo.rb", "puts :CACHE" end - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) expect(ref).not_to eq(old_ref) bundle "update foo" @@ -132,11 +132,11 @@ it "uses the local repository to generate the cache" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => '#{lib_path("foo-invalid")}', :branch => :master + gem "foo", :git => '#{lib_path("foo-invalid")}', :branch => :main G bundle %(config set local.foo #{lib_path("foo-1.0")}) @@ -172,7 +172,7 @@ end G - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) bundle "config set cache_all true" bundle :cache @@ -196,7 +196,7 @@ bundle "config set cache_all true" bundle :cache - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) gemspec = bundled_app("vendor/cache/foo-1.0-#{ref}/foo.gemspec").read expect(gemspec).to_not match("`echo bob`") end diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb index 74943703a20d91..e4b970eb34c15e 100644 --- a/spec/bundler/commands/info_spec.rb +++ b/spec/bundler/commands/info_spec.rb @@ -163,10 +163,10 @@ expect(the_bundle).to include_gems "foo 1.0" bundle "info foo" - expect(out).to include("foo (1.0 #{@git.ref_for("master", 6)}") + expect(out).to include("foo (1.0 #{@git.ref_for("main", 6)}") end - it "prints out branch names other than master" do + it "prints out branch names other than main" do update_git "foo", :branch => "omg" do |s| s.write "lib/foo.rb", "FOO = '1.0.omg'" end diff --git a/spec/bundler/commands/open_spec.rb b/spec/bundler/commands/open_spec.rb index 53dc35c2c772df..85f15176b4092d 100644 --- a/spec/bundler/commands/open_spec.rb +++ b/spec/bundler/commands/open_spec.rb @@ -36,7 +36,7 @@ it "does not blow up if the gem to open does not have a Gemfile" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb index fe85e1ecd1439d..9e496dc91a9f89 100644 --- a/spec/bundler/commands/pristine_spec.rb +++ b/spec/bundler/commands/pristine_spec.rb @@ -22,7 +22,7 @@ source "#{file_uri_for(gem_repo2)}" gem "weakling" gem "very_simple_binary" - gem "foo", :git => "#{lib_path("foo")}", :branch => "master" + gem "foo", :git => "#{lib_path("foo")}", :branch => "main" gem "git_with_ext", :git => "#{lib_path("git_with_ext")}" gem "bar", :path => "#{lib_path("bar")}" diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb index ceba6c5edebc47..093130f7d5f805 100644 --- a/spec/bundler/commands/remove_spec.rb +++ b/spec/bundler/commands/remove_spec.rb @@ -86,7 +86,7 @@ gem 'git' gem 'rack', git: "#{lib_path("rack-1.0")}", - branch: 'master' + branch: 'main' gem 'nokogiri' G diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb index 2adb121616639e..925e40b71b2b24 100644 --- a/spec/bundler/commands/show_spec.rb +++ b/spec/bundler/commands/show_spec.rb @@ -100,10 +100,10 @@ expect(the_bundle).to include_gems "foo 1.0" bundle :show - expect(out).to include("foo (1.0 #{@git.ref_for("master", 6)}") + expect(out).to include("foo (1.0 #{@git.ref_for("main", 6)}") end - it "prints out branch names other than master" do + it "prints out branch names other than main" do update_git "foo", :branch => "omg" do |s| s.write "lib/foo.rb", "FOO = '1.0.omg'" end diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index 3f8a5afc4070ec..20586741059138 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe "bundle install with git sources" do - describe "when floating on master" do + describe "when floating on main" do before :each do build_git "foo" do |s| s.executables = "foobar" @@ -51,7 +51,7 @@ bundle "update foo" - sha = git.ref_for("master", 11) + sha = git.ref_for("main", 11) spec_file = default_bundle_path.join("bundler/gems/foo-1.0-#{sha}/foo.gemspec").to_s ruby_code = Gem::Specification.load(spec_file).to_ruby file_code = File.read(spec_file) @@ -219,12 +219,12 @@ end it "works when the revision is a non-head ref" do - # want to ensure we don't fallback to master + # want to ensure we don't fallback to main update_git "foo", :path => lib_path("foo-1.0") do |s| s.write("lib/foo.rb", "raise 'FAIL'") end - sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0")) + sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0")) # want to ensure we don't fallback to HEAD update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s| @@ -255,12 +255,12 @@ end G - # want to ensure we don't fallback to master + # want to ensure we don't fallback to main update_git "foo", :path => lib_path("foo-1.0") do |s| s.write("lib/foo.rb", "raise 'FAIL'") end - sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0")) + sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0")) # want to ensure we don't fallback to HEAD update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s| @@ -284,7 +284,7 @@ end it "does not download random non-head refs" do - sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 master~1", :dir => lib_path("foo-1.0")) + sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0")) bundle "config set global_gem_cache true" @@ -420,7 +420,7 @@ gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -441,7 +441,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -461,7 +461,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -477,7 +477,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G lockfile0 = File.read(bundled_app_lock) @@ -499,7 +499,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G lockfile0 = File.read(bundled_app_lock) @@ -519,7 +519,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -583,12 +583,12 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) bundle :install, :raise_on_error => false - expect(err).to match(/is using branch another but Gemfile specifies master/) + expect(err).to match(/is using branch another but Gemfile specifies main/) end it "explodes on invalid revision on install" do @@ -600,7 +600,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -617,7 +617,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -1519,7 +1519,7 @@ gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{lib_path("foo")}", :branch => "master" + gem "foo", :git => "#{lib_path("foo")}", :branch => "main" G bundle :install diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 276a84f2a6b6cc..6994cb2af15863 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -180,7 +180,7 @@ lockfile <<-L GIT remote: #{lib_path("pg_array_parser-1.0")} - revision: #{git.ref_for("master")} + revision: #{git.ref_for("main")} specs: pg_array_parser (1.0-java) pg_array_parser (1.0) diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb index d43aacee7e92b5..0fa7ed85317947 100644 --- a/spec/bundler/install/git_spec.rb +++ b/spec/bundler/install/git_spec.rb @@ -10,7 +10,7 @@ gem "foo", :git => "#{file_uri_for(lib_path("foo"))}" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at master@#{revision_for(lib_path("foo"))[0..6]})") + expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})") expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}" end @@ -37,16 +37,16 @@ install_gemfile <<-G, :verbose => true source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}", :ref => "master~2" + gem "foo", :git => "#{file_uri_for(lib_path("foo"))}", :ref => "main~2" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at master~2@#{rev})") + expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev})") expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}" update_git "foo", "4.0", :path => lib_path("foo"), :gemspec => true bundle :update, :all => true, :verbose => true - expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at master~2@#{rev2})") + expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev2})") expect(the_bundle).to include_gems "foo 2.0", :source => "git@#{lib_path("foo")}" end diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index ea9893fb0e5bd7..b21765ec4d563e 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -386,7 +386,7 @@ expect(lockfile).to eq <<~G GIT remote: #{lib_path("foo-1.0")} - revision: #{git.ref_for("master")} + revision: #{git.ref_for("main")} specs: foo (1.0) @@ -457,7 +457,7 @@ expect(lockfile).to eq <<~G GIT remote: #{lib_path("foo-1.0")} - revision: #{git.ref_for("master")} + revision: #{git.ref_for("main")} specs: foo (1.0) @@ -617,7 +617,7 @@ expect(lockfile).to eq <<~G GIT remote: #{lib_path("bar-1.0")} - revision: #{bar.ref_for("master")} + revision: #{bar.ref_for("main")} specs: bar (1.0) diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb index 7d098997ec0496..412de04d441e2f 100644 --- a/spec/bundler/plugins/source/example_spec.rb +++ b/spec/bundler/plugins/source/example_spec.rb @@ -203,7 +203,7 @@ class SPlugin < Bundler::Plugin::API def initialize(opts) super - @ref = options["ref"] || options["branch"] || options["tag"] || "master" + @ref = options["ref"] || options["branch"] || options["tag"] || "main" @unlocked = false end @@ -247,7 +247,7 @@ def install(spec, opts) def options_to_lock opts = {"revision" => revision} - opts["ref"] = ref if ref != "master" + opts["ref"] = ref if ref != "main" opts end @@ -435,7 +435,7 @@ def installed? describe "bundle cache with gitp" do it "copies repository to vendor cache and uses it" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" # plugin source diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 5f1657997c603f..4390f0fb174e63 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -489,7 +489,7 @@ def clean_load_path(lp) gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -507,7 +507,7 @@ def clean_load_path(lp) gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -529,7 +529,7 @@ def clean_load_path(lp) gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -541,7 +541,7 @@ def clean_load_path(lp) G run "require 'rack'", :raise_on_error => false - expect(err).to match(/is using branch master but Gemfile specifies changed/) + expect(err).to match(/is using branch main but Gemfile specifies changed/) end it "explodes on refs with different branches on runtime" do @@ -551,17 +551,17 @@ def clean_load_path(lp) install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "master", :branch => "master" + gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "main" G gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "master", :branch => "nonexistant" + gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistant" G bundle %(config set local.rack #{lib_path("local-rack")}) run "require 'rack'", :raise_on_error => false - expect(err).to match(/is using branch master but Gemfile specifies nonexistant/) + expect(err).to match(/is using branch main but Gemfile specifies nonexistant/) end end diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 2397d74010c8e5..a4d4c9f085366b 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -528,7 +528,7 @@ def platform_string class GitBuilder < LibBuilder def _build(options) - default_branch = options[:default_branch] || "master" + default_branch = options[:default_branch] || "main" path = options[:path] || _default_path source = options[:source] || "git@#{path}" super(options.merge(:path => path, :source => source)) diff --git a/spec/bundler/update/git_spec.rb b/spec/bundler/update/git_spec.rb index 0787ee41a73f78..da92cab1cc14f3 100644 --- a/spec/bundler/update/git_spec.rb +++ b/spec/bundler/update/git_spec.rb @@ -57,7 +57,7 @@ expect(the_bundle).to include_gems "foo 1.1" end - it "floats on master when updating all gems that are pinned to the source even if you have child dependencies" do + it "floats on main when updating all gems that are pinned to the source even if you have child dependencies" do build_git "foo", :path => lib_path("foo") build_gem "bar", :to_bundle => true do |s| s.add_dependency "foo" @@ -103,7 +103,7 @@ build_git "foo" @remote = build_git("bar", :bare => true) update_git "foo", :remote => file_uri_for(@remote.path) - update_git "foo", :push => "master" + update_git "foo", :push => "main" install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -211,7 +211,7 @@ install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{file_uri_for(lib_path("rack-0.8"))}", :branch => "master" + gem "rack", :git => "#{file_uri_for(lib_path("rack-0.8"))}", :branch => "main" G bundle %(config set local.rack #{lib_path("local-rack")}) @@ -230,7 +230,7 @@ update_git "rails", "3.0", :path => lib_path("rails"), :gemspec => true bundle "update", :all => true - expect(out).to include("Using rails 3.0 (was 2.3.2) from #{file_uri_for(lib_path("rails"))} (at master@#{revision_for(lib_path("rails"))[0..6]})") + expect(out).to include("Using rails 3.0 (was 2.3.2) from #{file_uri_for(lib_path("rails"))} (at main@#{revision_for(lib_path("rails"))[0..6]})") end end @@ -301,7 +301,7 @@ s.write "foo.gemspec", spec_lines.join("\n") end - ref = @git.ref_for "master" + ref = @git.ref_for "main" bundle "update --source bar" From 457170e534bada3efb6e32ac834b198a521df58f Mon Sep 17 00:00:00 2001 From: git Date: Wed, 27 Jul 2022 01:04:28 +0900 Subject: [PATCH 018/142] * 2022-07-27 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 6ef7dc799b57fe..40220b36cf5c31 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 26 +#define RUBY_RELEASE_DAY 27 #include "ruby/version.h" #include "ruby/internal/abi.h" From 33f9e8f4ea451d33d789d9345599657347d92e96 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Tue, 26 Jul 2022 12:31:47 -0400 Subject: [PATCH 019/142] Add doc/rdoc directory to .document Adding the doc/rdoc directory to .document will allow files in that directory to be included in the documentation. --- doc/.document | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/.document b/doc/.document index 03d332367ca974..5ef2d99651404b 100644 --- a/doc/.document +++ b/doc/.document @@ -5,3 +5,4 @@ contributing NEWS syntax optparse +rdoc From 36d0c71acef5e80384c13f9b43419318d2127306 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Wed, 25 May 2022 10:17:04 -0400 Subject: [PATCH 020/142] Refactored poisoning and unpoisoning freelist to simpler API --- gc.c | 62 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/gc.c b/gc.c index a9961e92e77ca2..24078afc5a93e6 100644 --- a/gc.c +++ b/gc.c @@ -958,6 +958,24 @@ struct heap_page { bits_t pinned_bits[HEAP_PAGE_BITMAP_LIMIT]; }; +/* + * When asan is enabled, this will prohibit writing to the freelist until it is unlocked + */ +static void +asan_lock_freelist(struct heap_page *page) +{ + asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); +} + +/* + * When asan is enabled, this will enable the ability to write to the freelist + */ +static void +asan_unlock_freelist(struct heap_page *page) +{ + asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); +} + #define GET_PAGE_BODY(x) ((struct heap_page_body *)((bits_t)(x) & ~(HEAP_PAGE_ALIGN_MASK))) #define GET_PAGE_HEADER(x) (&GET_PAGE_BODY(x)->header) #define GET_HEAP_PAGE(x) (GET_PAGE_HEADER(x)->page) @@ -1939,12 +1957,12 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj asan_unpoison_object(obj, false); - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); p->as.free.flags = 0; p->as.free.next = page->freelist; page->freelist = p; - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); if (RGENGC_CHECK_MODE && /* obj should belong to page */ @@ -1961,7 +1979,7 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj static inline void heap_add_freepage(rb_heap_t *heap, struct heap_page *page) { - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); GC_ASSERT(page->free_slots != 0); GC_ASSERT(page->freelist != NULL); @@ -1970,14 +1988,14 @@ heap_add_freepage(rb_heap_t *heap, struct heap_page *page) RUBY_DEBUG_LOG("page:%p freelist:%p", (void *)page, (void *)page->freelist); - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); } #if GC_ENABLE_INCREMENTAL_MARK static inline void heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page) { - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); GC_ASSERT(page->free_slots != 0); GC_ASSERT(page->freelist != NULL); @@ -1985,7 +2003,7 @@ heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pa heap->pooled_pages = page; objspace->rincgc.pooled_slots += page->free_slots; - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); } #endif @@ -2209,7 +2227,7 @@ heap_page_allocate(rb_objspace_t *objspace, rb_size_pool_t *size_pool) } page->free_slots = limit; - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); return page; } @@ -2219,12 +2237,12 @@ heap_page_resurrect(rb_objspace_t *objspace, rb_size_pool_t *size_pool) struct heap_page *page = 0, *next; ccan_list_for_each_safe(&SIZE_POOL_TOMB_HEAP(size_pool)->pages, page, next, page_node) { - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); - if (page->freelist != NULL) { - heap_unlink_page(objspace, &size_pool->tomb_heap, page); - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); - return page; - } + asan_unlock_freelist(page); + if (page->freelist != NULL) { + heap_unlink_page(objspace, &size_pool->tomb_heap, page); + asan_lock_freelist(page); + return page; + } } return NULL; @@ -2618,7 +2636,7 @@ heap_next_free_page(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_ GC_ASSERT(page->free_slots != 0); RUBY_DEBUG_LOG("page:%p freelist:%p cnt:%d", (void *)page, (void *)page->freelist, page->free_slots); - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); return page; } @@ -5659,13 +5677,13 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context #if RGENGC_CHECK_MODE short freelist_len = 0; - asan_unpoison_memory_region(&sweep_page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(sweep_page); RVALUE *ptr = sweep_page->freelist; while (ptr) { freelist_len++; ptr = ptr->as.free.next; } - asan_poison_memory_region(&sweep_page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(sweep_page); if (freelist_len != sweep_page->free_slots) { rb_bug("inconsistent freelist length: expected %d but was %d", sweep_page->free_slots, freelist_len); } @@ -5723,7 +5741,7 @@ static void heap_page_freelist_append(struct heap_page *page, RVALUE *freelist) { if (freelist) { - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); if (page->freelist) { RVALUE *p = page->freelist; asan_unpoison_object((VALUE)p, false); @@ -5739,7 +5757,7 @@ heap_page_freelist_append(struct heap_page *page, RVALUE *freelist) else { page->freelist = freelist; } - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); } } @@ -7934,7 +7952,7 @@ gc_verify_heap_pages_(rb_objspace_t *objspace, struct ccan_list_head *head) struct heap_page *page = 0; ccan_list_for_each(head, page, page_node) { - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); + asan_unlock_freelist(page); RVALUE *p = page->freelist; while (p) { VALUE vp = (VALUE)p; @@ -7946,7 +7964,7 @@ gc_verify_heap_pages_(rb_objspace_t *objspace, struct ccan_list_head *head) p = p->as.free.next; asan_poison_object(prev); } - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_lock_freelist(page); if (page->flags.has_remembered_objects == FALSE) { remembered_old_objects += gc_verify_heap_page(objspace, page, Qfalse); @@ -10582,8 +10600,8 @@ static int gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t * objspace, struct heap_page *page) { VALUE v = (VALUE)vstart; - asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false); - asan_poison_memory_region(&page->freelist, sizeof(RVALUE*)); + asan_unlock_freelist(page); + asan_lock_freelist(page); page->flags.has_uncollectible_shady_objects = FALSE; page->flags.has_remembered_objects = FALSE; From 3b1ed03d8cc1422972004472fec9deadb72d19fa Mon Sep 17 00:00:00 2001 From: git Date: Wed, 27 Jul 2022 01:40:03 +0900 Subject: [PATCH 021/142] * expand tabs. [ci skip] Tabs were expanded because the file did not have any tab indentation in unedited lines. Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook. --- gc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gc.c b/gc.c index 24078afc5a93e6..3ea05ba8e7bba7 100644 --- a/gc.c +++ b/gc.c @@ -2238,11 +2238,11 @@ heap_page_resurrect(rb_objspace_t *objspace, rb_size_pool_t *size_pool) ccan_list_for_each_safe(&SIZE_POOL_TOMB_HEAP(size_pool)->pages, page, next, page_node) { asan_unlock_freelist(page); - if (page->freelist != NULL) { - heap_unlink_page(objspace, &size_pool->tomb_heap, page); + if (page->freelist != NULL) { + heap_unlink_page(objspace, &size_pool->tomb_heap, page); asan_lock_freelist(page); - return page; - } + return page; + } } return NULL; From 6a69807576b911dd9d5a81befe08a7c3bb870b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 17 Nov 2021 16:45:50 +0100 Subject: [PATCH 022/142] [rubygems/rubygems] Completely drop base parameter from index This parameter was coupling the concept of lockfile with the index. I don't think it's necessary. Also I believe it's causing some flaky test failures, which might leak into realworld issues. They are like this: ```` Invoking `/opt/hostedtoolcache/Ruby/3.0.4/x64/bin/ruby -I/home/runner/work/rubygems/rubygems/bundler/spec -r/home/runner/work/rubygems/rubygems/bundler/spec/support/artifice/fail.rb -r/home/runner/work/rubygems/rubygems/bundler/spec/support/hax.rb /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle lock` failed with output: ---------------------------------------------------------------------- --- ERROR REPORT TEMPLATE ------------------------------------------------------- ``` NoMethodError: undefined method `identifier' for #, @authors=["no one"], @bindir="bin", @cert_chain=[], @dependencies=[], @executables=[], @extensions=[], @extra_rdoc_files=[], @files=[], @licenses=[], @metadata={}, @platform="ruby", @rdoc_options=[], @require_paths=["lib"], @required_ruby_version=#=", #]]>, @required_rubygems_version=#=", #]]>, @requirements=[], @rubygems_version="3.2.33", @specification_version=4, @test_files=[], @new_platform="ruby", @full_name="win32-process-0.8.3", @has_rdoc=true, @license=["MIT"] win32-process-0.8.3> /home/runner/work/rubygems/rubygems/bundler/tmp/rubygems/lib/rubygems/specification.rb:2116:in `method_missing' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/remote_specification.rb:115:in `method_missing' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/lazy_specification.rb:34:in `eql?' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/index.rb:189:in `eql?' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/index.rb:189:in `search_by_dependency' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/index.rb:96:in `local_search' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/index.rb:64:in `unsorted_search' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/index.rb:60:in `search' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:179:in `results_for' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:113:in `search_for' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:216:in `block in sort_dependencies' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:207:in `each' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:207:in `sort_by' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:207:in `sort_dependencies' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb:60:in `block in sort_dependencies' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb:77:in `with_no_such_dependency_error_handling' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb:59:in `sort_dependencies' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:754:in `push_state_for_requirements' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:744:in `require_nested_dependencies_for' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:727:in `activate_new_spec' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:684:in `attempt_to_activate' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:254:in `process_topmost_state' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb:182:in `resolve' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb:43:in `resolve' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:50:in `start' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/resolver.rb:24:in `resolve' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/definition.rb:480:in `reresolve' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/definition.rb:283:in `resolve' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/definition.rb:181:in `resolve_remotely!' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/lock.rb:53:in `run' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:674:in `lock' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:31:in `dispatch' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:25:in `start' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/exe/bundle:48:in `block in ' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/exe/bundle:36:in `' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle:23:in `load' /home/runner/work/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle:23:in `
' ``` ```` I think the issue is that now we eagerly materialize some base specifications before resolving in order to give better errors if user specified an incorrect source in the Gemfile. This means that the key for the index hash will have heterogeneous specification objects (some LazySpecification, some real Specification), and `LazySpecification#eql?` is incompatible with that. By dropping the base parameter from the index, we should no longer have these heterogenous objects as hash keys. https://github.com/rubygems/rubygems/commit/dc179d41c3 --- lib/bundler/index.rb | 22 ++++++++++------------ lib/bundler/resolver.rb | 6 +++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 5bc24fc0b2060a..00c7a9e00d7c17 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -56,17 +56,17 @@ def search_all(name) # Search this index's specs, and any source indexes that this index knows # about, returning all of the results. - def search(query, base = nil) - sort_specs(unsorted_search(query, base)) + def search(query) + sort_specs(unsorted_search(query)) end - def unsorted_search(query, base) - results = local_search(query, base) + def unsorted_search(query) + results = local_search(query) seen = results.map(&:full_name).uniq unless @sources.empty? @sources.each do |source| - source.unsorted_search(query, base).each do |spec| + source.unsorted_search(query).each do |spec| next if seen.include?(spec.full_name) seen << spec.full_name @@ -89,12 +89,12 @@ def sort_specs(specs) self.class.sort_specs(specs) end - def local_search(query, base = nil) + def local_search(query) case query when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query) when String then specs_by_name(query) - when Gem::Dependency then search_by_dependency(query, base) - when DepProxy then search_by_dependency(query.dep, base) + when Gem::Dependency then search_by_dependency(query) + when DepProxy then search_by_dependency(query.dep) else raise "You can't search for a #{query.inspect}." end @@ -185,11 +185,9 @@ def specs_by_name(name) @specs[name].values end - def search_by_dependency(dependency, base = nil) - @cache[base || false] ||= {} - @cache[base || false][dependency] ||= begin + def search_by_dependency(dependency) + @cache[dependency] ||= begin specs = specs_by_name(dependency.name) - specs += base if base found = specs.select do |spec| next true if spec.source.is_a?(Source::Gemspec) dependency.matches_spec?(spec) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 33f232e184767b..40bc247b32253d 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -110,7 +110,7 @@ def search_for(dependency_proxy) dependency = dependency_proxy.dep name = dependency.name @search_for[dependency_proxy] ||= begin - results = results_for(dependency, @base[name]) + results = results_for(dependency) + @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) } if vertex = @base_dg.vertex_named(name) locked_requirement = vertex.payload.requirement @@ -175,8 +175,8 @@ def source_for(name) @source_requirements[name] || @source_requirements[:default] end - def results_for(dependency, base) - index_for(dependency).search(dependency, base) + def results_for(dependency) + index_for(dependency).search(dependency) end def name_for(dependency) From b4ae144e19ea5d784dfd0ed7d486c7f533d58f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 10:25:22 +0200 Subject: [PATCH 023/142] [rubygems/rubygems] Don't use Pathname for creating extension dir Not sure why, but I run into the following flaky test failure ```` (...) Invoking `/Users/deivid/.asdf/installs/ruby/3.1.2/bin/ruby -I/Users/deivid/Code/rubygems/rubygems/bundler/spec -r/Users/deivid/Code/rubygems/rubygems/bundler/spec/support/artifice/fail.rb -r/Users/deivid/Code/rubygems/rubygems/bundler/spec/support/hax.rb /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/bin/bundle install` failed with output: ---------------------------------------------------------------------- --- ERROR REPORT TEMPLATE ------------------------------------------------------- ``` NameError: constant Pathname::FileUtils not defined FileUtils.mkpath(@path, mode: mode) ^^^^^^^^^ /Users/deivid/.asdf/installs/ruby/3.1.2/lib/ruby/3.1.0/pathname.rb:585:in `mkpath' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/shared_helpers.rb:103:in `filesystem_access' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/rubygems_gem_installer.rb:78:in `build_extensions' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/rubygems_gem_installer.rb:28:in `install' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/source/rubygems.rb:207:in `install' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/installer/gem_installer.rb:54:in `install' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/installer/gem_installer.rb:16:in `install_from_spec' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/installer/parallel_installer.rb:186:in `do_install' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/installer/parallel_installer.rb:177:in `block in worker_pool' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/worker.rb:62:in `apply_func' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/worker.rb:57:in `block in process_queue' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/worker.rb:54:in `loop' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/worker.rb:54:in `process_queue' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/4/gems/system/gems/bundler-2.4.0.dev/lib/bundler/worker.rb:91:in `block (2 levels) in create_threads' (...) ``` Whatever it was, this small change should fix it. https://github.com/rubygems/rubygems/commit/71d7503ce4 --- lib/bundler/rubygems_gem_installer.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index 12cc809664cfad..13c2d258824b55 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -72,10 +72,11 @@ def build_extensions return super end - extension_dir = Pathname.new(extension_dir) build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?) if build_complete && !options[:force] - SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath) + SharedHelpers.filesystem_access(File.dirname(extension_dir)) do |p| + FileUtils.mkpath p + end SharedHelpers.filesystem_access(extension_cache_path) do FileUtils.cp_r extension_cache_path, extension_dir end From 64f9f7d855a0367c4518e9a2a4cd26e0d0344856 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 26 Jul 2022 15:06:52 -0500 Subject: [PATCH 024/142] [ruby/rdoc] [DOC] Clarifications for directives (https://github.com/ruby/rdoc/pull/903) - Former section "Directives in Trailing Comments" is reworked. The important thing about a directive is what it does, not whether it's trailing or stand-alone. Therefore I've worked the directives in the former section into the appropriate sections, based on function. - Each directive is now explicitly marked as trailing or stand-alone. - C-code directives are mentioned only for those directives that actually appear in our ruby/ruby C files, which are :startdoc:, :stopdoc:, :enddoc:, :include:, and :call-seq:. What effect, if any, other directives have in C, I'm not sure about. https://github.com/ruby/rdoc/commit/b00978bfa5 --- doc/rdoc/markup_reference.rb | 208 ++++++++++++++++++++--------------- 1 file changed, 117 insertions(+), 91 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 77e34cfb37ee44..cc10b04871a622 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -327,19 +327,55 @@ # # ===== Directives for Allowing or Suppressing Documentation # -# Each directive described in this section must appear on a line by itself. +# - # :stopdoc:: # -# - [:stopdoc:] -# Specifies that \RDoc should ignore markup -# until next :startdoc: directive or end-of-file. -# - [:startdoc:] -# Specifies that \RDoc should resume parsing markup. -# - [:enddoc:] -# Specifies that \RDoc should ignore markup to end-of-file -# regardless of other directives. +# - Appears on a line by itself. +# - Specifies that \RDoc should ignore markup +# until next :startdoc: directive or end-of-file. +# +# - # :startdoc:: +# +# - Appears on a line by itself. +# - Specifies that \RDoc should resume parsing markup. +# +# - # :enddoc:: +# +# - Appears on a line by itself. +# - Specifies that \RDoc should ignore markup to end-of-file +# regardless of other directives. +# +# - # :nodoc:: +# +# - Appended to a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies that the defined object should not be documented. +# +# - # :nodoc: all: +# +# - Appended to a line of code +# that defines a class or module. +# - Specifies that the class or module should not be documented. +# By default, however, a nested class or module _will_ be documented. +# +# - # :doc:: +# +# - Appended to a line of code +# that defines a class, module, method, alias, constant, or attribute. +# - Specifies the defined object should be documented, even if otherwise +# would not be documented. +# +# - # :notnew: (aliased as :not_new: and :not-new:): +# +# - Appended to a line of code +# that defines instance method +initialize+. +# - Specifies that singleton method +new+ should not be documented. +# By default, Ruby fakes a corresponding singleton method +new+, +# which \RDoc includes in the documentation. +# Note that instance method +initialize+ is private, and so by default +# is not documented. # # For Ruby code, but not for other \RDoc sources, -# there is a shorthand for [:stopdoc:] and [:startdoc:]: +# there is a shorthand for :stopdoc: and :startdoc:: # # # Documented. # #-- @@ -347,45 +383,64 @@ # #++ # # Documented. # +# For C code, any of directives :startdoc:, :enddoc:, +# and :nodoc: may appear in a stand-alone comment: +# +# /* :startdoc: */ +# /* :stopdoc: */ +# /* :enddoc: */ +# # ===== Directive for Specifying \RDoc Source Format # -# This directive described must appear on a line by itself. +# - # :markup: _type_: # -# - [:markup: _type_] -# Specifies the format for the \RDoc input. -# Parameter +type+ is one of +markdown+, +rd+, +rdoc+, +tomdoc+. +# - Appears on a line by itself. +# - Specifies the format for the \RDoc input; +# parameter +type+ is one of +markdown+, +rd+, +rdoc+, +tomdoc+. # # ===== Directives for HTML Output # -# Each directive described in this section must appear on a line by itself. +# - # :title: _text_: # -# - [:title: _text_] -# Specifies the title for the HTML output. -# - [:main: _file_name_] -# Specifies the HTML file to be displayed first. +# - Appears on a line by itself. +# - Specifies the title for the HTML output. +# +# - # :main: _filename_: +# - Appears on a line by itself. +# - Specifies the HTML file to be displayed first. # # ===== Directives for Method Documentation # -# - [:call-seq:] -# For the given method, specifies the calling sequence to be reported in the HTML, -# overriding the actual calling sequence in the Ruby code. -# See method #call_seq_directive. -# - [:args: _arg_names_ (aliased as :arg)] -# For the given method, specifies the arguments to be reported in the HTML, -# overriding the actual arguments in the Ruby code. -# See method #args_directive. -# - [:yields: _arg_names_ (aliased as :yield:)] -# For the given method, specifies the yield arguments to be reported in the HTML, -# overriding the actual yield in the Ruby code. -# See method #yields_directive. -# -# Note that \RDoc can build the calling sequence for a Ruby-coded method, -# but not for other languages. -# You may want to override that by explicitly giving a :call-seq: -# directive if you want to include: -# -# - A return type, which is not automatically inferred. -# - Multiple calling sequences. +# - # :call-seq:: +# +# - Appears on a line by itself. +# - Specifies the calling sequence to be reported in the HTML, +# overriding the actual calling sequence in the code. +# See method #call_seq_directive. +# +# Note that \RDoc can build the calling sequence for a Ruby-coded method, +# but not for other languages. +# You may want to override that by explicitly giving a :call-seq: +# directive if you want to include: +# +# - A return type, which is not automatically inferred. +# - Multiple calling sequences. +# +# For C code, the directive may appear in a stand-alone comment. +# +# - # :args: _arg_names_ (aliased as :arg:): +# +# - Appears on a line by itself. +# - Specifies the arguments to be reported in the HTML, +# overriding the actual arguments in the code. +# See method #args_directive. +# +# - # :yields: _arg_names_ (aliased as :yield:): +# +# - Appears on a line by itself. +# - Specifies the yield arguments to be reported in the HTML, +# overriding the actual yield in the code. +# See method #yields_directive. # # ===== Directives for Organizing Documentation # @@ -397,16 +452,15 @@ # # You can use directives to modify those behaviors. # -# - [:section: _section_title_] -# -# Directive :section: section_title specifies that -# following methods are to be grouped into a section -# with the given section_title as its heading. -# This directive remains in effect until another such directive is given, -# but may be temporarily overridden by directive :category:. -# See below. +# - # :section: _section_title_: # -# Directive :section: with no title reverts to the default section. +# - Appears on a line by itself. +# - Specifies that following methods are to be grouped into the section +# with the given section_title, +# or into the default section if no title is given. +# The directive remains in effect until another such directive is given, +# but may be temporarily overridden by directive :category:. +# See below. # # The comment block containing this directive: # @@ -434,56 +488,28 @@ # You can use directive :category: to temporarily # override the current section. # -# - [:category: _section_title_] +# - # :category: _section_title_: # -# Directive :category: section_title specifies that -# just one following method is to be included in the given section. -# Subsequent methods are to be grouped into the current section. -# -# Directive :category: with no title specifies that just one -# following method is to be included in the default section. +# - Appears on a line by itself. +# - Specifies that just one following method is to be included +# in the given section, or in the default section if no title is given. +# Subsequent methods are to be grouped into the current section. # # ===== Directive for Including a File # -# - [:include: _filename_] -# -# Include the contents of the named file at this point. -# This directive must appear alone on one line, possibly preceded by spaces. -# In this position, it can be escaped with a backslash in front of the first colon. -# -# The file is searched for in the directories -# given with the --include command-line option, -# or in the current directory by default. -# The file content is shifted to have the same indentation as the colon -# at the start of the directive. +# - # :include: _filepath_: # -# ===== Directives in Trailing Comments +# - Appears on a line by itself. +# - Specifies that the contents of the given file +# are to be included at this point. +# The file content is shifted to have the same indentation as the colon +# at the start of the directive. # -# Each \RDoc directive in this section appears in a trailing -# comment in a line of code. +# The file is searched for in the directories +# given with the --include command-line option, +# or by default in the current directory. # -# - [:nodoc:] -# - Appears in a trailing comment on a line of code -# that defines a class, module, method, alias, constant, or attribute. -# - Specifies that the defined object should not be documented. -# - [:nodoc: all] -# - Appears in a trailing comment on a line of code -# that defines a class or module. -# - Specifies that the class or module should not be documented. -# By default, however, a nested class or module _will_ be documented -# - [:doc:] -# - Appears in a trailing comment on a line of code -# that defines a class, module, method, alias, constant, or attribute. -# - Specifies the defined object should be documented, even if otherwise -# would not be documented. -# - [:notnew: (aliased as :not_new and :not-new:)] -# - Appears in a trailing comment on a line of code -# that defines instance method +initialize+. -# - Specifies that singleton method +new+ should not be documented. -# By default, Ruby fakes a corresponding singleton method +new+, -# which \RDoc includes in the documentaton. -# Note that instance method +initialize+ is private, and so by default -# is not documented. +# For C code, the directive may appear in a stand-alone comment # # === Text Markup # From c3d9849df9759caf298e4d0edca1e59f16e153d1 Mon Sep 17 00:00:00 2001 From: moe Date: Mon, 25 Jul 2022 13:40:04 +0200 Subject: [PATCH 025/142] [rubygems/rubygems] Add ignore_funding_requests config flag https://github.com/rubygems/rubygems/commit/ab302f72c9 --- lib/bundler/cli/common.rb | 1 + lib/bundler/man/bundle-add.1 | 2 +- lib/bundler/man/bundle-binstubs.1 | 2 +- lib/bundler/man/bundle-cache.1 | 2 +- lib/bundler/man/bundle-check.1 | 2 +- lib/bundler/man/bundle-clean.1 | 2 +- lib/bundler/man/bundle-config.1 | 5 ++++- lib/bundler/man/bundle-config.1.ronn | 2 ++ lib/bundler/man/bundle-doctor.1 | 2 +- lib/bundler/man/bundle-exec.1 | 2 +- lib/bundler/man/bundle-gem.1 | 2 +- lib/bundler/man/bundle-info.1 | 2 +- lib/bundler/man/bundle-init.1 | 2 +- lib/bundler/man/bundle-inject.1 | 2 +- lib/bundler/man/bundle-install.1 | 2 +- lib/bundler/man/bundle-list.1 | 2 +- lib/bundler/man/bundle-lock.1 | 2 +- lib/bundler/man/bundle-open.1 | 2 +- lib/bundler/man/bundle-outdated.1 | 2 +- lib/bundler/man/bundle-platform.1 | 2 +- lib/bundler/man/bundle-pristine.1 | 2 +- lib/bundler/man/bundle-remove.1 | 2 +- lib/bundler/man/bundle-show.1 | 2 +- lib/bundler/man/bundle-update.1 | 2 +- lib/bundler/man/bundle-viz.1 | 2 +- lib/bundler/man/bundle.1 | 2 +- lib/bundler/man/gemfile.5 | 2 +- spec/bundler/install/gems/fund_spec.rb | 27 ++++++++++++++++++++++++++ 28 files changed, 58 insertions(+), 25 deletions(-) diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb index b547619c6af2c2..0d83a1c07e9386 100644 --- a/lib/bundler/cli/common.rb +++ b/lib/bundler/cli/common.rb @@ -15,6 +15,7 @@ def self.print_post_install_message(name, msg) end def self.output_fund_metadata_summary + return if Bundler.settings["ignore_funding_requests"] definition = Bundler.definition current_dependencies = definition.requested_dependencies current_specs = definition.specs diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1 index 1a7712486198b0..20430a78a02c26 100644 --- a/lib/bundler/man/bundle-add.1 +++ b/lib/bundler/man/bundle-add.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-ADD" "1" "June 2022" "" "" +.TH "BUNDLE\-ADD" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1 index d8312c391d9b5c..9c57c7c9c51f0e 100644 --- a/lib/bundler/man/bundle-binstubs.1 +++ b/lib/bundler/man/bundle-binstubs.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-BINSTUBS" "1" "June 2022" "" "" +.TH "BUNDLE\-BINSTUBS" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1 index 935477a3de46b8..49030158811e82 100644 --- a/lib/bundler/man/bundle-cache.1 +++ b/lib/bundler/man/bundle-cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CACHE" "1" "June 2022" "" "" +.TH "BUNDLE\-CACHE" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1 index 0f38d17bd3dce9..5be78862746450 100644 --- a/lib/bundler/man/bundle-check.1 +++ b/lib/bundler/man/bundle-check.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CHECK" "1" "June 2022" "" "" +.TH "BUNDLE\-CHECK" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1 index e0b2aac549e0e8..2bb95ed2defda4 100644 --- a/lib/bundler/man/bundle-clean.1 +++ b/lib/bundler/man/bundle-clean.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CLEAN" "1" "June 2022" "" "" +.TH "BUNDLE\-CLEAN" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 9b60c4c96183d0..76b444d8c6e681 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-CONFIG" "1" "June 2022" "" "" +.TH "BUNDLE\-CONFIG" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-config\fR \- Set bundler configuration options @@ -205,6 +205,9 @@ The following is a list of all configuration keys and their purpose\. You can le \fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\. . .IP "\(bu" 4 +\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR): When set, no funding requests will be printed\. +. +.IP "\(bu" 4 \fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\. . .IP "\(bu" 4 diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 31bb3108c8c15f..8a636641c0294f 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -204,6 +204,8 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). * `global_gem_cache` (`BUNDLE_GLOBAL_GEM_CACHE`): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation. +* `ignore_funding_requests` (`BUNDLE_IGNORE_FUNDING_REQUESTS`): + When set, no funding requests will be printed. * `ignore_messages` (`BUNDLE_IGNORE_MESSAGES`): When set, no post install messages will be printed. To silence a single gem, use dot notation like `ignore_messages.httparty true`. diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1 index 5e76db89c2dcce..6aad9858db4012 100644 --- a/lib/bundler/man/bundle-doctor.1 +++ b/lib/bundler/man/bundle-doctor.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-DOCTOR" "1" "June 2022" "" "" +.TH "BUNDLE\-DOCTOR" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-doctor\fR \- Checks the bundle for common problems diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1 index 1702c22e6fd259..210dd178e82143 100644 --- a/lib/bundler/man/bundle-exec.1 +++ b/lib/bundler/man/bundle-exec.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-EXEC" "1" "June 2022" "" "" +.TH "BUNDLE\-EXEC" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-exec\fR \- Execute a command in the context of the bundle diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1 index eb66e2d41d787b..0fb6f7d0ab39aa 100644 --- a/lib/bundler/man/bundle-gem.1 +++ b/lib/bundler/man/bundle-gem.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-GEM" "1" "June 2022" "" "" +.TH "BUNDLE\-GEM" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1 index be1a9e1dcd13e3..d3bad843b86b02 100644 --- a/lib/bundler/man/bundle-info.1 +++ b/lib/bundler/man/bundle-info.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INFO" "1" "June 2022" "" "" +.TH "BUNDLE\-INFO" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-info\fR \- Show information for the given gem in your bundle diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1 index 24f1f7543bd4c7..0b3abfeefcec98 100644 --- a/lib/bundler/man/bundle-init.1 +++ b/lib/bundler/man/bundle-init.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INIT" "1" "June 2022" "" "" +.TH "BUNDLE\-INIT" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-init\fR \- Generates a Gemfile into the current working directory diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1 index 2dbcd6e37657f8..0f6627d9a3e5a8 100644 --- a/lib/bundler/man/bundle-inject.1 +++ b/lib/bundler/man/bundle-inject.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INJECT" "1" "June 2022" "" "" +.TH "BUNDLE\-INJECT" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1 index e8184fd5105998..c742efd142451c 100644 --- a/lib/bundler/man/bundle-install.1 +++ b/lib/bundler/man/bundle-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-INSTALL" "1" "June 2022" "" "" +.TH "BUNDLE\-INSTALL" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1 index 5bc3f43943d4e9..3a9cc9a237b9d1 100644 --- a/lib/bundler/man/bundle-list.1 +++ b/lib/bundler/man/bundle-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LIST" "1" "June 2022" "" "" +.TH "BUNDLE\-LIST" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-list\fR \- List all the gems in the bundle diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1 index 2934b441719e42..ac03c5478e379b 100644 --- a/lib/bundler/man/bundle-lock.1 +++ b/lib/bundler/man/bundle-lock.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-LOCK" "1" "June 2022" "" "" +.TH "BUNDLE\-LOCK" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1 index c4e58fb8540f40..be6c5af2488b84 100644 --- a/lib/bundler/man/bundle-open.1 +++ b/lib/bundler/man/bundle-open.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OPEN" "1" "June 2022" "" "" +.TH "BUNDLE\-OPEN" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1 index ee865b3e9702da..fc3d5e8caf0a07 100644 --- a/lib/bundler/man/bundle-outdated.1 +++ b/lib/bundler/man/bundle-outdated.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-OUTDATED" "1" "June 2022" "" "" +.TH "BUNDLE\-OUTDATED" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-outdated\fR \- List installed gems with newer versions available diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1 index aab17a429a5c39..344ad930831460 100644 --- a/lib/bundler/man/bundle-platform.1 +++ b/lib/bundler/man/bundle-platform.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PLATFORM" "1" "June 2022" "" "" +.TH "BUNDLE\-PLATFORM" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-platform\fR \- Displays platform compatibility information diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1 index a0a5ac1a9bb4c6..44e5a83a01bb52 100644 --- a/lib/bundler/man/bundle-pristine.1 +++ b/lib/bundler/man/bundle-pristine.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-PRISTINE" "1" "June 2022" "" "" +.TH "BUNDLE\-PRISTINE" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1 index f6055716c78d35..29ec2460181e2b 100644 --- a/lib/bundler/man/bundle-remove.1 +++ b/lib/bundler/man/bundle-remove.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-REMOVE" "1" "June 2022" "" "" +.TH "BUNDLE\-REMOVE" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-remove\fR \- Removes gems from the Gemfile diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1 index 14db8075f6df29..227b1c8a1e361c 100644 --- a/lib/bundler/man/bundle-show.1 +++ b/lib/bundler/man/bundle-show.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-SHOW" "1" "June 2022" "" "" +.TH "BUNDLE\-SHOW" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1 index b7e2b788124a4a..7d0988bfa55d20 100644 --- a/lib/bundler/man/bundle-update.1 +++ b/lib/bundler/man/bundle-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-UPDATE" "1" "June 2022" "" "" +.TH "BUNDLE\-UPDATE" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-update\fR \- Update your gems to the latest available versions diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1 index f93ea158358de3..f6f51cde0eca59 100644 --- a/lib/bundler/man/bundle-viz.1 +++ b/lib/bundler/man/bundle-viz.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE\-VIZ" "1" "June 2022" "" "" +.TH "BUNDLE\-VIZ" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1 index e6e6cdce7b2570..c80ef51992d7cd 100644 --- a/lib/bundler/man/bundle.1 +++ b/lib/bundler/man/bundle.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BUNDLE" "1" "June 2022" "" "" +.TH "BUNDLE" "1" "July 2022" "" "" . .SH "NAME" \fBbundle\fR \- Ruby Dependency Management diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5 index 6ea1602ea41f09..63a16ca3ff48bb 100644 --- a/lib/bundler/man/gemfile.5 +++ b/lib/bundler/man/gemfile.5 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GEMFILE" "5" "June 2022" "" "" +.TH "GEMFILE" "5" "July 2022" "" "" . .SH "NAME" \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs diff --git a/spec/bundler/install/gems/fund_spec.rb b/spec/bundler/install/gems/fund_spec.rb index f521b0296f31e4..436454c1f404e8 100644 --- a/spec/bundler/install/gems/fund_spec.rb +++ b/spec/bundler/install/gems/fund_spec.rb @@ -52,6 +52,33 @@ end end + context "when gems include a fund URI but `ignore_funding_requests` is configured" do + before do + bundle "config set ignore_funding_requests true" + end + + it "does not display the plural fund message after installing" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo2)}" + gem 'has_funding_and_other_metadata' + gem 'has_funding' + gem 'rack-obama' + G + + expect(out).not_to include("2 installed gems you directly depend on are looking for funding.") + end + + it "does not display the singular fund message after installing" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo2)}" + gem 'has_funding' + gem 'rack-obama' + G + + expect(out).not_to include("1 installed gem you directly depend on is looking for funding.") + end + end + context "when gems do not include fund messages" do it "does not display any fund messages" do install_gemfile <<-G From 8154b176dee18284772d58c817851bd988e58742 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Wed, 27 Jul 2022 14:17:19 +0900 Subject: [PATCH 026/142] Manually sync with https://github.com/ruby/date/pull/64 --- ext/date/date.gemspec | 1 + ext/date/date_core.c | 154 ++++++++++++++++++++++++++++-------------- ext/date/lib/date.rb | 4 ++ 3 files changed, 109 insertions(+), 50 deletions(-) diff --git a/ext/date/date.gemspec b/ext/date/date.gemspec index cf076969766788..eecbf786a38195 100644 --- a/ext/date/date.gemspec +++ b/ext/date/date.gemspec @@ -12,6 +12,7 @@ Gem::Specification.new do |s| s.require_path = %w{lib} s.files = [ + "README.md", "lib/date.rb", "ext/date/date_core.c", "ext/date/date_parse.c", "ext/date/date_strftime.c", "ext/date/date_strptime.c", "ext/date/date_tmx.h", "ext/date/extconf.rb", "ext/date/prereq.mk", "ext/date/zonetab.h", "ext/date/zonetab.list" diff --git a/ext/date/date_core.c b/ext/date/date_core.c index d7ebcaa784a99b..a1dc9387e04cfc 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -465,6 +465,7 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns) } #ifndef NDEBUG +/* :nodoc: */ static int c_find_fdom(int y, int m, double sg, int *rjd, int *ns) { @@ -621,6 +622,7 @@ c_jd_to_weeknum(int jd, int f, double sg, int *ry, int *rw, int *rd) } #ifndef NDEBUG +/* :nodoc: */ static void c_nth_kday_to_jd(int y, int m, int n, int k, double sg, int *rjd, int *ns) { @@ -646,6 +648,7 @@ c_jd_to_wday(int jd) } #ifndef NDEBUG +/* :nodoc: */ static void c_jd_to_nth_kday(int jd, double sg, int *ry, int *rm, int *rn, int *rk) { @@ -822,6 +825,7 @@ c_valid_weeknum_p(int y, int w, int d, int f, double sg, } #ifndef NDEBUG +/* :nodoc: */ static int c_valid_nth_kday_p(int y, int m, int n, int k, double sg, int *rm, int *rn, int *rk, int *rjd, int *ns) @@ -963,6 +967,7 @@ ns_to_day(VALUE n) } #ifndef NDEBUG +/* :nodoc: */ static VALUE ms_to_sec(VALUE m) { @@ -981,6 +986,7 @@ ns_to_sec(VALUE n) } #ifndef NDEBUG +/* :nodoc: */ inline static VALUE ins_to_day(int n) { @@ -1016,6 +1022,7 @@ day_to_sec(VALUE d) } #ifndef NDEBUG +/* :nodoc: */ static VALUE day_to_ns(VALUE d) { @@ -1040,6 +1047,7 @@ sec_to_ns(VALUE s) } #ifndef NDEBUG +/* :nodoc: */ static VALUE isec_to_ns(int s) { @@ -1066,6 +1074,7 @@ div_df(VALUE d, VALUE *f) } #ifndef NDEBUG +/* :nodoc: */ static VALUE div_sf(VALUE s, VALUE *f) { @@ -1500,6 +1509,7 @@ m_df(union DateData *x) } #ifndef NDEBUG +/* :nodoc: */ static VALUE m_df_in_day(union DateData *x) { @@ -1997,6 +2007,7 @@ expect_numeric(VALUE x) } #ifndef NDEBUG +/* :nodoc: */ static void civil_to_jd(VALUE y, int m, int d, double sg, VALUE *nth, int *ry, @@ -2309,6 +2320,7 @@ valid_weeknum_p(VALUE y, int w, int d, int f, double sg, } #ifndef NDEBUG +/* :nodoc: */ static int valid_nth_kday_p(VALUE y, int m, int n, int k, double sg, VALUE *nth, int *ry, @@ -2446,6 +2458,7 @@ valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass) { @@ -2535,6 +2548,7 @@ valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass) { @@ -2626,6 +2640,7 @@ valid_ordinal_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass) { @@ -2712,6 +2727,7 @@ valid_commercial_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass) { @@ -2773,6 +2789,7 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd) { @@ -2804,6 +2821,7 @@ valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } } +/* :nodoc: */ static VALUE date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass) { @@ -2824,6 +2842,7 @@ date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass) return valid_weeknum_sub(5, argv2, klass, 1); } +/* :nodoc: */ static VALUE date_s_valid_weeknum_p(int argc, VALUE *argv, VALUE klass) { @@ -2875,6 +2894,7 @@ valid_nth_kday_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } } +/* :nodoc: */ static VALUE date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) { @@ -2895,6 +2915,7 @@ date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) return valid_nth_kday_sub(5, argv2, klass, 1); } +/* :nodoc: */ static VALUE date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) { @@ -2917,6 +2938,7 @@ date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) return Qtrue; } +/* :nodoc: */ static VALUE date_s_zone_to_diff(VALUE klass, VALUE str) { @@ -3112,6 +3134,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg, } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s_new_bang(int argc, VALUE *argv, VALUE klass) { @@ -3623,6 +3646,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s_weeknum(int argc, VALUE *argv, VALUE klass) { @@ -3672,6 +3696,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass) return ret; } +/* :nodoc: */ static VALUE date_s_nth_kday(int argc, VALUE *argv, VALUE klass) { @@ -4471,10 +4496,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * Parses the given representation of date and time, and returns a * hash of parsed elements. * - * This method *does not* function as a validator. If the input + * This method *does* *not* function as a validator. If the input * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `Date._strptime` or - * `DateTime._strptime` instead of this method as possible. + * result. Should consider to use Date._strptime or DateTime._strptime + * instead of this method as possible. * * If the optional second argument is true and the detected year is in * the range "00" to "99", considers the year a 2-digit form and makes @@ -4483,8 +4508,8 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3} * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__parse(int argc, VALUE *argv, VALUE klass) @@ -4499,10 +4524,10 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * Parses the given representation of date and time, and creates a * date object. * - * This method *does not* function as a validator. If the input + * This method *does* *not* function as a validator. If the input * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `Date.strptime` instead of this - * method as possible. + * result. Should consider to use Date.strptime instead of this method + * as possible. * * If the optional second argument is true and the detected year is in * the range "00" to "99", considers the year a 2-digit form and makes @@ -4513,8 +4538,8 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * Date.parse('3rd Feb 2001') #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. */ @@ -4560,8 +4585,8 @@ VALUE date__jisx0301(VALUE); * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__iso8601(int argc, VALUE *argv, VALUE klass) @@ -4586,8 +4611,8 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass) * Date.iso8601('2001-W05-6') #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. */ @@ -4623,8 +4648,8 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass) * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__rfc3339(int argc, VALUE *argv, VALUE klass) @@ -4647,8 +4672,8 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass) * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. */ @@ -4684,8 +4709,8 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass) * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__xmlschema(int argc, VALUE *argv, VALUE klass) @@ -4708,8 +4733,8 @@ date_s__xmlschema(int argc, VALUE *argv, VALUE klass) * Date.xmlschema('2001-02-03') #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. * @@ -4746,8 +4771,8 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass) * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * Date._rfc822 is an alias for Date._rfc2822. */ @@ -4773,8 +4798,8 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. * @@ -4811,8 +4836,8 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__httpdate(int argc, VALUE *argv, VALUE klass) @@ -4836,8 +4861,8 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. * @@ -4873,8 +4898,8 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass) * Returns a hash of parsed elements. * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE date_s__jisx0301(int argc, VALUE *argv, VALUE klass) @@ -4901,8 +4926,8 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass) * Date.jisx0301('13.02.03') #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. * * See argument {start}[rdoc-ref:Date@Argument+start]. * @@ -5097,6 +5122,7 @@ d_lite_initialize_copy(VALUE copy, VALUE date) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_fill(VALUE self) { @@ -5342,6 +5368,7 @@ d_lite_cwday(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_wnum0(VALUE self) { @@ -5349,6 +5376,7 @@ d_lite_wnum0(VALUE self) return INT2FIX(m_wnum0(dat)); } +/* :nodoc: */ static VALUE d_lite_wnum1(VALUE self) { @@ -5465,6 +5493,7 @@ d_lite_saturday_p(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k) { @@ -6841,6 +6870,7 @@ d_lite_to_s(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE mk_inspect_raw(union DateData *x, VALUE klass) { @@ -6890,6 +6920,7 @@ mk_inspect_raw(union DateData *x, VALUE klass) } } +/* :nodoc: */ static VALUE d_lite_inspect_raw(VALUE self) { @@ -7265,6 +7296,7 @@ d_lite_jisx0301(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_marshal_dump_old(VALUE self) { @@ -7551,6 +7583,9 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass) return ret; } +/* + * Same as DateTime.new. + */ static VALUE datetime_s_civil(int argc, VALUE *argv, VALUE klass) { @@ -7739,6 +7774,7 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE datetime_s_weeknum(int argc, VALUE *argv, VALUE klass) { @@ -7808,6 +7844,7 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass) return ret; } +/* :nodoc: */ static VALUE datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass) { @@ -8153,9 +8190,9 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) * Parses the given representation of date and time, and creates a * DateTime object. * - * This method *does not* function as a validator. If the input + * This method *does* *not* function as a validator. If the input * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `DateTime.strptime` instead of this + * result. Should consider to use DateTime.strptime instead of this * method as possible. * * If the optional second argument is true and the detected year is in @@ -8169,8 +8206,8 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_parse(int argc, VALUE *argv, VALUE klass) @@ -8216,8 +8253,8 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) @@ -8256,8 +8293,8 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) @@ -8296,8 +8333,8 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) @@ -8337,8 +8374,8 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) @@ -8377,8 +8414,8 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) @@ -8422,8 +8459,8 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) * #=> # * * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing `limit: nil`, but note that - * it may take a long time to parse. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. */ static VALUE datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) @@ -8813,6 +8850,7 @@ datetime_to_datetime(VALUE self) #define MIN_JD -327 #define MAX_JD 366963925 +/* :nodoc: */ static int test_civil(int from, int to, double sg) { @@ -8833,6 +8871,7 @@ test_civil(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_civil(VALUE klass) { @@ -8853,6 +8892,7 @@ date_s_test_civil(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_ordinal(int from, int to, double sg) { @@ -8873,6 +8913,7 @@ test_ordinal(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_ordinal(VALUE klass) { @@ -8893,6 +8934,7 @@ date_s_test_ordinal(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_commercial(int from, int to, double sg) { @@ -8913,6 +8955,7 @@ test_commercial(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_commercial(VALUE klass) { @@ -8933,6 +8976,7 @@ date_s_test_commercial(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_weeknum(int from, int to, int f, double sg) { @@ -8953,6 +8997,7 @@ test_weeknum(int from, int to, int f, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_weeknum(VALUE klass) { @@ -8977,6 +9022,7 @@ date_s_test_weeknum(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_nth_kday(int from, int to, double sg) { @@ -8997,6 +9043,7 @@ test_nth_kday(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_nth_kday(VALUE klass) { @@ -9017,6 +9064,7 @@ date_s_test_nth_kday(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_unit_v2v(VALUE i, VALUE (* conv1)(VALUE), @@ -9028,6 +9076,7 @@ test_unit_v2v(VALUE i, return f_eqeq_p(o, i); } +/* :nodoc: */ static int test_unit_v2v_iter2(VALUE (* conv1)(VALUE), VALUE (* conv2)(VALUE)) @@ -9059,6 +9108,7 @@ test_unit_v2v_iter2(VALUE (* conv1)(VALUE), return 1; } +/* :nodoc: */ static int test_unit_v2v_iter(VALUE (* conv1)(VALUE), VALUE (* conv2)(VALUE)) @@ -9070,6 +9120,7 @@ test_unit_v2v_iter(VALUE (* conv1)(VALUE), return 1; } +/* :nodoc: */ static VALUE date_s_test_unit_conv(VALUE klass) { @@ -9084,6 +9135,7 @@ date_s_test_unit_conv(VALUE klass) return Qtrue; } +/* :nodoc: */ static VALUE date_s_test_all(VALUE klass) { @@ -9382,6 +9434,8 @@ Init_date_core(void) * */ cDate = rb_define_class("Date", rb_cObject); + + /* Exception for invalid date/time */ eDateError = rb_define_class_under(cDate, "Error", rb_eArgError); rb_include_module(cDate, rb_mComparable); diff --git a/ext/date/lib/date.rb b/ext/date/lib/date.rb index 5770187a8e3e47..88984d7bd295aa 100644 --- a/ext/date/lib/date.rb +++ b/ext/date/lib/date.rb @@ -6,6 +6,10 @@ class Date VERSION = '3.2.2' # :nodoc: + # call-seq: + # infinite? -> false + # + # Returns +false+ def infinite? false end From 464f73a5f0c1042bfefdd367b330cbdcafffca95 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 27 Jul 2022 17:36:45 +0900 Subject: [PATCH 027/142] Do not load library files from repository only for test What we want to test should be the bundled and to be installed files, but not the upstream. --- tool/test-bundled-gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/test-bundled-gems.rb b/tool/test-bundled-gems.rb index ac27b9579c5a26..12358b69cc43ea 100644 --- a/tool/test-bundled-gems.rb +++ b/tool/test-bundled-gems.rb @@ -24,7 +24,7 @@ next if ARGV.any? {|pat| !File.fnmatch?(pat, gem)} puts "#{github_actions ? "##[group]" : "\n"}Testing the #{gem} gem" - test_command = "#{ruby} -C #{gem_dir}/src/#{gem} -Ilib #{rake} test" + test_command = "#{ruby} -C #{gem_dir}/src/#{gem} #{rake} test" first_timeout = 600 # 10min toplib = gem From 852ac26e837e63b879554cbf15e46ca70bff8681 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 27 Jul 2022 14:06:51 +0900 Subject: [PATCH 028/142] Make indents and newlines consistent [ci skip] --- io_buffer.c | 80 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/io_buffer.c b/io_buffer.c index cf6784e932e410..848b46792a2512 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -86,7 +86,8 @@ io_buffer_map_file(struct rb_io_buffer *data, int descriptor, size_t size, off_t if (flags & RB_IO_BUFFER_PRIVATE) { access |= FILE_MAP_COPY; data->flags |= RB_IO_BUFFER_PRIVATE; - } else { + } + else { // This buffer refers to external data. data->flags |= RB_IO_BUFFER_EXTERNAL; } @@ -186,7 +187,8 @@ io_buffer_initialize(struct rb_io_buffer *data, void *base, size_t size, enum rb if (!base) { rb_raise(rb_eIOBufferAllocationError, "Could not allocate buffer!"); } - } else { + } + else { // Otherwise we don't do anything. return; } @@ -304,9 +306,9 @@ io_buffer_for_make_instance(VALUE klass, VALUE string) } struct io_buffer_for_yield_instance_arguments { - VALUE klass; - VALUE string; - VALUE instance; + VALUE klass; + VALUE string; + VALUE instance; }; static VALUE @@ -377,17 +379,18 @@ rb_io_buffer_type_for(VALUE klass, VALUE string) // If the string is frozen, both code paths are okay. // If the string is not frozen, if a block is not given, it must be frozen. if (rb_block_given_p()) { - struct io_buffer_for_yield_instance_arguments arguments = { - .klass = klass, - .string = string, - .instance = Qnil, - }; + struct io_buffer_for_yield_instance_arguments arguments = { + .klass = klass, + .string = string, + .instance = Qnil, + }; - return rb_ensure(io_buffer_for_yield_instance, (VALUE)&arguments, io_buffer_for_yield_instance_ensure, (VALUE)&arguments); - } else { - // This internally returns the source string if it's already frozen. - string = rb_str_tmp_frozen_acquire(string); - return io_buffer_for_make_instance(klass, string); + return rb_ensure(io_buffer_for_yield_instance, (VALUE)&arguments, io_buffer_for_yield_instance_ensure, (VALUE)&arguments); + } + else { + // This internally returns the source string if it's already frozen. + string = rb_str_tmp_frozen_acquire(string); + return io_buffer_for_make_instance(klass, string); } } @@ -557,7 +560,8 @@ rb_io_buffer_initialize(int argc, VALUE *argv, VALUE self) if (argc > 0) { size = RB_NUM2SIZE(argv[0]); - } else { + } + else { size = RUBY_IO_BUFFER_DEFAULT_SIZE; } @@ -682,7 +686,8 @@ io_buffer_hexdump(VALUE string, size_t width, char *base, size_t size, int first if (first) { rb_str_catf(string, "0x%08" PRIxSIZE " ", offset); first = 0; - } else { + } + else { rb_str_catf(string, "\n0x%08" PRIxSIZE " ", offset); } @@ -1139,7 +1144,8 @@ rb_io_buffer_slice(VALUE self, VALUE _offset, VALUE _length) return instance; } -int rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size) +int +rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size) { struct rb_io_buffer *data = NULL; TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, data); @@ -1665,7 +1671,8 @@ io_buffer_copy_from(struct rb_io_buffer *data, const void *source_base, size_t s // The offset we copy into the buffer: if (argc >= 1) { offset = NUM2SIZET(argv[0]); - } else { + } + else { offset = 0; } @@ -1676,14 +1683,16 @@ io_buffer_copy_from(struct rb_io_buffer *data, const void *source_base, size_t s if (source_offset > source_size) { rb_raise(rb_eArgError, "The given source offset is bigger than the source itself!"); } - } else { + } + else { source_offset = 0; } // The length we are going to copy: if (argc >= 2 && !RB_NIL_P(argv[1])) { length = NUM2SIZET(argv[1]); - } else { + } + else { // Default to the source offset -> source size: length = source_size - source_offset; } @@ -1836,7 +1845,8 @@ io_buffer_get_string(int argc, VALUE *argv, VALUE self) if (argc >= 2 && !RB_NIL_P(argv[1])) { length = NUM2SIZET(argv[1]); - } else { + } + else { length = size - offset; } @@ -1956,7 +1966,8 @@ io_buffer_clear(int argc, VALUE *argv, VALUE self) size_t length; if (argc >= 3) { length = NUM2SIZET(argv[2]); - } else { + } + else { length = data->size - offset; } @@ -1965,8 +1976,9 @@ io_buffer_clear(int argc, VALUE *argv, VALUE self) return self; } -static -size_t io_buffer_default_size(size_t page_size) { +static size_t +io_buffer_default_size(size_t page_size) +{ // Platform agnostic default size, based on empirical performance observation: const size_t platform_agnostic_default_size = 64*1024; @@ -2166,7 +2178,7 @@ static void memory_and(unsigned char * restrict output, unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - output[offset] = base[offset] & mask[offset % mask_size]; + output[offset] = base[offset] & mask[offset % mask_size]; } } @@ -2206,7 +2218,7 @@ static void memory_or(unsigned char * restrict output, unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - output[offset] = base[offset] | mask[offset % mask_size]; + output[offset] = base[offset] | mask[offset % mask_size]; } } @@ -2246,7 +2258,7 @@ static void memory_xor(unsigned char * restrict output, unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - output[offset] = base[offset] ^ mask[offset % mask_size]; + output[offset] = base[offset] ^ mask[offset % mask_size]; } } @@ -2286,7 +2298,7 @@ static void memory_not(unsigned char * restrict output, unsigned char * restrict base, size_t size) { for (size_t offset = 0; offset < size; offset += 1) { - output[offset] = ~base[offset]; + output[offset] = ~base[offset]; } } @@ -2321,7 +2333,7 @@ static inline int io_buffer_overlaps(const struct rb_io_buffer *a, const struct rb_io_buffer *b) { if (a->base > b->base) { - return io_buffer_overlaps(b, a); + return io_buffer_overlaps(b, a); } return (b->base >= a->base) && (b->base <= (void*)((unsigned char *)a->base + a->size)); @@ -2338,7 +2350,7 @@ static void memory_and_inplace(unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - base[offset] &= mask[offset % mask_size]; + base[offset] &= mask[offset % mask_size]; } } @@ -2384,7 +2396,7 @@ static void memory_or_inplace(unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - base[offset] |= mask[offset % mask_size]; + base[offset] |= mask[offset % mask_size]; } } @@ -2430,7 +2442,7 @@ static void memory_xor_inplace(unsigned char * restrict base, size_t size, unsigned char * restrict mask, size_t mask_size) { for (size_t offset = 0; offset < size; offset += 1) { - base[offset] ^= mask[offset % mask_size]; + base[offset] ^= mask[offset % mask_size]; } } @@ -2476,7 +2488,7 @@ static void memory_not_inplace(unsigned char * restrict base, size_t size) { for (size_t offset = 0; offset < size; offset += 1) { - base[offset] = ~base[offset]; + base[offset] = ~base[offset]; } } From 8b9d4b2ce64d496454428292b8d723878906c966 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 27 Jul 2022 18:24:22 +0900 Subject: [PATCH 029/142] Append semicolons [ci skip] --- io_buffer.c | 88 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/io_buffer.c b/io_buffer.c index 848b46792a2512..898aa3e796f7ba 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -1500,28 +1500,28 @@ VALUE rb_io_buffer_get_value(const void* base, size_t size, ID type, size_t offset) { #define READ_TYPE(name) if (type == RB_IO_BUFFER_TYPE_##name) return io_buffer_read_##name(base, size, &offset); - READ_TYPE(U8) - READ_TYPE(S8) - - READ_TYPE(u16) - READ_TYPE(U16) - READ_TYPE(s16) - READ_TYPE(S16) - - READ_TYPE(u32) - READ_TYPE(U32) - READ_TYPE(s32) - READ_TYPE(S32) - - READ_TYPE(u64) - READ_TYPE(U64) - READ_TYPE(s64) - READ_TYPE(S64) - - READ_TYPE(f32) - READ_TYPE(F32) - READ_TYPE(f64) - READ_TYPE(F64) + READ_TYPE(U8); + READ_TYPE(S8); + + READ_TYPE(u16); + READ_TYPE(U16); + READ_TYPE(s16); + READ_TYPE(S16); + + READ_TYPE(u32); + READ_TYPE(U32); + READ_TYPE(s32); + READ_TYPE(S32); + + READ_TYPE(u64); + READ_TYPE(U64); + READ_TYPE(s64); + READ_TYPE(S64); + + READ_TYPE(f32); + READ_TYPE(F32); + READ_TYPE(f64); + READ_TYPE(F64); #undef READ_TYPE rb_raise(rb_eArgError, "Invalid type name!"); @@ -1576,28 +1576,28 @@ void rb_io_buffer_set_value(const void* base, size_t size, ID type, size_t offset, VALUE value) { #define WRITE_TYPE(name) if (type == RB_IO_BUFFER_TYPE_##name) {io_buffer_write_##name(base, size, &offset, value); return;} - WRITE_TYPE(U8) - WRITE_TYPE(S8) - - WRITE_TYPE(u16) - WRITE_TYPE(U16) - WRITE_TYPE(s16) - WRITE_TYPE(S16) - - WRITE_TYPE(u32) - WRITE_TYPE(U32) - WRITE_TYPE(s32) - WRITE_TYPE(S32) - - WRITE_TYPE(u64) - WRITE_TYPE(U64) - WRITE_TYPE(s64) - WRITE_TYPE(S64) - - WRITE_TYPE(f32) - WRITE_TYPE(F32) - WRITE_TYPE(f64) - WRITE_TYPE(F64) + WRITE_TYPE(U8); + WRITE_TYPE(S8); + + WRITE_TYPE(u16); + WRITE_TYPE(U16); + WRITE_TYPE(s16); + WRITE_TYPE(S16); + + WRITE_TYPE(u32); + WRITE_TYPE(U32); + WRITE_TYPE(s32); + WRITE_TYPE(S32); + + WRITE_TYPE(u64); + WRITE_TYPE(U64); + WRITE_TYPE(s64); + WRITE_TYPE(S64); + + WRITE_TYPE(f32); + WRITE_TYPE(F32); + WRITE_TYPE(f64); + WRITE_TYPE(F64); #undef WRITE_TYPE rb_raise(rb_eArgError, "Invalid type name!"); From f42230ff2210647d480d02a381065359be993015 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 27 Jul 2022 18:42:27 +0900 Subject: [PATCH 030/142] Adjust styles [ci skip] --- compile.c | 3 ++- debug.c | 3 ++- ext/-test-/enumerator_kw/enumerator_kw.c | 3 ++- ext/-test-/rb_call_super_kw/rb_call_super_kw.c | 3 ++- gc.c | 6 ++++-- include/ruby/fiber/scheduler.h | 12 ++++++++---- io.c | 6 ++++-- io_buffer.c | 3 ++- missing/flock.c | 8 +++++--- mjit.c | 3 ++- object.c | 12 ++++++++---- thread_pthread.c | 3 ++- vm_insnhelper.c | 3 ++- yjit.c | 3 ++- 14 files changed, 47 insertions(+), 24 deletions(-) diff --git a/compile.c b/compile.c index dc8ed459464a74..6a9ed2a5d09453 100644 --- a/compile.c +++ b/compile.c @@ -4837,7 +4837,8 @@ struct masgn_state { }; static int -add_masgn_lhs_node(struct masgn_state *state, int lhs_pos, const NODE *line_node, int argc, INSN *before_insn) { +add_masgn_lhs_node(struct masgn_state *state, int lhs_pos, const NODE *line_node, int argc, INSN *before_insn) +{ if (!state) { rb_bug("no masgn_state"); } diff --git a/debug.c b/debug.c index 81b03c540f783c..3af7f26275033a 100644 --- a/debug.c +++ b/debug.c @@ -348,7 +348,8 @@ setup_debug_log_filter(void) if (*str == '-') { debug_log.filters[i].negative = true; str++; - } else if (*str == '+') { + } + else if (*str == '+') { // negative is false on default. str++; } diff --git a/ext/-test-/enumerator_kw/enumerator_kw.c b/ext/-test-/enumerator_kw/enumerator_kw.c index 947d2b37e624ad..9104c518694634 100644 --- a/ext/-test-/enumerator_kw/enumerator_kw.c +++ b/ext/-test-/enumerator_kw/enumerator_kw.c @@ -14,7 +14,8 @@ enumerator_kw(int argc, VALUE *argv, VALUE self) } void -Init_enumerator_kw(void) { +Init_enumerator_kw(void) +{ VALUE module = rb_define_module("Bug"); module = rb_define_module_under(module, "EnumeratorKw"); rb_define_method(module, "m", enumerator_kw, -1); diff --git a/ext/-test-/rb_call_super_kw/rb_call_super_kw.c b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c index 7f094545d29150..61681ed7334498 100644 --- a/ext/-test-/rb_call_super_kw/rb_call_super_kw.c +++ b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c @@ -7,7 +7,8 @@ rb_call_super_kw_m(int argc, VALUE *argv, VALUE self) } void -Init_rb_call_super_kw(void) { +Init_rb_call_super_kw(void) +{ VALUE module = rb_define_module("Bug"); module = rb_define_module_under(module, "RbCallSuperKw"); rb_define_method(module, "m", rb_call_super_kw_m, -1); diff --git a/gc.c b/gc.c index 3ea05ba8e7bba7..7dd9cdb3c70ae4 100644 --- a/gc.c +++ b/gc.c @@ -8452,7 +8452,8 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, rb_size_pool_t *size_p } static bool -gc_compact_plane(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap, uintptr_t p, bits_t bitset, struct heap_page *page) { +gc_compact_plane(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap, uintptr_t p, bits_t bitset, struct heap_page *page) +{ short slot_size = page->slot_size; short slot_bits = slot_size / BASE_SLOT_SIZE; GC_ASSERT(slot_bits > 0); @@ -8511,7 +8512,8 @@ gc_compact_page(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *h } static bool -gc_compact_all_compacted_p(rb_objspace_t *objspace) { +gc_compact_all_compacted_p(rb_objspace_t *objspace) +{ for (int i = 0; i < SIZE_POOL_COUNT; i++) { rb_size_pool_t *size_pool = &size_pools[i]; rb_heap_t *heap = SIZE_POOL_EDEN_HEAP(size_pool); diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h index ced092adbcd3a1..9f67bd5bf6d194 100644 --- a/include/ruby/fiber/scheduler.h +++ b/include/ruby/fiber/scheduler.h @@ -43,10 +43,12 @@ struct timeval; * @return A `VALUE` which contains the result and/or errno. */ static inline VALUE -rb_fiber_scheduler_io_result(ssize_t result, int error) { +rb_fiber_scheduler_io_result(ssize_t result, int error) +{ if (result == -1) { return RB_INT2NUM(-error); - } else { + } + else { return RB_SIZE2NUM(result); } } @@ -63,11 +65,13 @@ rb_fiber_scheduler_io_result(ssize_t result, int error) { * @return The original result of the system call. */ static inline ssize_t -rb_fiber_scheduler_io_result_apply(VALUE result) { +rb_fiber_scheduler_io_result_apply(VALUE result) +{ if (RB_FIXNUM_P(result) && RB_NUM2INT(result) < 0) { errno = -RB_NUM2INT(result); return -1; - } else { + } + else { return RB_NUM2SIZE(result); } } diff --git a/io.c b/io.c index 34ccf249777c9b..de09a977989c0f 100644 --- a/io.c +++ b/io.c @@ -1224,7 +1224,8 @@ io_flush_buffer(rb_io_t *fptr) { if (!NIL_P(fptr->write_lock) && rb_mutex_owned_p(fptr->write_lock)) { return (int)io_flush_buffer_async((VALUE)fptr); - } else { + } + else { return (int)rb_mutex_synchronize(fptr->write_lock, io_flush_buffer_async, (VALUE)fptr); } } @@ -1699,7 +1700,8 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync) else { return io_binwrite_string((VALUE)&arg); } - } else { + } + else { if (fptr->wbuf.off) { if (fptr->wbuf.len) MEMMOVE(fptr->wbuf.ptr, fptr->wbuf.ptr+fptr->wbuf.off, char, fptr->wbuf.len); diff --git a/io_buffer.c b/io_buffer.c index 898aa3e796f7ba..6ce0dd13dfba76 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -312,7 +312,8 @@ struct io_buffer_for_yield_instance_arguments { }; static VALUE -io_buffer_for_yield_instance(VALUE _arguments) { +io_buffer_for_yield_instance(VALUE _arguments) +{ struct io_buffer_for_yield_instance_arguments *arguments = (struct io_buffer_for_yield_instance_arguments *)_arguments; rb_str_locktmp(arguments->string); diff --git a/missing/flock.c b/missing/flock.c index 9daf1c38ccc4ba..0b76961762597e 100644 --- a/missing/flock.c +++ b/missing/flock.c @@ -5,9 +5,11 @@ #elif defined __wasi__ #include -int flock(int fd, int operation) { - errno = EINVAL; - return -1; +int +flock(int fd, int operation) +{ + errno = EINVAL; + return -1; } #elif defined HAVE_FCNTL && defined HAVE_FCNTL_H diff --git a/mjit.c b/mjit.c index da3fd9d61e3996..01ad7339f0ebfc 100644 --- a/mjit.c +++ b/mjit.c @@ -1501,7 +1501,8 @@ create_unit(const rb_iseq_t *iseq) unit->id = current_unit_num++; if (iseq == NULL) { // Compact unit unit->compact_p = true; - } else { // Normal unit + } + else { // Normal unit unit->iseq = (rb_iseq_t *)iseq; ISEQ_BODY(iseq)->jit_unit = unit; } diff --git a/object.c b/object.c index 3a8a07736a66fc..d1743b554ba4eb 100644 --- a/object.c +++ b/object.c @@ -1623,16 +1623,19 @@ rb_class_inherited_p(VALUE mod, VALUE arg) return RCLASS_SUPERCLASSES(mod)[arg_depth] == arg ? Qtrue : Qnil; - } else if (arg_depth > mod_depth) { + } + else if (arg_depth > mod_depth) { // check if mod > arg return RCLASS_SUPERCLASSES(arg)[mod_depth] == mod ? Qfalse : Qnil; - } else { + } + else { // Depths match, and we know they aren't equal: no relation return Qnil; } - } else { + } + else { if (!CLASS_OR_MODULE_P(arg) && !RB_TYPE_P(arg, T_ICLASS)) { rb_raise(rb_eTypeError, "compared with non class/module"); } @@ -2025,7 +2028,8 @@ rb_class_superclass(VALUE klass) if (!super) { if (klass == rb_cBasicObject) return Qnil; rb_raise(rb_eTypeError, "uninitialized class"); - } else { + } + else { super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1]; RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS)); return super; diff --git a/thread_pthread.c b/thread_pthread.c index e748797fe70e9a..c29c7e195806e7 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -146,7 +146,8 @@ rb_internal_thread_remove_event_hook(rb_internal_thread_event_hook_t * hook) if (rb_internal_thread_event_hooks == hook) { ATOMIC_PTR_EXCHANGE(rb_internal_thread_event_hooks, hook->next); success = TRUE; - } else { + } + else { rb_internal_thread_event_hook_t *h = rb_internal_thread_event_hooks; do { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 2fb1ecb5f70bf5..2ff48d26626eeb 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5359,7 +5359,8 @@ vm_opt_ltlt(VALUE recv, VALUE obj) BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) { if (LIKELY(RB_TYPE_P(obj, T_STRING))) { return rb_str_buf_append(recv, obj); - } else { + } + else { return rb_str_concat(recv, obj); } } diff --git a/yjit.c b/yjit.c index daf608b106f9ed..edf5a139cc8a49 100644 --- a/yjit.c +++ b/yjit.c @@ -91,7 +91,8 @@ rb_yjit_add_frame(VALUE hash, VALUE frame) if (RTEST(rb_hash_aref(hash, frame_id))) { return; - } else { + } + else { VALUE frame_info = rb_hash_new(); // Full label for the frame VALUE name = rb_profile_frame_full_label(frame); From 64c8291c7e7b6c5e1357c48ab4edb0f434ef1739 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 27 Jul 2022 14:11:50 +0900 Subject: [PATCH 031/142] [ruby/pathname] Fix `autoload` of `FileUtils` Should not be `Pathname::FileUtils`. https://github.com/ruby/pathname/commit/d1eb366e73 --- ext/pathname/lib/pathname.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb index 41e5c171a729ac..9a297529ca64e9 100644 --- a/ext/pathname/lib/pathname.rb +++ b/ext/pathname/lib/pathname.rb @@ -574,9 +574,9 @@ def find(ignore_error: true) # :yield: pathname end -class Pathname # * FileUtils * - autoload(:FileUtils, 'fileutils') +autoload(:FileUtils, 'fileutils') +class Pathname # * FileUtils * # Creates a full path, including any intermediate directories that don't yet # exist. # From 70a9328b791f46a16e0f2d85db28b893a6ceed5b Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Wed, 27 Jul 2022 13:18:25 +0100 Subject: [PATCH 032/142] [ci-skip]Document how to run an individual bootstrap test --- doc/contributing/testing_ruby.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/contributing/testing_ruby.md b/doc/contributing/testing_ruby.md index dd46ba5dbce757..ecdb1529260f6a 100644 --- a/doc/contributing/testing_ruby.md +++ b/doc/contributing/testing_ruby.md @@ -20,6 +20,12 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+ make btest OPTS=-v ``` + To run an individual bootstrap test, we can set the filename in the environment variable `BTESTS`: + + ``` + make btest BTESTS=bootstraptest/test_gc.rb + ``` + If we want to run the bootstrap test suite on Ruby (not Miniruby), we can use: ``` From 44f42413e6c3c2b487a03b53bf6cacbb83ac285b Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 27 Jul 2022 17:18:23 +0200 Subject: [PATCH 033/142] Update to ruby/mspec@290e36a --- spec/mspec/lib/mspec/guards/superuser.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/mspec/lib/mspec/guards/superuser.rb b/spec/mspec/lib/mspec/guards/superuser.rb index e92ea7e8628945..24daf9b26cd2e5 100644 --- a/spec/mspec/lib/mspec/guards/superuser.rb +++ b/spec/mspec/lib/mspec/guards/superuser.rb @@ -6,10 +6,20 @@ def match? end end +class RealSuperUserGuard < SpecGuard + def match? + Process.uid == 0 + end +end + def as_superuser(&block) SuperUserGuard.new.run_if(:as_superuser, &block) end +def as_real_superuser(&block) + RealSuperUserGuard.new.run_if(:as_real_superuser, &block) +end + def as_user(&block) SuperUserGuard.new.run_unless(:as_user, &block) end From 6582df26dcdef5dab01242b4d97d9b242e959860 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 27 Jul 2022 17:18:25 +0200 Subject: [PATCH 034/142] Update to ruby/spec@cbfaf51 --- spec/ruby/core/enumerable/compact_spec.rb | 11 +++ spec/ruby/core/enumerator/lazy/lazy_spec.rb | 14 ++++ spec/ruby/core/file/shared/fnmatch.rb | 8 +- spec/ruby/core/range/clone_spec.rb | 26 ++++++ spec/ruby/core/range/dup_spec.rb | 4 +- spec/ruby/core/range/new_spec.rb | 10 +++ spec/ruby/core/regexp/shared/quote.rb | 5 ++ spec/ruby/core/regexp/source_spec.rb | 22 ++++- spec/ruby/core/string/capitalize_spec.rb | 3 +- spec/ruby/core/string/delete_prefix_spec.rb | 4 + spec/ruby/core/string/delete_suffix_spec.rb | 4 + spec/ruby/core/string/downcase_spec.rb | 4 + spec/ruby/core/string/encoding_spec.rb | 1 + .../string/fixtures/iso-8859-9-encoding.rb | 2 +- spec/ruby/core/string/include_spec.rb | 14 ++++ spec/ruby/core/string/inspect_spec.rb | 20 +++++ spec/ruby/core/string/lstrip_spec.rb | 34 ++++++-- spec/ruby/core/string/ord_spec.rb | 5 ++ spec/ruby/core/string/reverse_spec.rb | 17 ++++ spec/ruby/core/string/rstrip_spec.rb | 28 ++++++- spec/ruby/core/string/setbyte_spec.rb | 6 ++ spec/ruby/core/string/shared/dedup.rb | 10 +++ spec/ruby/core/string/split_spec.rb | 16 ++++ spec/ruby/core/string/start_with_spec.rb | 10 +++ spec/ruby/core/string/strip_spec.rb | 6 ++ spec/ruby/core/string/swapcase_spec.rb | 4 + spec/ruby/core/string/upcase_spec.rb | 4 + spec/ruby/language/range_spec.rb | 8 ++ spec/ruby/language/regexp/escapes_spec.rb | 84 +++++++++++++++++-- spec/ruby/language/regexp_spec.rb | 21 ----- spec/ruby/library/stringio/shared/read.rb | 6 ++ spec/ruby/optional/capi/encoding_spec.rb | 15 +++- spec/ruby/optional/capi/ext/encoding_spec.c | 7 +- spec/ruby/shared/file/executable.rb | 35 ++++++++ spec/ruby/shared/file/executable_real.rb | 35 ++++++++ spec/ruby/shared/file/readable.rb | 16 ++++ spec/ruby/shared/file/readable_real.rb | 16 ++++ spec/ruby/shared/file/writable.rb | 16 ++++ spec/ruby/shared/file/writable_real.rb | 16 ++++ spec/ruby/shared/string/end_with.rb | 9 +- spec/ruby/shared/string/start_with.rb | 4 + 41 files changed, 526 insertions(+), 54 deletions(-) create mode 100644 spec/ruby/core/enumerable/compact_spec.rb create mode 100644 spec/ruby/core/range/clone_spec.rb diff --git a/spec/ruby/core/enumerable/compact_spec.rb b/spec/ruby/core/enumerable/compact_spec.rb new file mode 100644 index 00000000000000..86e95dce085e96 --- /dev/null +++ b/spec/ruby/core/enumerable/compact_spec.rb @@ -0,0 +1,11 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is '3.1' do + describe "Enumerable#compact" do + it 'returns array without nil elements' do + arr = EnumerableSpecs::Numerous.new(nil, 1, 2, nil, true) + arr.compact.should == [1, 2, true] + end + end +end diff --git a/spec/ruby/core/enumerator/lazy/lazy_spec.rb b/spec/ruby/core/enumerator/lazy/lazy_spec.rb index cde9b310661495..683dfb81d76d7a 100644 --- a/spec/ruby/core/enumerator/lazy/lazy_spec.rb +++ b/spec/ruby/core/enumerator/lazy/lazy_spec.rb @@ -16,6 +16,10 @@ ] lazy_methods += [:chunk_while, :uniq] + ruby_version_is '3.1' do + lazy_methods += [:compact] + end + Enumerator::Lazy.instance_methods(false).should include(*lazy_methods) end end @@ -26,3 +30,13 @@ lazy.lazy.should equal(lazy) end end + +ruby_version_is '3.1' do + describe "Enumerator::Lazy#compact" do + it 'returns array without nil elements' do + arr = [1, nil, 3, false, 5].to_enum.lazy.compact + arr.should be_an_instance_of(Enumerator::Lazy) + arr.force.should == [1, 3, false, 5] + end + end +end diff --git a/spec/ruby/core/file/shared/fnmatch.rb b/spec/ruby/core/file/shared/fnmatch.rb index 00682bb64cec07..94f22144b06046 100644 --- a/spec/ruby/core/file/shared/fnmatch.rb +++ b/spec/ruby/core/file/shared/fnmatch.rb @@ -159,10 +159,10 @@ end it "does not match leading periods in filenames with wildcards by default" do - File.send(@method, '*', '.profile').should == false - File.send(@method, '*', 'home/.profile').should == true - File.send(@method, '*/*', 'home/.profile').should == true - File.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME).should == false + File.should_not.send(@method, '*', '.profile') + File.should.send(@method, '*', 'home/.profile') + File.should.send(@method, '*/*', 'home/.profile') + File.should_not.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME) end it "matches patterns with leading periods to dotfiles by default" do diff --git a/spec/ruby/core/range/clone_spec.rb b/spec/ruby/core/range/clone_spec.rb new file mode 100644 index 00000000000000..cf6ce74da09883 --- /dev/null +++ b/spec/ruby/core/range/clone_spec.rb @@ -0,0 +1,26 @@ +require_relative '../../spec_helper' + +describe "Range#clone" do + it "duplicates the range" do + original = (1..3) + copy = original.clone + copy.begin.should == 1 + copy.end.should == 3 + copy.should_not.exclude_end? + copy.should_not.equal? original + + original = ("a"..."z") + copy = original.clone + copy.begin.should == "a" + copy.end.should == "z" + copy.should.exclude_end? + copy.should_not.equal? original + end + + it "maintains the frozen state" do + (1..2).clone.frozen?.should == (1..2).frozen? + (1..).clone.frozen?.should == (1..).frozen? + Range.new(1, 2).clone.frozen?.should == Range.new(1, 2).frozen? + Class.new(Range).new(1, 2).clone.frozen?.should == Class.new(Range).new(1, 2).frozen? + end +end diff --git a/spec/ruby/core/range/dup_spec.rb b/spec/ruby/core/range/dup_spec.rb index 976d4fd1d0910b..fab3c3f1b26ce2 100644 --- a/spec/ruby/core/range/dup_spec.rb +++ b/spec/ruby/core/range/dup_spec.rb @@ -2,10 +2,12 @@ describe "Range#dup" do it "duplicates the range" do - copy = (1..3).dup + original = (1..3) + copy = original.dup copy.begin.should == 1 copy.end.should == 3 copy.should_not.exclude_end? + copy.should_not.equal?(original) copy = ("a"..."z").dup copy.begin.should == "a" diff --git a/spec/ruby/core/range/new_spec.rb b/spec/ruby/core/range/new_spec.rb index 85e99babffe9f0..40df914b830400 100644 --- a/spec/ruby/core/range/new_spec.rb +++ b/spec/ruby/core/range/new_spec.rb @@ -65,5 +65,15 @@ range_exclude.should_not == range_include end + + ruby_version_is "3.0" do + it "creates a frozen range if the class is Range.class" do + Range.new(1, 2).should.frozen? + end + + it "does not create a frozen range if the class is not Range.class" do + Class.new(Range).new(1, 2).should_not.frozen? + end + end end end diff --git a/spec/ruby/core/regexp/shared/quote.rb b/spec/ruby/core/regexp/shared/quote.rb index 33bdfd99793962..953310276692f9 100644 --- a/spec/ruby/core/regexp/shared/quote.rb +++ b/spec/ruby/core/regexp/shared/quote.rb @@ -17,6 +17,11 @@ Regexp.send(@method, str).should == '\+\[\]\(' end + it "works for broken strings" do + Regexp.send(@method, "a.\x85b.".force_encoding("US-ASCII")).should =="a\\.\x85b\\.".force_encoding("US-ASCII") + Regexp.send(@method, "a.\x80".force_encoding("UTF-8")).should == "a\\.\x80".force_encoding("UTF-8") + end + it "sets the encoding of the result to US-ASCII if there are only US-ASCII characters present in the input String" do str = "abc".force_encoding("euc-jp") Regexp.send(@method, str).encoding.should == Encoding::US_ASCII diff --git a/spec/ruby/core/regexp/source_spec.rb b/spec/ruby/core/regexp/source_spec.rb index 709fee49b3ad2c..5f253da9ea0590 100644 --- a/spec/ruby/core/regexp/source_spec.rb +++ b/spec/ruby/core/regexp/source_spec.rb @@ -9,8 +9,26 @@ /x(.)xz/.source.should == "x(.)xz" end - it "will remove escape characters" do - /foo\/bar/.source.should == "foo/bar" + it "keeps escape sequences as is" do + /\x20\+/.source.should == '\x20\+' + end + + describe "escaping" do + it "keeps escaping of metacharacter" do + /\$/.source.should == "\\$" + end + + it "keeps escaping of metacharacter used as a terminator" do + %r+\++.source.should == "\\+" + end + + it "removes escaping of non-metacharacter used as a terminator" do + %r@\@@.source.should == "@" + end + + it "keeps escaping of non-metacharacter not used as a terminator" do + /\@/.source.should == "\\@" + end end not_supported_on :opal do diff --git a/spec/ruby/core/string/capitalize_spec.rb b/spec/ruby/core/string/capitalize_spec.rb index 8afaefc0210783..751f4160a67f0f 100644 --- a/spec/ruby/core/string/capitalize_spec.rb +++ b/spec/ruby/core/string/capitalize_spec.rb @@ -10,6 +10,7 @@ "hello".capitalize.should == "Hello" "HELLO".capitalize.should == "Hello" "123ABC".capitalize.should == "123abc" + "abcdef"[1...-1].capitalize.should == "Bcde" end describe "full Unicode case mapping" do @@ -37,7 +38,7 @@ end it "handles non-ASCII substrings properly" do - "garçon"[1..-1].capitalize(:ascii).should == "Arçon" + "garçon"[1...-1].capitalize(:ascii).should == "Arço" end end diff --git a/spec/ruby/core/string/delete_prefix_spec.rb b/spec/ruby/core/string/delete_prefix_spec.rb index a063e443d8d83a..17ce18bccad8bb 100644 --- a/spec/ruby/core/string/delete_prefix_spec.rb +++ b/spec/ruby/core/string/delete_prefix_spec.rb @@ -21,6 +21,10 @@ r.should == s end + it "does not remove partial bytes, only full characters" do + "\xe3\x81\x82".delete_prefix("\xe3").should == "\xe3\x81\x82" + end + it "doesn't set $~" do $~ = nil diff --git a/spec/ruby/core/string/delete_suffix_spec.rb b/spec/ruby/core/string/delete_suffix_spec.rb index 3d3274bc5b7e89..0705c732463a82 100644 --- a/spec/ruby/core/string/delete_suffix_spec.rb +++ b/spec/ruby/core/string/delete_suffix_spec.rb @@ -21,6 +21,10 @@ r.should == s end + it "does not remove partial bytes, only full characters" do + "\xe3\x81\x82".delete_suffix("\x82").should == "\xe3\x81\x82" + end + it "doesn't set $~" do $~ = nil diff --git a/spec/ruby/core/string/downcase_spec.rb b/spec/ruby/core/string/downcase_spec.rb index 86d84808890662..f0a15f1e25f120 100644 --- a/spec/ruby/core/string/downcase_spec.rb +++ b/spec/ruby/core/string/downcase_spec.rb @@ -27,6 +27,10 @@ it "does not downcase non-ASCII characters" do "Câ„«R".downcase(:ascii).should == "câ„«r" end + + it "works with substrings" do + "prefix TÉ"[-2..-1].downcase(:ascii).should == "tÉ" + end end describe "full Unicode case mapping adapted for Turkic languages" do diff --git a/spec/ruby/core/string/encoding_spec.rb b/spec/ruby/core/string/encoding_spec.rb index 4d17a39f29427f..574a1e2f9287df 100644 --- a/spec/ruby/core/string/encoding_spec.rb +++ b/spec/ruby/core/string/encoding_spec.rb @@ -10,6 +10,7 @@ it "is equal to the source encoding by default" do s = StringSpecs::ISO88599Encoding.new s.cedilla.encoding.should == s.source_encoding + s.cedilla.encode("utf-8").should == 350.chr(Encoding::UTF_8) # S-cedilla end it "returns the given encoding if #force_encoding has been called" do diff --git a/spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb b/spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb index 61a691ff789d65..cfa91dedc3a641 100644 --- a/spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb +++ b/spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb @@ -4,6 +4,6 @@ class ISO88599Encoding def source_encoding; __ENCODING__; end def x_escape; [0xDF].pack('C').force_encoding("iso-8859-9"); end def ascii_only; "glark"; end - def cedilla; "Åž"; end + def cedilla; "Þ"; end # S-cedilla end end diff --git a/spec/ruby/core/string/include_spec.rb b/spec/ruby/core/string/include_spec.rb index e32eb17c29e2b6..23e1e134ec73f3 100644 --- a/spec/ruby/core/string/include_spec.rb +++ b/spec/ruby/core/string/include_spec.rb @@ -13,6 +13,20 @@ StringSpecs::MyString.new("hello").include?(StringSpecs::MyString.new("lo")).should == true end + it "returns true if both strings are empty" do + "".should.include?("") + "".force_encoding("EUC-JP").should.include?("") + "".should.include?("".force_encoding("EUC-JP")) + "".force_encoding("EUC-JP").should.include?("".force_encoding("EUC-JP")) + end + + it "returns true if the RHS is empty" do + "a".should.include?("") + "a".force_encoding("EUC-JP").should.include?("") + "a".should.include?("".force_encoding("EUC-JP")) + "a".force_encoding("EUC-JP").should.include?("".force_encoding("EUC-JP")) + end + it "tries to convert other to string using to_str" do other = mock('lo') other.should_receive(:to_str).and_return("lo") diff --git a/spec/ruby/core/string/inspect_spec.rb b/spec/ruby/core/string/inspect_spec.rb index 8bfd465144d6b4..8bf3d3161fba7c 100644 --- a/spec/ruby/core/string/inspect_spec.rb +++ b/spec/ruby/core/string/inspect_spec.rb @@ -19,6 +19,21 @@ ].should be_computed_by(:inspect) end + it "returns a string with special characters replaced with \\ notation for UTF-16" do + pairs = [ + ["\a", '"\\a"'], + ["\b", '"\\b"'], + ["\t", '"\\t"'], + ["\n", '"\\n"'], + ["\v", '"\\v"'], + ["\f", '"\\f"'], + ["\r", '"\\r"'], + ["\e", '"\\e"'] + ].map { |str, result| [str.encode('UTF-16LE'), result] } + + pairs.should be_computed_by(:inspect) + end + it "returns a string with \" and \\ escaped with a backslash" do [ ["\"", '"\\""'], ["\\", '"\\\\"'] @@ -311,6 +326,11 @@ "\xF0\x9F".inspect.should == '"\\xF0\\x9F"' end + it "works for broken US-ASCII strings" do + s = "©".force_encoding("US-ASCII") + s.inspect.should == '"\xC2\xA9"' + end + describe "when default external is UTF-8" do before :each do @extenc, Encoding.default_external = Encoding.default_external, Encoding::UTF_8 diff --git a/spec/ruby/core/string/lstrip_spec.rb b/spec/ruby/core/string/lstrip_spec.rb index 02bc6b4322f6be..75434613f18bac 100644 --- a/spec/ruby/core/string/lstrip_spec.rb +++ b/spec/ruby/core/string/lstrip_spec.rb @@ -10,6 +10,14 @@ " hello world ".lstrip.should == "hello world " "\n\r\t\n\v\r hello world ".lstrip.should == "hello world " "hello".lstrip.should == "hello" + " ã“ã«ã¡ã‚".lstrip.should == "ã“ã«ã¡ã‚" + end + + it "works with lazy substrings" do + " hello "[1...-1].lstrip.should == "hello " + " hello world "[1...-1].lstrip.should == "hello world " + "\n\r\t\n\v\r hello world "[1...-1].lstrip.should == "hello world " + " ã“ã«ã¡ã‚ "[1...-1].lstrip.should == "ã“ã«ã¡ã‚" end ruby_version_is '3.0' do @@ -27,20 +35,26 @@ a.should == "hello " end + it "returns nil if no modifications were made" do + a = "hello" + a.lstrip!.should == nil + a.should == "hello" + end + + it "makes a string empty if it is only whitespace" do + "".lstrip!.should == nil + " ".lstrip.should == "" + " ".lstrip.should == "" + end + ruby_version_is '3.0' do - it "strips leading \\0" do + it "removes leading NULL bytes and whitespace" do a = "\000 \000hello\000 \000" a.lstrip! a.should == "hello\000 \000" end end - it "returns nil if no modifications were made" do - a = "hello" - a.lstrip!.should == nil - a.should == "hello" - end - it "raises a FrozenError on a frozen instance that is modified" do -> { " hello ".freeze.lstrip! }.should raise_error(FrozenError) end @@ -51,9 +65,13 @@ -> { "".freeze.lstrip! }.should raise_error(FrozenError) end - it "raises an ArgumentError if the first codepoint is invalid" do + it "raises an ArgumentError if the first non-space codepoint is invalid" do s = "\xDFabc".force_encoding(Encoding::UTF_8) s.valid_encoding?.should be_false -> { s.lstrip! }.should raise_error(ArgumentError) + + s = " \xDFabc".force_encoding(Encoding::UTF_8) + s.valid_encoding?.should be_false + -> { s.lstrip! }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/core/string/ord_spec.rb b/spec/ruby/core/string/ord_spec.rb index cfc630a1249d83..4cf26990fedec8 100644 --- a/spec/ruby/core/string/ord_spec.rb +++ b/spec/ruby/core/string/ord_spec.rb @@ -25,4 +25,9 @@ it "raises an ArgumentError if called on an empty String" do -> { ''.ord }.should raise_error(ArgumentError) end + + it "raises ArgumentError if the character is broken" do + s = "©".force_encoding("US-ASCII") + -> { s.ord }.should raise_error(ArgumentError, "invalid byte sequence in US-ASCII") + end end diff --git a/spec/ruby/core/string/reverse_spec.rb b/spec/ruby/core/string/reverse_spec.rb index bade4685d9966e..4206b8af90b7f4 100644 --- a/spec/ruby/core/string/reverse_spec.rb +++ b/spec/ruby/core/string/reverse_spec.rb @@ -29,6 +29,14 @@ it "reverses a string with multi byte characters" do "微軟正黑體".reverse.should == "體黑正軟微" end + + it "works with a broken string" do + str = "微軟\xDF\xDE正黑體".force_encoding(Encoding::UTF_8) + + str.valid_encoding?.should be_false + + str.reverse.should == "體黑正\xDE\xDF軟微" + end end describe "String#reverse!" do @@ -55,4 +63,13 @@ str.reverse! str.should == "體黑正軟微" end + + it "works with a broken string" do + str = "微軟\xDF\xDE正黑體".force_encoding(Encoding::UTF_8) + + str.valid_encoding?.should be_false + str.reverse! + + str.should == "體黑正\xDE\xDF軟微" + end end diff --git a/spec/ruby/core/string/rstrip_spec.rb b/spec/ruby/core/string/rstrip_spec.rb index dc34b12719ed9d..4332b33b20046f 100644 --- a/spec/ruby/core/string/rstrip_spec.rb +++ b/spec/ruby/core/string/rstrip_spec.rb @@ -11,6 +11,14 @@ " hello world \n\r\t\n\v\r".rstrip.should == " hello world" "hello".rstrip.should == "hello" "hello\x00".rstrip.should == "hello" + "ã“ã«ã¡ã‚ ".rstrip.should == "ã“ã«ã¡ã‚" + end + + it "works with lazy substrings" do + " hello "[1...-1].rstrip.should == " hello" + " hello world "[1...-1].rstrip.should == " hello world" + " hello world \n\r\t\n\v\r"[1...-1].rstrip.should == " hello world" + " ã“ã«ã¡ã‚ "[1...-1].rstrip.should == "ã“ã«ã¡ã‚" end it "returns a copy of self with all trailing whitespace and NULL bytes removed" do @@ -37,6 +45,20 @@ a.should == "hello" end + it "makes a string empty if it is only whitespace" do + "".rstrip!.should == nil + " ".rstrip.should == "" + " ".rstrip.should == "" + end + + ruby_version_is '3.0' do + it "removes trailing NULL bytes and whitespace" do + a = "\000 goodbye \000" + a.rstrip! + a.should == "\000 goodbye" + end + end + it "raises a FrozenError on a frozen instance that is modified" do -> { " hello ".freeze.rstrip! }.should raise_error(FrozenError) end @@ -47,9 +69,13 @@ -> { "".freeze.rstrip! }.should raise_error(FrozenError) end - it "raises an ArgumentError if the last codepoint is invalid" do + it "raises an ArgumentError if the last non-space codepoint is invalid" do s = "abc\xDF".force_encoding(Encoding::UTF_8) s.valid_encoding?.should be_false -> { s.rstrip! }.should raise_error(ArgumentError) + + s = "abc\xDF ".force_encoding(Encoding::UTF_8) + s.valid_encoding?.should be_false + -> { s.rstrip! }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/core/string/setbyte_spec.rb b/spec/ruby/core/string/setbyte_spec.rb index 03e5bad88b7c57..77bff6403850f6 100644 --- a/spec/ruby/core/string/setbyte_spec.rb +++ b/spec/ruby/core/string/setbyte_spec.rb @@ -36,6 +36,12 @@ str.valid_encoding?.should be_true str.setbyte(2,253) str.valid_encoding?.should be_false + + str = "ABC" + str.setbyte(0, 0x20) # ' ' + str.should.valid_encoding? + str.setbyte(0, 0xE3) + str.should_not.valid_encoding? end it "regards a negative index as counting from the end of the String" do diff --git a/spec/ruby/core/string/shared/dedup.rb b/spec/ruby/core/string/shared/dedup.rb index 345e8745835c54..6ffcb9b04553a7 100644 --- a/spec/ruby/core/string/shared/dedup.rb +++ b/spec/ruby/core/string/shared/dedup.rb @@ -38,6 +38,16 @@ dynamic.send(@method).should equal("this string is frozen".send(@method).freeze) end + it "does not deduplicate a frozen string when it has instance variables" do + dynamic = %w(this string is frozen).join(' ') + dynamic.instance_variable_set(:@a, 1) + dynamic.freeze + + dynamic.send(@method).should_not equal("this string is frozen".freeze) + dynamic.send(@method).should_not equal("this string is frozen".send(@method).freeze) + dynamic.send(@method).should equal(dynamic) + end + ruby_version_is "3.0" do it "interns the provided string if it is frozen" do dynamic = "this string is unique and frozen #{rand}".freeze diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb index 7ef34c65daae48..b57f6608166302 100644 --- a/spec/ruby/core/string/split_spec.rb +++ b/spec/ruby/core/string/split_spec.rb @@ -455,6 +455,14 @@ a.should == ["Chunky", "Bacon"] end + it "yields each split substring with default pattern for a lazy substring" do + a = [] + returned_object = "chunky bacon"[1...-1].split { |str| a << str.capitalize } + + returned_object.should == "hunky baco" + a.should == ["Hunky", "Baco"] + end + it "yields each split substring with default pattern for a non-ASCII string" do a = [] returned_object = "l'été arrive bientôt".split { |str| a << str } @@ -463,6 +471,14 @@ a.should == ["l'été", "arrive", "bientôt"] end + it "yields each split substring with default pattern for a non-ASCII lazy substring" do + a = [] + returned_object = "l'été arrive bientôt"[1...-1].split { |str| a << str } + + returned_object.should == "'été arrive bientô" + a.should == ["'été", "arrive", "bientô"] + end + it "yields the string when limit is 1" do a = [] returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize } diff --git a/spec/ruby/core/string/start_with_spec.rb b/spec/ruby/core/string/start_with_spec.rb index aaed197ff372a3..3833289f96d488 100644 --- a/spec/ruby/core/string/start_with_spec.rb +++ b/spec/ruby/core/string/start_with_spec.rb @@ -5,4 +5,14 @@ describe "String#start_with?" do it_behaves_like :start_with, :to_s + + # Here and not in the shared examples because this is invalid as a Symbol + it "does not check that we are not starting to match at the head of a character" do + "\xA9".should.start_with?("\xA9") # A9 is not a character head for UTF-8 + end + + it "does not check we are matching only part of a character" do + "\xe3\x81\x82".size.should == 1 + "\xe3\x81\x82".should.start_with?("\xe3") + end end diff --git a/spec/ruby/core/string/strip_spec.rb b/spec/ruby/core/string/strip_spec.rb index e841db54ce401b..662f13b03219c7 100644 --- a/spec/ruby/core/string/strip_spec.rb +++ b/spec/ruby/core/string/strip_spec.rb @@ -35,6 +35,12 @@ a.should == "hello" end + it "makes a string empty if it is only whitespace" do + "".strip!.should == nil + " ".strip.should == "" + " ".strip.should == "" + end + ruby_version_is '3.0' do it "removes leading and trailing NULL bytes and whitespace" do a = "\000 goodbye \000" diff --git a/spec/ruby/core/string/swapcase_spec.rb b/spec/ruby/core/string/swapcase_spec.rb index 417f6c6d8d76b2..6307a1eaafe602 100644 --- a/spec/ruby/core/string/swapcase_spec.rb +++ b/spec/ruby/core/string/swapcase_spec.rb @@ -28,6 +28,10 @@ it "does not swapcase non-ASCII characters" do "aßet".swapcase(:ascii).should == "AßET" end + + it "works with substrings" do + "prefix aTé"[-3..-1].swapcase(:ascii).should == "Até" + end end describe "full Unicode case mapping adapted for Turkic languages" do diff --git a/spec/ruby/core/string/upcase_spec.rb b/spec/ruby/core/string/upcase_spec.rb index b2b34190feaab8..209fe73b6ec985 100644 --- a/spec/ruby/core/string/upcase_spec.rb +++ b/spec/ruby/core/string/upcase_spec.rb @@ -27,6 +27,10 @@ it "does not upcase non-ASCII characters" do "aßet".upcase(:ascii).should == "AßET" end + + it "works with substrings" do + "prefix té"[-2..-1].upcase(:ascii).should == "Té" + end end describe "full Unicode case mapping adapted for Turkic languages" do diff --git a/spec/ruby/language/range_spec.rb b/spec/ruby/language/range_spec.rb index 55dc65882a9e2a..ccc9f55537d5fd 100644 --- a/spec/ruby/language/range_spec.rb +++ b/spec/ruby/language/range_spec.rb @@ -10,6 +10,14 @@ (1...10).should == Range.new(1, 10, true) end + it "creates a simple range as an object literal" do + ary = [] + 2.times do + ary.push(1..3) + end + ary[0].should.equal?(ary[1]) + end + it "creates endless ranges" do (1..).should == Range.new(1, nil) (1...).should == Range.new(1, nil, true) diff --git a/spec/ruby/language/regexp/escapes_spec.rb b/spec/ruby/language/regexp/escapes_spec.rb index 2e5fe5ad2e64fa..16a4d8c23b2bf6 100644 --- a/spec/ruby/language/regexp/escapes_spec.rb +++ b/spec/ruby/language/regexp/escapes_spec.rb @@ -2,8 +2,10 @@ require_relative '../../spec_helper' require_relative '../fixtures/classes' +# TODO: synchronize with spec/core/regexp/new_spec.rb - +# escaping is also tested there describe "Regexps with escape characters" do - it "they're supported" do + it "supports escape sequences" do /\t/.match("\t").to_a.should == ["\t"] # horizontal tab /\v/.match("\v").to_a.should == ["\v"] # vertical tab /\n/.match("\n").to_a.should == ["\n"] # newline @@ -15,9 +17,7 @@ # \nnn octal char (encoded byte value) end - it "support quoting meta-characters via escape sequence" do - /\\/.match("\\").to_a.should == ["\\"] - /\//.match("/").to_a.should == ["/"] + it "supports quoting meta-characters via escape sequence" do # parenthesis, etc /\(/.match("(").to_a.should == ["("] /\)/.match(")").to_a.should == [")"] @@ -25,6 +25,8 @@ /\]/.match("]").to_a.should == ["]"] /\{/.match("{").to_a.should == ["{"] /\}/.match("}").to_a.should == ["}"] + /\/.match(">").to_a.should == [">"] # alternation separator /\|/.match("|").to_a.should == ["|"] # quantifiers @@ -37,11 +39,81 @@ /\$/.match("$").to_a.should == ["$"] end + it "supports quoting meta-characters via escape sequence when used as a terminator" do + # parenthesis, etc + # %r[[, %r((, etc literals - are forbidden + %r(\().match("(").to_a.should == ["("] + %r(\)).match(")").to_a.should == [")"] + %r)\().match("(").to_a.should == ["("] + %r)\)).match(")").to_a.should == [")"] + + %r[\[].match("[").to_a.should == ["["] + %r[\]].match("]").to_a.should == ["]"] + %r]\[].match("[").to_a.should == ["["] + %r]\]].match("]").to_a.should == ["]"] + + %r{\{}.match("{").to_a.should == ["{"] + %r{\}}.match("}").to_a.should == ["}"] + %r}\{}.match("{").to_a.should == ["{"] + %r}\}}.match("}").to_a.should == ["}"] + + %r<\<>.match("<").to_a.should == ["<"] + %r<\>>.match(">").to_a.should == [">"] + %r>\<>.match("<").to_a.should == ["<"] + %r>\>>.match(">").to_a.should == [">"] + + # alternation separator + %r|\||.match("|").to_a.should == ["|"] + # quantifiers + %r?\??.match("?").to_a.should == ["?"] + %r.\...match(".").to_a.should == ["."] + %r*\**.match("*").to_a.should == ["*"] + %r+\++.match("+").to_a.should == ["+"] + # line anchors + %r^\^^.match("^").to_a.should == ["^"] + %r$\$$.match("$").to_a.should == ["$"] + end + + it "supports quoting non-meta-characters via escape sequence when used as a terminator" do + non_meta_character_terminators = [ + '!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`', '/', '=', '~' + ] + + non_meta_character_terminators.each do |c| + pattern = eval("%r" + c + "\\" + c + c) + pattern.match(c).to_a.should == [c] + end + end + + it "does not change semantics of escaped non-meta-character when used as a terminator" do + all_terminators = [*("!".."/"), *(":".."@"), *("[".."`"), *("{".."~")] + meta_character_terminators = ["$", "^", "*", "+", ".", "?", "|", "}", ")", ">", "]"] + special_cases = ['(', '{', '[', '<', '\\'] + + # it should be equivalent to + # [ '!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`', '/', '=', '~' ] + non_meta_character_terminators = all_terminators - meta_character_terminators - special_cases + + non_meta_character_terminators.each do |c| + pattern = eval("%r" + c + "\\" + c + c) + pattern.should == /#{c}/ + end + end + + it "does not change semantics of escaped meta-character when used as a terminator" do + meta_character_terminators = ["$", "^", "*", "+", ".", "?", "|", "}", ")", ">", "]"] + + meta_character_terminators.each do |c| + pattern = eval("%r" + c + "\\" + c + c) + pattern.should == eval("/\\#{c}/") + end + end + it "allows any character to be escaped" do /\y/.match("y").to_a.should == ["y"] end - it "support \\x (hex characters)" do + it "supports \\x (hex characters)" do /\xA/.match("\nxyz").to_a.should == ["\n"] /\x0A/.match("\n").to_a.should == ["\n"] /\xAA/.match("\nA").should be_nil @@ -53,7 +125,7 @@ # \x{7HHHHHHH} wide hexadecimal char (character code point value) end - it "support \\c (control characters)" do + it "supports \\c (control characters)" do #/\c \c@\c`/.match("\00\00\00").to_a.should == ["\00\00\00"] /\c#\cc\cC/.match("\03\03\03").to_a.should == ["\03\03\03"] /\c'\cG\cg/.match("\a\a\a").to_a.should == ["\a\a\a"] diff --git a/spec/ruby/language/regexp_spec.rb b/spec/ruby/language/regexp_spec.rb index 8fc4dc4f0a8973..d49689349dd08c 100644 --- a/spec/ruby/language/regexp_spec.rb +++ b/spec/ruby/language/regexp_spec.rb @@ -96,7 +96,6 @@ /./.match("\0").to_a.should == ["\0"] end - it "supports | (alternations)" do /a|b/.match("a").to_a.should == ["a"] end @@ -161,26 +160,6 @@ pattern.should_not =~ 'T' end - escapable_terminators = ['!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`'] - - it "supports escaping characters when used as a terminator" do - escapable_terminators.each do |c| - ref = "(?-mix:#{c})" - pattern = eval("%r" + c + "\\" + c + c) - pattern.to_s.should == ref - end - end - - it "treats an escaped non-escapable character normally when used as a terminator" do - all_terminators = [*("!".."/"), *(":".."@"), *("[".."`"), *("{".."~")] - special_cases = ['(', '{', '[', '<', '\\', '=', '~'] - (all_terminators - special_cases - escapable_terminators).each do |c| - ref = "(?-mix:\\#{c})" - pattern = eval("%r" + c + "\\" + c + c) - pattern.to_s.should == ref - end - end - it "support handling unicode 9.0 characters with POSIX bracket expressions" do char_lowercase = "\u{104D8}" # OSAGE SMALL LETTER A /[[:lower:]]/.match(char_lowercase).to_s.should == char_lowercase diff --git a/spec/ruby/library/stringio/shared/read.rb b/spec/ruby/library/stringio/shared/read.rb index c60677bba75f05..252a85d89d9042 100644 --- a/spec/ruby/library/stringio/shared/read.rb +++ b/spec/ruby/library/stringio/shared/read.rb @@ -89,6 +89,12 @@ @io.send(@method) @io.pos.should eql(7) end + + it "correctly update the current position in bytes when multi-byte characters are used" do + @io.print("example\u03A3") # Overwrite the original string with 8 characters containing 9 bytes. + @io.send(@method) + @io.pos.should eql(9) + end end describe :stringio_read_nil, shared: true do diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb index e18108c022fcb3..ae557b03d76a0a 100644 --- a/spec/ruby/optional/capi/encoding_spec.rb +++ b/spec/ruby/optional/capi/encoding_spec.rb @@ -128,10 +128,16 @@ describe "rb_enc_mbc_to_codepoint" do it "returns the correct codepoint for the given character and size" do - @s.rb_enc_mbc_to_codepoint("é", 2).should == 0x00E9 - @s.rb_enc_mbc_to_codepoint("éa", 2).should == 0x00E9 - @s.rb_enc_mbc_to_codepoint("éa", 1).should == 0xC3 - @s.rb_enc_mbc_to_codepoint("éa", 3).should == 0x00E9 + @s.rb_enc_mbc_to_codepoint("é").should == 0xE9 + end + + it "returns 0 if p == e" do + @s.rb_enc_mbc_to_codepoint("").should == 0 + end + + it "returns the raw byte if incomplete character in UTF-8" do + @s.rb_enc_mbc_to_codepoint("\xC3").should == 0xC3 + @s.rb_enc_mbc_to_codepoint("\x80").should == 0x80 end end @@ -630,6 +636,7 @@ it "returns the correct case fold for the given string" do @s.ONIGENC_MBC_CASE_FOLD("lower").should == ["l", 1] @s.ONIGENC_MBC_CASE_FOLD("Upper").should == ["u", 1] + @s.ONIGENC_MBC_CASE_FOLD("ABC"[1..-1]).should == ["b", 1] end it "works with other encodings" do diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c index 68c4161bab0c43..c49f6cde7e6e00 100644 --- a/spec/ruby/optional/capi/ext/encoding_spec.c +++ b/spec/ruby/optional/capi/ext/encoding_spec.c @@ -120,10 +120,9 @@ static VALUE encoding_spec_rb_enc_from_index(VALUE self, VALUE index) { return rb_str_new2(rb_enc_from_index(NUM2INT(index))->name); } -static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str, VALUE offset) { - int o = FIX2INT(offset); +static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str) { char *p = RSTRING_PTR(str); - char *e = p + o; + char *e = RSTRING_END(str); return INT2FIX(rb_enc_mbc_to_codepoint(p, e, rb_enc_get(str))); } @@ -341,7 +340,7 @@ void Init_encoding_spec(void) { rb_define_method(cls, "rb_enc_isalnum", encoding_spec_rb_enc_isalnum, 2); rb_define_method(cls, "rb_enc_isspace", encoding_spec_rb_enc_isspace, 2); rb_define_method(cls, "rb_enc_from_index", encoding_spec_rb_enc_from_index, 1); - rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 2); + rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 1); rb_define_method(cls, "rb_enc_mbcput", encoding_spec_rb_enc_mbcput, 2); rb_define_method(cls, "rb_enc_from_encoding", encoding_spec_rb_enc_from_encoding, 1); rb_define_method(cls, "rb_enc_get", encoding_spec_rb_enc_get, 1); diff --git a/spec/ruby/shared/file/executable.rb b/spec/ruby/shared/file/executable.rb index 7b5c4c580c2bf7..baa156de9862dd 100644 --- a/spec/ruby/shared/file/executable.rb +++ b/spec/ruby/shared/file/executable.rb @@ -39,6 +39,41 @@ -> { @object.send(@method, nil) }.should raise_error(TypeError) -> { @object.send(@method, false) }.should raise_error(TypeError) end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + before :each do + @file = tmp('temp3.txt') + touch @file + end + + after :each do + rm_r @file + end + + it "returns true if file owner has permission to execute" do + File.chmod(0766, @file) + @object.send(@method, @file).should == true + end + + it "returns true if group has permission to execute" do + File.chmod(0676, @file) + @object.send(@method, @file).should == true + end + + it "returns true if other have permission to execute" do + File.chmod(0667, @file) + @object.send(@method, @file).should == true + end + + it "return false if nobody has permission to execute" do + File.chmod(0666, @file) + @object.send(@method, @file).should == false + end + end + end + end end describe :file_executable_missing, shared: true do diff --git a/spec/ruby/shared/file/executable_real.rb b/spec/ruby/shared/file/executable_real.rb index ce3d5ca1768dc3..bf2734ea071fdf 100644 --- a/spec/ruby/shared/file/executable_real.rb +++ b/spec/ruby/shared/file/executable_real.rb @@ -37,6 +37,41 @@ -> { @object.send(@method, nil) }.should raise_error(TypeError) -> { @object.send(@method, false) }.should raise_error(TypeError) end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + before :each do + @file = tmp('temp3.txt') + touch @file + end + + after :each do + rm_r @file + end + + it "returns true if file owner has permission to execute" do + File.chmod(0766, @file) + @object.send(@method, @file).should == true + end + + it "returns true if group has permission to execute" do + File.chmod(0676, @file) + @object.send(@method, @file).should == true + end + + it "returns true if other have permission to execute" do + File.chmod(0667, @file) + @object.send(@method, @file).should == true + end + + it "return false if nobody has permission to execute" do + File.chmod(0666, @file) + @object.send(@method, @file).should == false + end + end + end + end end describe :file_executable_real_missing, shared: true do diff --git a/spec/ruby/shared/file/readable.rb b/spec/ruby/shared/file/readable.rb index eb2ca068121823..7b45e23e3607e1 100644 --- a/spec/ruby/shared/file/readable.rb +++ b/spec/ruby/shared/file/readable.rb @@ -24,6 +24,22 @@ it "accepts an object that has a #to_path method" do @object.send(@method, mock_to_path(@file2)).should == true end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0333, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end end describe :file_readable_missing, shared: true do diff --git a/spec/ruby/shared/file/readable_real.rb b/spec/ruby/shared/file/readable_real.rb index b6e53ac76d7579..32d38bc7a23fb5 100644 --- a/spec/ruby/shared/file/readable_real.rb +++ b/spec/ruby/shared/file/readable_real.rb @@ -14,6 +14,22 @@ it "accepts an object that has a #to_path method" do File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true } end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0333, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end end describe :file_readable_real_missing, shared: true do diff --git a/spec/ruby/shared/file/writable.rb b/spec/ruby/shared/file/writable.rb index 4bb8aedce6840b..65ea2c1781a6d7 100644 --- a/spec/ruby/shared/file/writable.rb +++ b/spec/ruby/shared/file/writable.rb @@ -19,6 +19,22 @@ it "accepts an object that has a #to_path method" do File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true } end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0555, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end end describe :file_writable_missing, shared: true do diff --git a/spec/ruby/shared/file/writable_real.rb b/spec/ruby/shared/file/writable_real.rb index e9721fd379b88e..b4a0a58c6e4391 100644 --- a/spec/ruby/shared/file/writable_real.rb +++ b/spec/ruby/shared/file/writable_real.rb @@ -24,6 +24,22 @@ -> { @object.send(@method, nil) }.should raise_error(TypeError) -> { @object.send(@method, false) }.should raise_error(TypeError) end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0555, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end end describe :file_writable_real_missing, shared: true do diff --git a/spec/ruby/shared/string/end_with.rb b/spec/ruby/shared/string/end_with.rb index 5f2a0112356517..0e4c1386e8e7eb 100644 --- a/spec/ruby/shared/string/end_with.rb +++ b/spec/ruby/shared/string/end_with.rb @@ -38,7 +38,7 @@ it "uses only the needed arguments" do find = mock('h') find.should_not_receive(:to_str) - "hello".send(@method).should.end_with?("o",find) + "hello".send(@method).should.end_with?("o", find) end it "works for multibyte strings" do @@ -51,4 +51,11 @@ "ã‚れ".send(@method).end_with?(pat) end.should raise_error(Encoding::CompatibilityError) end + + it "checks that we are starting to match at the head of a character" do + "\xC3\xA9".send(@method).should_not.end_with?("\xA9") + "\xe3\x81\x82".send(@method).should_not.end_with?("\x82") + "ab".force_encoding("UTF-16BE").send(@method).should_not.end_with?( + "b".force_encoding("UTF-16BE")) + end end diff --git a/spec/ruby/shared/string/start_with.rb b/spec/ruby/shared/string/start_with.rb index d8d6e13f6ae67a..6932a017b6d621 100644 --- a/spec/ruby/shared/string/start_with.rb +++ b/spec/ruby/shared/string/start_with.rb @@ -69,4 +69,8 @@ Regexp.last_match.should be_nil $1.should be_nil end + + it "does not check that we are not matching part of a character" do + "\xC3\xA9".send(@method).should.start_with?("\xC3") + end end From 708d06f301df9a703fbee6bd1ae369c5e11de7ad Mon Sep 17 00:00:00 2001 From: git Date: Thu, 28 Jul 2022 00:24:13 +0900 Subject: [PATCH 035/142] * 2022-07-28 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 40220b36cf5c31..94f98fc381619e 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 27 +#define RUBY_RELEASE_DAY 28 #include "ruby/version.h" #include "ruby/internal/abi.h" From 4ad69899b7db1e384665dec090d5cdc0c3b3c9b2 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 27 Jul 2022 15:29:00 -0700 Subject: [PATCH 036/142] Fix documentation for ARGF.inplace_mode{,=} The value affects the name of the backup file created, not the name of the file modified (as the file is modified in place). Fixes [Bug #18920] --- io.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/io.c b/io.c index de09a977989c0f..d90ff62660718e 100644 --- a/io.c +++ b/io.c @@ -14094,9 +14094,9 @@ argf_to_s(VALUE argf) * call-seq: * ARGF.inplace_mode -> String * - * Returns the file extension appended to the names of modified files under - * in-place edit mode. This value can be set using +ARGF.inplace_mode=+ or - * passing the +-i+ switch to the Ruby binary. + * Returns the file extension appended to the names of backup copies of + * modified files under in-place edit mode. This value can be set using + * +ARGF.inplace_mode=+ or passing the +-i+ switch to the Ruby binary. */ static VALUE argf_inplace_mode_get(VALUE argf) @@ -14117,8 +14117,8 @@ opt_i_get(ID id, VALUE *var) * ARGF.inplace_mode = ext -> ARGF * * Sets the filename extension for in-place editing mode to the given String. - * Each file being edited has this value appended to its filename. The - * modified file is saved under this new name. + * The backup copy of each file being edited has this value appended to its + * filename. * * For example: * @@ -14129,8 +14129,9 @@ opt_i_get(ID id, VALUE *var) * print line.sub("foo","bar") * end * - * Each line of _file.txt_ has the first occurrence of "foo" replaced with - * "bar", then the new line is written out to _file.txt.bak_. + * First, _file.txt.bak_ is created as a backup copy of _file.txt_. + * Then, each line of _file.txt_ has the first occurrence of "foo" replaced with + * "bar". */ static VALUE argf_inplace_mode_set(VALUE argf, VALUE val) From 431fdc9200ce28fcd10efb96fda869bb874fb2d0 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 09:02:23 +0900 Subject: [PATCH 037/142] [DOC] Cross references for `ARGF` --- io.c | 122 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/io.c b/io.c index d90ff62660718e..1fe927895779f1 100644 --- a/io.c +++ b/io.c @@ -9571,11 +9571,11 @@ argf_initialize_copy(VALUE argf, VALUE orig) * call-seq: * ARGF.lineno = integer -> integer * - * Sets the line number of +ARGF+ as a whole to the given +Integer+. + * Sets the line number of ARGF as a whole to the given Integer. * - * +ARGF+ sets the line number automatically as you read data, so normally + * ARGF sets the line number automatically as you read data, so normally * you will not need to set it explicitly. To access the current line number - * use +ARGF.lineno+. + * use ARGF.lineno. * * For example: * @@ -9598,7 +9598,7 @@ argf_set_lineno(VALUE argf, VALUE val) * ARGF.lineno -> integer * * Returns the current line number of ARGF as a whole. This value - * can be set manually with +ARGF.lineno=+. + * can be set manually with ARGF.lineno=. * * For example: * @@ -9923,10 +9923,10 @@ rb_f_gets(int argc, VALUE *argv, VALUE recv) * ARGF.gets(limit [, getline_args]) -> string or nil * ARGF.gets(sep, limit [, getline_args]) -> string or nil * - * Returns the next line from the current file in +ARGF+. + * Returns the next line from the current file in ARGF. * * By default lines are assumed to be separated by $/; - * to use a different character as a separator, supply it as a +String+ + * to use a different character as a separator, supply it as a String * for the _sep_ argument. * * The optional _limit_ argument specifies how many characters of each line @@ -10005,16 +10005,16 @@ rb_f_readline(int argc, VALUE *argv, VALUE recv) * ARGF.readline(limit) -> string * ARGF.readline(sep, limit) -> string * - * Returns the next line from the current file in +ARGF+. + * Returns the next line from the current file in ARGF. * * By default lines are assumed to be separated by $/; - * to use a different character as a separator, supply it as a +String+ + * to use a different character as a separator, supply it as a String * for the _sep_ argument. * * The optional _limit_ argument specifies how many characters of each line * to return. By default all characters are returned. * - * An +EOFError+ is raised at the end of the file. + * An EOFError is raised at the end of the file. */ static VALUE argf_readline(int argc, VALUE *argv, VALUE argf) @@ -10111,7 +10111,7 @@ rb_f_readlines(int argc, VALUE *argv, VALUE recv) * ARGF.to_a(limit) -> array * ARGF.to_a(sep, limit) -> array * - * Reads each file in +ARGF+ in its entirety, returning an +Array+ containing + * Reads each file in ARGF in its entirety, returning an Array containing * lines from the files. Lines are assumed to be separated by _sep_. * * lines = ARGF.readlines @@ -13126,12 +13126,12 @@ global_argf_p(VALUE arg) * call-seq: * ARGF.external_encoding -> encoding * - * Returns the external encoding for files read from +ARGF+ as an +Encoding+ + * Returns the external encoding for files read from ARGF as an Encoding * object. The external encoding is the encoding of the text as stored in a - * file. Contrast with +ARGF.internal_encoding+, which is the encoding used - * to represent this text within Ruby. + * file. Contrast with ARGF.internal_encoding, which is the encoding used to + * represent this text within Ruby. * - * To set the external encoding use +ARGF.set_encoding+. + * To set the external encoding use ARGF.set_encoding. * * For example: * @@ -13151,10 +13151,10 @@ argf_external_encoding(VALUE argf) * call-seq: * ARGF.internal_encoding -> encoding * - * Returns the internal encoding for strings read from +ARGF+ as an - * +Encoding+ object. + * Returns the internal encoding for strings read from ARGF as an + * Encoding object. * - * If +ARGF.set_encoding+ has been called with two encoding names, the second + * If ARGF.set_encoding has been called with two encoding names, the second * is returned. Otherwise, if +Encoding.default_external+ has been set, that * value is returned. Failing that, if a default external encoding was * specified on the command-line, that value is used. If the encoding is @@ -13190,7 +13190,7 @@ argf_internal_encoding(VALUE argf) * specifies the internal encoding. * * If the external encoding and the internal encoding are specified, the - * optional +Hash+ argument can be used to adjust the conversion process. The + * optional Hash argument can be used to adjust the conversion process. The * structure of this hash is explained in the String#encode documentation. * * For example: @@ -13219,7 +13219,7 @@ argf_set_encoding(int argc, VALUE *argv, VALUE argf) * ARGF.tell -> Integer * ARGF.pos -> Integer * - * Returns the current offset (in bytes) of the current file in +ARGF+. + * Returns the current offset (in bytes) of the current file in ARGF. * * ARGF.pos #=> 0 * ARGF.gets #=> "This is line one\n" @@ -13240,7 +13240,7 @@ argf_tell(VALUE argf) * call-seq: * ARGF.seek(amount, whence=IO::SEEK_SET) -> 0 * - * Seeks to offset _amount_ (an +Integer+) in the +ARGF+ stream according to + * Seeks to offset _amount_ (an Integer) in the ARGF stream according to * the value of _whence_. See IO#seek for further details. */ static VALUE @@ -13257,7 +13257,7 @@ argf_seek_m(int argc, VALUE *argv, VALUE argf) * call-seq: * ARGF.pos = position -> Integer * - * Seeks to the position given by _position_ (in bytes) in +ARGF+. + * Seeks to the position given by _position_ (in bytes) in ARGF. * * For example: * @@ -13279,7 +13279,7 @@ argf_set_pos(VALUE argf, VALUE offset) * ARGF.rewind -> 0 * * Positions the current file to the beginning of input, resetting - * +ARGF.lineno+ to zero. + * ARGF.lineno to zero. * * ARGF.readline #=> "This is line one\n" * ARGF.rewind #=> 0 @@ -13310,7 +13310,7 @@ argf_rewind(VALUE argf) * ARGF.to_i -> integer * * Returns an integer representing the numeric file descriptor for - * the current file. Raises an +ArgumentError+ if there isn't a current file. + * the current file. Raises an ArgumentError if there isn't a current file. * * ARGF.fileno #=> 3 */ @@ -13328,8 +13328,8 @@ argf_fileno(VALUE argf) * call-seq: * ARGF.to_io -> IO * - * Returns an +IO+ object representing the current file. This will be a - * +File+ object unless the current file is a stream such as STDIN. + * Returns an IO object representing the current file. This will be a + * File object unless the current file is a stream such as STDIN. * * For example: * @@ -13349,8 +13349,8 @@ argf_to_io(VALUE argf) * ARGF.eof? -> true or false * ARGF.eof -> true or false * - * Returns true if the current file in +ARGF+ is at end of file, i.e. it has - * no data to read. The stream must be opened for reading or an +IOError+ + * Returns true if the current file in ARGF is at end of file, i.e. it has + * no data to read. The stream must be opened for reading or an IOError * will be raised. * * $ echo "eof" | ruby argf.rb @@ -13585,10 +13585,10 @@ argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock) * call-seq: * ARGF.getc -> String or nil * - * Reads the next character from +ARGF+ and returns it as a +String+. Returns + * Reads the next character from ARGF and returns it as a String. Returns * +nil+ at the end of the stream. * - * +ARGF+ treats the files named on the command line as a single file created + * ARGF treats the files named on the command line as a single file created * by concatenating their contents. After returning the last character of the * first file, it returns the first character of the second file, and so on. * @@ -13630,7 +13630,7 @@ argf_getc(VALUE argf) * call-seq: * ARGF.getbyte -> Integer or nil * - * Gets the next 8-bit byte (0..255) from +ARGF+. Returns +nil+ if called at + * Gets the next 8-bit byte (0..255) from ARGF. Returns +nil+ if called at * the end of the stream. * * For example: @@ -13670,8 +13670,8 @@ argf_getbyte(VALUE argf) * call-seq: * ARGF.readchar -> String or nil * - * Reads the next character from +ARGF+ and returns it as a +String+. Raises - * an +EOFError+ after the last character of the last file has been read. + * Reads the next character from ARGF and returns it as a String. Raises + * an EOFError after the last character of the last file has been read. * * For example: * @@ -13710,8 +13710,8 @@ argf_readchar(VALUE argf) * call-seq: * ARGF.readbyte -> Integer * - * Reads the next 8-bit byte from ARGF and returns it as an +Integer+. Raises - * an +EOFError+ after the last byte of the last file has been read. + * Reads the next 8-bit byte from ARGF and returns it as an Integer. Raises + * an EOFError after the last byte of the last file has been read. * * For example: * @@ -13791,15 +13791,15 @@ argf_block_call_line(ID mid, int argc, VALUE *argv, VALUE argf) * which defaults to your platform's newline character) of each file in * +ARGV+. If a block is supplied, each line in turn will be yielded to the * block, otherwise an enumerator is returned. - * The optional _limit_ argument is an +Integer+ specifying the maximum + * The optional _limit_ argument is an Integer specifying the maximum * length of each line; longer lines will be split according to this limit. * * This method allows you to treat the files supplied on the command line as * a single file consisting of the concatenation of each named file. After * the last line of the first file has been returned, the first line of the - * second file is returned. The +ARGF.filename+ and +ARGF.lineno+ methods can - * be used to determine the filename of the current line and line number of - * the whole input, respectively. + * second file is returned. The ARGF.filename and ARGF.lineno methods can be + * used to determine the filename of the current line and line number of the + * whole input, respectively. * * For example, the following code prints out each line of each named file * prefixed with its line number, displaying the filename once per file: @@ -13833,12 +13833,12 @@ argf_each_line(int argc, VALUE *argv, VALUE argf) * ARGF.each_byte -> an_enumerator * * Iterates over each byte of each file in +ARGV+. - * A byte is returned as an +Integer+ in the range 0..255. + * A byte is returned as an Integer in the range 0..255. * * This method allows you to treat the files supplied on the command line as * a single file consisting of the concatenation of each named file. After * the last byte of the first file has been returned, the first byte of the - * second file is returned. The +ARGF.filename+ method can be used to + * second file is returned. The ARGF.filename method can be used to * determine the filename of the current byte. * * If no block is given, an enumerator is returned instead. @@ -13863,12 +13863,12 @@ argf_each_byte(VALUE argf) * ARGF.each_char {|char| block } -> ARGF * ARGF.each_char -> an_enumerator * - * Iterates over each character of each file in +ARGF+. + * Iterates over each character of each file in ARGF. * * This method allows you to treat the files supplied on the command line as * a single file consisting of the concatenation of each named file. After * the last character of the first file has been returned, the first - * character of the second file is returned. The +ARGF.filename+ method can + * character of the second file is returned. The ARGF.filename method can * be used to determine the name of the file in which the current character * appears. * @@ -13889,12 +13889,12 @@ argf_each_char(VALUE argf) * ARGF.each_codepoint {|codepoint| block } -> ARGF * ARGF.each_codepoint -> an_enumerator * - * Iterates over each codepoint of each file in +ARGF+. + * Iterates over each codepoint of each file in ARGF. * * This method allows you to treat the files supplied on the command line as * a single file consisting of the concatenation of each named file. After * the last codepoint of the first file has been returned, the first - * codepoint of the second file is returned. The +ARGF.filename+ method can + * codepoint of the second file is returned. The ARGF.filename method can * be used to determine the name of the file in which the current codepoint * appears. * @@ -13949,7 +13949,7 @@ argf_filename_getter(ID id, VALUE *var) * call-seq: * ARGF.file -> IO or File object * - * Returns the current file as an +IO+ or +File+ object. + * Returns the current file as an IO or File object. * $stdin is returned when the current file is STDIN. * * For example: @@ -13974,7 +13974,7 @@ argf_file(VALUE argf) * call-seq: * ARGF.binmode -> ARGF * - * Puts +ARGF+ into binary mode. Once a stream is in binary mode, it cannot + * Puts ARGF into binary mode. Once a stream is in binary mode, it cannot * be reset to non-binary mode. This option has the following effects: * * * Newline conversion is disabled. @@ -13995,8 +13995,8 @@ argf_binmode_m(VALUE argf) * call-seq: * ARGF.binmode? -> true or false * - * Returns true if +ARGF+ is being read in binary mode; false otherwise. - * To enable binary mode use +ARGF.binmode+. + * Returns true if ARGF is being read in binary mode; false otherwise. + * To enable binary mode use ARGF.binmode. * * For example: * @@ -14039,7 +14039,7 @@ argf_skip(VALUE argf) * ARGF.close -> ARGF * * Closes the current file and skips to the next file in ARGV. If there are - * no more files to open, just closes the current file. +STDIN+ will not be + * no more files to open, just closes the current file. STDIN will not be * closed. * * For example: @@ -14068,7 +14068,7 @@ argf_close_m(VALUE argf) * ARGF.closed? -> true or false * * Returns _true_ if the current file has been closed; _false_ otherwise. Use - * +ARGF.close+ to actually close the current file. + * ARGF.close to actually close the current file. */ static VALUE argf_closed(VALUE argf) @@ -14096,7 +14096,7 @@ argf_to_s(VALUE argf) * * Returns the file extension appended to the names of backup copies of * modified files under in-place edit mode. This value can be set using - * +ARGF.inplace_mode=+ or passing the +-i+ switch to the Ruby binary. + * ARGF.inplace_mode= or passing the +-i+ switch to the Ruby binary. */ static VALUE argf_inplace_mode_get(VALUE argf) @@ -14309,9 +14309,9 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y) * methods exist in two forms, * * one that returns +nil+ when the end of file is reached, the other - * raises +EOFError+. + * raises EOFError. * - * +EOFError+ is a subclass of +IOError+. + * EOFError is a subclass of IOError. * * file = File.open("/etc/hosts") * file.read @@ -14323,11 +14323,11 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y) /* * Document-class: ARGF * - * +ARGF+ is a stream designed for use in scripts that process files given as + * ARGF is a stream designed for use in scripts that process files given as * command-line arguments or passed in via STDIN. * * The arguments passed to your script are stored in the +ARGV+ Array, one - * argument per element. +ARGF+ assumes that any arguments that aren't + * argument per element. ARGF assumes that any arguments that aren't * filenames have been removed from +ARGV+. For example: * * $ ruby argf.rb --verbose file1 file2 @@ -14336,15 +14336,15 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y) * option = ARGV.shift #=> "--verbose" * ARGV #=> ["file1", "file2"] * - * You can now use +ARGF+ to work with a concatenation of each of these named - * files. For instance, +ARGF.read+ will return the contents of _file1_ + * You can now use ARGF to work with a concatenation of each of these named + * files. For instance, ARGF.read will return the contents of _file1_ * followed by the contents of _file2_. * - * After a file in +ARGV+ has been read +ARGF+ removes it from the Array. + * After a file in +ARGV+ has been read ARGF removes it from the Array. * Thus, after all files have been read +ARGV+ will be empty. * - * You can manipulate +ARGV+ yourself to control what +ARGF+ operates on. If - * you remove a file from +ARGV+, it is ignored by +ARGF+; if you add files to + * You can manipulate +ARGV+ yourself to control what ARGF operates on. If + * you remove a file from +ARGV+, it is ignored by ARGF; if you add files to * +ARGV+, they are treated as if they were named on the command line. For * example: * @@ -14354,7 +14354,7 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y) * ARGV.replace ["file2", "file3"] * ARGF.read # Returns the contents of file2 and file3 * - * If +ARGV+ is empty, +ARGF+ acts as if it contained STDIN, i.e. the data + * If +ARGV+ is empty, ARGF acts as if it contained STDIN, i.e. the data * piped to your script. For example: * * $ echo "glark" | ruby -e 'p ARGF.read' From 5d5c1d0fbdf18b1fc4d5b74499ddba532adb6bc6 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 01:42:21 +0900 Subject: [PATCH 038/142] Suppress use-after-free warning by gcc-12 --- gc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gc.c b/gc.c index 7dd9cdb3c70ae4..75f06588299302 100644 --- a/gc.c +++ b/gc.c @@ -12368,6 +12368,7 @@ objspace_xfree(rb_objspace_t *objspace, void *ptr, size_t old_size) objspace_malloc_increase(objspace, ptr, 0, old_size, MEMOP_TYPE_FREE) { free(ptr); + ptr = NULL; RB_DEBUG_COUNTER_INC(heap_xfree); } } From bee5089d6789401f265f87b2f23f1bd7ec63cec8 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 27 Jul 2022 21:29:14 -0700 Subject: [PATCH 039/142] Try reproducing the MinGW hang on time command (#6168) to see if it really exits correctly. GitHub Support asked me to confirm the command is exiting correctly. --- .github/workflows/mingw.yml | 2 +- test/rinda/test_rinda.rb | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 80b7a92f15223c..2842a19f4885c0 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -135,7 +135,7 @@ jobs: run: | # Actions uses UTF8, causes test failures, similar to normal OS setup chcp.com 437 - make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} + time make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} env: RUBY_TESTOPTS: >- -j${{env.TEST_JOBS}} --retry --job-status=normal --show-skip --timeout-scale=1.5 diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb index d8340e0fc48dff..d937cd0f45557f 100644 --- a/test/rinda/test_rinda.rb +++ b/test/rinda/test_rinda.rb @@ -496,10 +496,6 @@ class TupleSpaceProxyTest < Test::Unit::TestCase include TupleSpaceTestModule def setup - if RUBY_PLATFORM.match?(/mingw/) - @omitted = true - omit 'This test seems to randomly hang on GitHub Actions MinGW UCRT64' - end super ThreadGroup.new.add(Thread.current) @ts_base = Rinda::TupleSpace.new(1) @@ -507,9 +503,6 @@ def setup @server = DRb.start_service("druby://localhost:0") end def teardown - return if @omitted - @omitted = false - # implementation-dependent @ts_base.instance_eval{ if th = @keeper From 2b9374768f9f93129e5c4b7aaedfa785d041cbb1 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 09:17:59 +0900 Subject: [PATCH 040/142] `RUBY_DEBUG_LOG2` should filter against the given `file` --- vm_debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm_debug.h b/vm_debug.h index ead1c7c10a8b9d..59561056488001 100644 --- a/vm_debug.h +++ b/vm_debug.h @@ -100,7 +100,7 @@ bool ruby_debug_log_filter(const char *func_name, const char *file_name); } while (0) #define RUBY_DEBUG_LOG2(file, line, ...) do { \ - if (RUBY_DEBUG_LOG_ENABLED(RUBY_FUNCTION_NAME_STRING, __FILE__)) \ + if (RUBY_DEBUG_LOG_ENABLED(RUBY_FUNCTION_NAME_STRING, file)) \ ruby_debug_log(file, line, RUBY_FUNCTION_NAME_STRING, "" __VA_ARGS__); \ } while (0) From 98e01c991433a6785fac3d750114b5b3cb70710d Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 28 Jul 2022 19:10:24 +0900 Subject: [PATCH 041/142] Also skip the failing test similar with a343952d195a324dd4563318d8f88b167316ce5d --- bootstraptest/test_io.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb index c6c3772d3696b0..ff2649769656b4 100644 --- a/bootstraptest/test_io.rb +++ b/bootstraptest/test_io.rb @@ -1,3 +1,4 @@ +/freebsd/ =~ RUBY_PLATFORM or assert_finish 5, %q{ r, w = IO.pipe t1 = Thread.new { r.sysread(1) } From 202ce7de01e051fca01c683833e4294d79ef87bb Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 28 Jul 2022 19:14:01 +0900 Subject: [PATCH 042/142] test_io_console.rbL399 is also randomly failing same as bfc697f1e26f1406c45ec7309ca0d4c0b5ecedd6 --- test/io/console/test_io_console.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb index f6e46fe112bfd4..342f979ec36308 100644 --- a/test/io/console/test_io_console.rb +++ b/test/io/console/test_io_console.rb @@ -395,7 +395,7 @@ def test_intr assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) end - if cc = ctrl["lnext"] + if cc = ctrl["lnext"] && /freebsd/ !~ RUBY_PLATFORM assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) From d448ecc7b11274e2e5d924a42693788141fad753 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 28 Jul 2022 19:25:52 +0900 Subject: [PATCH 043/142] Fix the missing brackets --- test/io/console/test_io_console.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb index 342f979ec36308..b5382555f553e8 100644 --- a/test/io/console/test_io_console.rb +++ b/test/io/console/test_io_console.rb @@ -395,7 +395,7 @@ def test_intr assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) end - if cc = ctrl["lnext"] && /freebsd/ !~ RUBY_PLATFORM + if (cc = ctrl["lnext"]) && /freebsd/ !~ RUBY_PLATFORM assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) assert_ctrl("#{cc.ord}", cc, r, w) From 3eade599194dac960bc5b81c3f1bcff4a460b959 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 28 Jul 2022 19:45:15 +0900 Subject: [PATCH 044/142] Skip randomly failing tests with FreeBSD 12 --- test/ruby/test_io.rb | 6 ++++++ test/ruby/test_thread.rb | 2 ++ 2 files changed, 8 insertions(+) diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index b8530e74004f1c..6a3d7594cf04e9 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -3114,6 +3114,8 @@ def test_cross_thread_close_fd end def test_cross_thread_close_stdio + omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM + assert_separately([], <<-'end;') IO.pipe do |r,w| $stdin.reopen(r) @@ -3782,6 +3784,8 @@ def test_race_gets_and_close end def test_race_closed_stream + omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM + assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}") begin; bug13158 = '[ruby-core:79262] [Bug #13158]' @@ -3876,6 +3880,8 @@ def lim.to_int; raise "invalid limit"; end end def test_closed_stream_in_rescue + omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM + assert_separately([], "#{<<-"begin;"}\n#{<<~"end;"}") begin; 10.times do diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 881c4d102dc4cb..f6156a16fdb949 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -972,6 +972,8 @@ def test_backtrace end def test_thread_timer_and_interrupt + omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM + bug5757 = '[ruby-dev:44985]' pid = nil cmd = 'Signal.trap(:INT, "DEFAULT"); pipe=IO.pipe; Thread.start {Thread.pass until Thread.main.stop?; puts; STDOUT.flush}; pipe[0].read' From 2375afb8d6fd218cd9083749d87a7a59946d8938 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 27 Jul 2022 11:18:29 -0400 Subject: [PATCH 045/142] Refactor gc_ref_update_array --- gc.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/gc.c b/gc.c index 75f06588299302..84f9aa30f63ef1 100644 --- a/gc.c +++ b/gc.c @@ -9957,16 +9957,26 @@ gc_sort_heap_by_empty_slots(rb_objspace_t *objspace) static void gc_ref_update_array(rb_objspace_t * objspace, VALUE v) { - long i, len; + if (ARY_SHARED_P(v)) { + UPDATE_IF_MOVED(objspace, RARRAY(v)->as.heap.aux.shared_root); + } + else { + long len = RARRAY_LEN(v); - if (ARY_SHARED_P(v)) return; + if (len > 0) { + VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(v); + for (long i = 0; i < len; i++) { + UPDATE_IF_MOVED(objspace, ptr[i]); + } + } - len = RARRAY_LEN(v); - if (len > 0) { - VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(v); - for (i = 0; i < len; i++) { - UPDATE_IF_MOVED(objspace, ptr[i]); +#if USE_RVARGC + if ((size_t)GET_HEAP_PAGE(v)->slot_size >= rb_ary_size_as_embedded(v)) { + if (rb_ary_embeddable_p(v)) { + rb_ary_make_embedded(v); + } } +#endif } } @@ -10466,19 +10476,7 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj) return; case T_ARRAY: - if (ARY_SHARED_P(obj)) { - UPDATE_IF_MOVED(objspace, any->as.array.as.heap.aux.shared_root); - } - else { - gc_ref_update_array(objspace, obj); - } -#if USE_RVARGC - if ((size_t)GET_HEAP_PAGE(obj)->slot_size >= rb_ary_size_as_embedded(obj)) { - if (rb_ary_embeddable_p(obj)) { - rb_ary_make_embedded(obj); - } - } -#endif + gc_ref_update_array(objspace, obj); break; case T_HASH: From 1c16645216b6db04ccb1144e6f7e085e1e0a6132 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 27 Jul 2022 11:26:31 -0400 Subject: [PATCH 046/142] Make array slices views rather than copies Before this commit, if the slice fits in VWA, it would make a copy rather than a view. This is slower as it requires a memcpy of the contents. --- array.c | 39 +++++++++++++++++++++++++++++---------- gc.c | 14 ++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/array.c b/array.c index 8c7fa583e958b6..b2ebf3c0e9ebee 100644 --- a/array.c +++ b/array.c @@ -1027,7 +1027,7 @@ rb_ary_memsize(VALUE ary) static VALUE ary_make_shared(VALUE ary) { - assert(!ARY_EMBED_P(ary)); + assert(USE_RVARGC || !ARY_EMBED_P(ary)); ary_verify(ary); if (ARY_SHARED_P(ary)) { @@ -1037,21 +1037,38 @@ ary_make_shared(VALUE ary) return ary; } else if (OBJ_FROZEN(ary)) { - rb_ary_transient_heap_evacuate(ary, TRUE); - ary_shrink_capa(ary); + if (!ARY_EMBED_P(ary)) { + rb_ary_transient_heap_evacuate(ary, TRUE); + ary_shrink_capa(ary); + } return ary; } else { - long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary); - const VALUE *ptr; + rb_ary_transient_heap_evacuate(ary, TRUE); + + long capa = ARY_CAPA(ary); + long len = RARRAY_LEN(ary); + + /* Shared roots cannot be embedded because the reference count + * (refcnt) is stored in as.heap.aux.capa. */ VALUE shared = ary_alloc_heap(0); - rb_ary_transient_heap_evacuate(ary, TRUE); - ptr = ARY_HEAP_PTR(ary); + if (ARY_EMBED_P(ary)) { + /* Cannot use ary_heap_alloc because we don't want to allocate + * on the transient heap. */ + VALUE *ptr = ALLOC_N(VALUE, capa); + ARY_SET_PTR(shared, ptr); + ary_memcpy(shared, 0, len, RARRAY_PTR(ary)); + + FL_UNSET_EMBED(ary); + ARY_SET_HEAP_LEN(ary, len); + ARY_SET_PTR(ary, ptr); + } + else { + ARY_SET_PTR(shared, RARRAY_PTR(ary)); + } - FL_UNSET_EMBED(shared); ARY_SET_LEN(shared, capa); - ARY_SET_PTR(shared, ptr); ary_mem_clear(shared, len, capa - len); FL_SET_SHARED_ROOT(shared); ARY_SET_SHARED_ROOT_REFCNT(shared, 1); @@ -1318,7 +1335,9 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len) assert(len >= 0); assert(offset+len <= RARRAY_LEN(ary)); - if (ary_embeddable_p(len)) { + const size_t rarray_embed_capa_max = (sizeof(struct RArray) - offsetof(struct RArray, as.ary)) / sizeof(VALUE); + + if ((size_t)len <= rarray_embed_capa_max && ary_embeddable_p(len)) { VALUE result = ary_alloc_embed(klass, len); ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset); ARY_SET_EMBED_LEN(result, len); diff --git a/gc.c b/gc.c index 84f9aa30f63ef1..cd48c47a941389 100644 --- a/gc.c +++ b/gc.c @@ -9958,7 +9958,21 @@ static void gc_ref_update_array(rb_objspace_t * objspace, VALUE v) { if (ARY_SHARED_P(v)) { +#if USE_RVARGC + VALUE old_root = RARRAY(v)->as.heap.aux.shared_root; +#endif + UPDATE_IF_MOVED(objspace, RARRAY(v)->as.heap.aux.shared_root); + +#if USE_RVARGC + VALUE new_root = RARRAY(v)->as.heap.aux.shared_root; + // If the root is embedded and its location has changed + if (ARY_EMBED_P(new_root) && new_root != old_root) { + size_t offset = (size_t)(RARRAY(v)->as.heap.ptr - RARRAY(old_root)->as.ary); + GC_ASSERT(RARRAY(v)->as.heap.ptr >= RARRAY(old_root)->as.ary); + RARRAY(v)->as.heap.ptr = RARRAY(new_root)->as.ary + offset; + } +#endif } else { long len = RARRAY_LEN(v); From 229cf263df8ae5020b959724b26ac7ecc5e7e122 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 27 Jul 2022 14:05:31 -0400 Subject: [PATCH 047/142] Lock the VM for rb_gc_writebarrier_unprotect When using Ractors, rb_gc_writebarrier_unprotect requries a VM lock since it modifies the bitmaps. --- gc.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/gc.c b/gc.c index cd48c47a941389..df4c99b15b2cce 100644 --- a/gc.c +++ b/gc.c @@ -8964,25 +8964,29 @@ rb_gc_writebarrier_unprotect(VALUE obj) gc_report(2, objspace, "rb_gc_writebarrier_unprotect: %s %s\n", obj_info(obj), rgengc_remembered(objspace, obj) ? " (already remembered)" : ""); - if (RVALUE_OLD_P(obj)) { - gc_report(1, objspace, "rb_gc_writebarrier_unprotect: %s\n", obj_info(obj)); - RVALUE_DEMOTE(objspace, obj); - gc_mark_set(objspace, obj); - gc_remember_unprotected(objspace, obj); + RB_VM_LOCK_ENTER_NO_BARRIER(); + { + if (RVALUE_OLD_P(obj)) { + gc_report(1, objspace, "rb_gc_writebarrier_unprotect: %s\n", obj_info(obj)); + RVALUE_DEMOTE(objspace, obj); + gc_mark_set(objspace, obj); + gc_remember_unprotected(objspace, obj); #if RGENGC_PROFILE - objspace->profile.total_shade_operation_count++; + objspace->profile.total_shade_operation_count++; #if RGENGC_PROFILE >= 2 - objspace->profile.shade_operation_count_types[BUILTIN_TYPE(obj)]++; + objspace->profile.shade_operation_count_types[BUILTIN_TYPE(obj)]++; #endif /* RGENGC_PROFILE >= 2 */ #endif /* RGENGC_PROFILE */ - } - else { - RVALUE_AGE_RESET(obj); - } + } + else { + RVALUE_AGE_RESET(obj); + } - RB_DEBUG_COUNTER_INC(obj_wb_unprotect); - MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj); + RB_DEBUG_COUNTER_INC(obj_wb_unprotect); + MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj); + } + RB_VM_LOCK_LEAVE_NO_BARRIER(); } } From c38ad2aeb55aadd4a697f9541efac1fe30fd6891 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 00:25:34 +0900 Subject: [PATCH 048/142] Fix format specifier for `rb_ractor_id()` --- vm_sync.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vm_sync.c b/vm_sync.c index 610bdb7b10d585..b0634955e63103 100644 --- a/vm_sync.c +++ b/vm_sync.c @@ -106,13 +106,15 @@ vm_lock_enter(rb_ractor_t *cr, rb_vm_t *vm, bool locked, bool no_barrier, unsign vm->ractor.sync.lock_rec++; *lev = vm->ractor.sync.lock_rec; - RUBY_DEBUG_LOG2(file, line, "rec:%u owner:%d", vm->ractor.sync.lock_rec, rb_ractor_id(vm->ractor.sync.lock_owner)); + RUBY_DEBUG_LOG2(file, line, "rec:%u owner:%u", vm->ractor.sync.lock_rec, + (unsigned int)rb_ractor_id(vm->ractor.sync.lock_owner)); } static void vm_lock_leave(rb_vm_t *vm, unsigned int *lev APPEND_LOCATION_ARGS) { - RUBY_DEBUG_LOG2(file, line, "rec:%u owner:%d", vm->ractor.sync.lock_rec, rb_ractor_id(vm->ractor.sync.lock_owner)); + RUBY_DEBUG_LOG2(file, line, "rec:%u owner:%u", vm->ractor.sync.lock_rec, + (unsigned int)rb_ractor_id(vm->ractor.sync.lock_owner)); ASSERT_vm_locking(); VM_ASSERT(vm->ractor.sync.lock_rec > 0); From 94c3d528e7d1dc86ecafc6b992f16d062a17f015 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 00:31:47 +0900 Subject: [PATCH 049/142] Fix conversion of `rb_ractor_id()` --- ractor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ractor.rb b/ractor.rb index ef36b2937f6fc2..953d3ceddc197f 100644 --- a/ractor.rb +++ b/ractor.rb @@ -699,7 +699,7 @@ def take def inspect loc = __builtin_cexpr! %q{ RACTOR_PTR(self)->loc } name = __builtin_cexpr! %q{ RACTOR_PTR(self)->name } - id = __builtin_cexpr! %q{ INT2FIX(rb_ractor_id(RACTOR_PTR(self))) } + id = __builtin_cexpr! %q{ UINT2NUM(rb_ractor_id(RACTOR_PTR(self))) } status = __builtin_cexpr! %q{ rb_str_new2(ractor_status_str(RACTOR_PTR(self)->status_)) } From 90cf767d158db06312a82c468a2bbf37f63bcb7a Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 28 Jul 2022 09:10:16 +0900 Subject: [PATCH 050/142] Fix format-pedantic warnings --- ractor_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ractor_core.h b/ractor_core.h index 32ae9ab0138191..412971decfc418 100644 --- a/ractor_core.h +++ b/ractor_core.h @@ -273,7 +273,7 @@ rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const cha #else native_tls_set(ruby_current_ec_key, ec); #endif - RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", cr->threads.running_ec, ec); + RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec); VM_ASSERT(cr->threads.running_ec != ec); cr->threads.running_ec = ec; } From 18b1e5e6dbef9bb0c265e57e1267840d7c13cd88 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 28 Jul 2022 09:50:37 -0500 Subject: [PATCH 051/142] [ruby/rdoc] [DOC] Add some links in intro; delimit rendered HTML output. (https://github.com/ruby/rdoc/pull/904) https://github.com/ruby/rdoc/commit/c02645364f --- doc/rdoc/markup_reference.rb | 133 +++++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 54 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index cc10b04871a622..cc682f987edfc0 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -9,16 +9,28 @@ # # = \RDoc Markup Reference # -# [Note] +# Notes: # -# Examples in this reference are Ruby code and comments. -# Certain differences among the sources are noted. +# - Examples in this reference are Ruby code and comments; +# certain differences from other sources +# (such as C code and comments) are noted. +# - An example that shows rendered HTML output +# displays that output in a blockquote: +# +# Rendered HTML: +# >>> +# Some stuff # # \RDoc-generated documentation is derived from and controlled by: # -# - Single-line or multi-line comments that precede certain definitions. -# - \RDoc directives in trailing comments (on the same line as code). -# - The Ruby code itself. +# - Single-line or multi-line comments that precede certain definitions; +# see {Markup in Comments}[rdoc-ref:RDoc::MarkupReference@Markup+in+Comments]. +# - \RDoc directives in trailing comments (on the same line as code); +# see :nodoc:, :doc:, and :notnew. +# - \RDoc directives in single-line comments; +# see other {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. +# - The Ruby code itself; +# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code] # # == Markup in Comments # @@ -76,12 +88,12 @@ # # You'll love it. # # Rendered HTML: +# >>> +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. # -# \RDoc produces HTML and command-line documentation for Ruby projects. -# \RDoc includes the rdoc and ri tools for generating and displaying -# documentation from the command-line. -# -# You'll love it. +# You'll love it. # # A paragraph may contain nested blocks, including: # @@ -113,16 +125,17 @@ # # This is not verbatim text. # # Rendered HTML: +# >>> +# This is not verbatim text. # -# This is not verbatim text. -# -# This is verbatim text. -# Whitespace is honored. # See? +# This is verbatim text. # Whitespace is honored. # See? +# Whitespace is honored. # See? # -# This is still the same verbatim text block. +# This is still the same verbatim text block. +# +# This is not verbatim text. # -# This is not verbatim text. # ==== Code Blocks # # A special case of verbatim text is the code block, @@ -134,12 +147,24 @@ # - Has a contrasting background color. # - Has syntax highlighting. # -# Example: +# Example input: # -# def foo(name = '', value = 0) -# @name = name # Whitespace is still honored. -# @value = value -# end +# Consider this method: +# +# def foo(name = '', value = 0) +# @name = name # Whitespace is still honored. +# @value = value +# end +# +# +# Rendered HTML: +# >>> +# Consider this method: +# +# def foo(name = '', value = 0) +# @name = name # Whitespace is still honored. +# @value = value +# end # # Pro tip: If your indented Ruby code does not get highlighted, # it may contain a syntax error. @@ -180,14 +205,14 @@ # # - Last one. # # Rendered HTML: +# >>> +# - An item. +# - Another. +# - An item spanning +# multiple lines. # -# - An item. -# - Another. -# - An item spanning -# multiple lines. -# -# * Yet another. -# - Last one. +# * Yet another. +# - Last one. # # ===== Numbered Lists # @@ -206,14 +231,14 @@ # # 1000. Last one. # # Rendered HTML: +# >>> +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. # -# 100. An item. -# 10. Another. -# 1. An item spanning -# multiple lines. -# -# 1. Yet another. -# 1000. Last one. +# 1. Yet another. +# 1000. Last one. # # ===== Lettered Lists # @@ -232,12 +257,12 @@ # # a. Last one. # # Rendered HTML: +# >>> +# z. An item. +# y. Another. # -# z. An item. -# y. Another. -# -# x. Yet another. -# a. Last one. +# x. Yet another. +# a. Last one. # # ===== Labeled Lists # @@ -257,14 +282,14 @@ # # bam:: Last one. # # Rendered HTML: +# >>> +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. # -# [foo] An item. -# bat:: Another. -# [bag] An item spanning -# multiple lines. -# -# [bar baz] Yet another. -# bam:: Last one. +# [bar baz] Yet another. +# bam:: Last one. # # ===== Blocks Nested in Lists # @@ -313,15 +338,15 @@ # # --- # # Rendered HTML: +# >>> +# ------ +# Stuff between. # -# ------ -# Stuff between. -# -# \--- Not a horizontal rule. +# \--- Not a horizontal rule. # -# -- Also not a horizontal rule. +# -- Also not a horizontal rule. # -# --- +# --- # # ==== Directives # From ab08a43ec5ab7a8d82c980dc1eefc9e5d71e926d Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Fri, 29 Jul 2022 01:08:07 +0930 Subject: [PATCH 052/142] YJIT: Teach getblockparamproxy to handle the no-block case without exiting (#6191) Teach getblockparamproxy to handle the no-block case without exiting Co-authored-by: John Hawthorn Co-authored-by: John Hawthorn --- bootstraptest/test_yjit.rb | 13 ++++++ test/ruby/test_yjit.rb | 16 +++++++ yjit.c | 11 +++++ yjit/src/codegen.rs | 88 ++++++++++++++++++++++++++++++-------- yjit/src/cruby.rs | 3 ++ 5 files changed, 113 insertions(+), 18 deletions(-) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 7158486d5048ff..966a5f30021499 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1224,6 +1224,19 @@ def foo(&block) [foo {1}, foo {2}, foo {42}] } +# test calling without block param +assert_equal '[1, false, 2, false]', %q{ + def bar + block_given? && yield + end + + def foo(&block) + bar(&block) + end + + [foo { 1 }, foo, foo { 2 }, foo] +} + # test calling block param failing assert_equal '42', %q{ def foo(&block) diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index f8fc4f21eff2c7..37e72dcafac3b5 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -513,6 +513,22 @@ def foo &blk RUBY end + def test_getblockparamproxy_with_no_block + # Currently side exits on the send + assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: { send: 2 }) + def bar + end + + def foo &blk + bar(&blk) + bar(&blk) + end + + foo + foo + RUBY + end + def test_send_splat assert_compiles(<<~'RUBY', result: "3#1,2,3/P", exits: {}) def internal_method(*args) diff --git a/yjit.c b/yjit.c index edf5a139cc8a49..1a2f71a9599f32 100644 --- a/yjit.c +++ b/yjit.c @@ -699,6 +699,17 @@ rb_get_cfp_ep(struct rb_control_frame_struct *cfp) return (VALUE*)cfp->ep; } +const VALUE * +rb_get_cfp_ep_level(struct rb_control_frame_struct *cfp, uint32_t lv) +{ + uint32_t i; + const VALUE *ep = (VALUE*)cfp->ep; + for (i = 0; i < lv; i++) { + ep = VM_ENV_PREV_EP(ep); + } + return ep; +} + VALUE rb_yarv_class_of(VALUE obj) { diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index af501158ff33b2..0acd1972c39df1 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -214,6 +214,15 @@ fn jit_peek_at_local(jit: &JITState, n: i32) -> VALUE { } } +fn jit_peek_at_block_handler(jit: &JITState, level: u32) -> VALUE { + assert!(jit_at_current_insn(jit)); + + unsafe { + let ep = get_cfp_ep_level(get_ec_cfp(jit.ec.unwrap()), level); + *ep.offset(VM_ENV_DATA_INDEX_SPECVAL as isize) + } +} + // Add a comment at the current position in the code block fn add_comment(cb: &mut CodeBlock, comment_str: &str) { if cfg!(feature = "asm_comments") { @@ -5634,6 +5643,13 @@ fn gen_getblockparamproxy( cb: &mut CodeBlock, ocb: &mut OutlinedCb, ) -> CodegenStatus { + if !jit_at_current_insn(jit) { + defer_compilation(jit, ctx, cb, ocb); + return EndBlock; + } + + let starting_context = *ctx; // make a copy for use with jit_chain_guard + // A mirror of the interpreter code. Checking for the case // where it's pushing rb_block_param_proxy. let side_exit = get_side_exit(jit, ocb, ctx); @@ -5641,6 +5657,15 @@ fn gen_getblockparamproxy( // EP level let level = jit_get_arg(jit, 1).as_u32(); + // Peek at the block handler so we can check whether it's nil + let comptime_handler = jit_peek_at_block_handler(jit, level); + + // When a block handler is present, it should always be a GC-guarded + // pointer (VM_BH_ISEQ_BLOCK_P) + if comptime_handler.as_u64() != 0 && comptime_handler.as_u64() & 0x3 != 0x1 { + return CantCompile; + } + // Load environment pointer EP from CFP gen_get_ep(cb, REG0, level); @@ -5669,27 +5694,54 @@ fn gen_getblockparamproxy( ), ); - // Block handler is a tagged pointer. Look at the tag. 0x03 is from VM_BH_ISEQ_BLOCK_P(). - and(cb, REG0_8, imm_opnd(0x3)); + // Specialize compilation for the case where no block handler is present + if comptime_handler.as_u64() == 0 { + // Bail if there is a block handler + cmp(cb, REG0, uimm_opnd(0)); - // Bail unless VM_BH_ISEQ_BLOCK_P(bh). This also checks for null. - cmp(cb, REG0_8, imm_opnd(0x1)); - jnz_ptr( - cb, - counted_exit!(ocb, side_exit, gbpp_block_handler_not_iseq), - ); + jit_chain_guard( + JCC_JNZ, + jit, + &starting_context, + cb, + ocb, + SEND_MAX_DEPTH, + side_exit, + ); - // Push rb_block_param_proxy. It's a root, so no need to use jit_mov_gc_ptr. - mov( - cb, - REG0, - const_ptr_opnd(unsafe { rb_block_param_proxy }.as_ptr()), - ); - assert!(!unsafe { rb_block_param_proxy }.special_const_p()); - let top = ctx.stack_push(Type::UnknownHeap); - mov(cb, top, REG0); + jit_putobject(jit, ctx, cb, Qnil); + } else { + // Block handler is a tagged pointer. Look at the tag. 0x03 is from VM_BH_ISEQ_BLOCK_P(). + and(cb, REG0_8, imm_opnd(0x3)); - KeepCompiling + // Bail unless VM_BH_ISEQ_BLOCK_P(bh). This also checks for null. + cmp(cb, REG0_8, imm_opnd(0x1)); + + jit_chain_guard( + JCC_JNZ, + jit, + &starting_context, + cb, + ocb, + SEND_MAX_DEPTH, + side_exit, + ); + + // Push rb_block_param_proxy. It's a root, so no need to use jit_mov_gc_ptr. + mov( + cb, + REG0, + const_ptr_opnd(unsafe { rb_block_param_proxy }.as_ptr()), + ); + assert!(!unsafe { rb_block_param_proxy }.special_const_p()); + + let top = ctx.stack_push(Type::Unknown); + mov(cb, top, REG0); + } + + jump_to_next_insn(jit, ctx, cb, ocb); + + EndBlock } fn gen_getblockparam( diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 7c21bd962b4621..919557817218a1 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -135,6 +135,9 @@ extern "C" { #[link_name = "rb_get_cfp_ep"] pub fn get_cfp_ep(cfp: CfpPtr) -> *mut VALUE; + #[link_name = "rb_get_cfp_ep_level"] + pub fn get_cfp_ep_level(cfp: CfpPtr, lv: u32) -> *const VALUE; + #[link_name = "rb_get_cme_def_type"] pub fn get_cme_def_type(cme: *const rb_callable_method_entry_t) -> rb_method_type_t; From 68655c62df3aee7e665452f84d91a6cfdcd77d02 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 29 Jul 2022 00:38:29 +0900 Subject: [PATCH 053/142] * 2022-07-29 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 94f98fc381619e..b079c749d0dd9a 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 28 +#define RUBY_RELEASE_DAY 29 #include "ruby/version.h" #include "ruby/internal/abi.h" From c56e957decab0dd1f6aa2f4daba5d3d082c7782b Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 28 Jul 2022 11:06:30 -0500 Subject: [PATCH 054/142] [ruby/rdoc] Link from RDoc::Markup to RDoc::MarkupReference (https://github.com/ruby/rdoc/pull/906) Recently new RDoc::MarkupReference replaces Markup Reference in RDoc::Markup (which was always the goal). https://github.com/ruby/rdoc/commit/825be7eaf4 --- lib/rdoc/markup.rb | 284 +-------------------------------------------- 1 file changed, 1 insertion(+), 283 deletions(-) diff --git a/lib/rdoc/markup.rb b/lib/rdoc/markup.rb index f7aa02fd9f7813..7fec1c686970cf 100644 --- a/lib/rdoc/markup.rb +++ b/lib/rdoc/markup.rb @@ -97,289 +97,7 @@ # # = \RDoc Markup Reference # -# == Block Markup -# -# === Paragraphs and Verbatim -# -# The markup engine looks for a document's natural left margin. This is -# used as the initial margin for the document. -# -# Consecutive lines starting at this margin are considered to be a -# paragraph. Empty lines separate paragraphs. -# -# Any line that starts to the right of the current margin is treated -# as verbatim text. This is useful for code listings: -# -# 3.times { puts "Ruby" } -# -# In verbatim text, two or more blank lines are collapsed into one, -# and trailing blank lines are removed: -# -# This is the first line -# -# -# This is the second non-blank line, -# after 2 blank lines in the source markup. -# -# -# There were two trailing blank lines right above this paragraph, that -# have been removed. In addition, the verbatim text has been shifted -# left, so the amount of indentation of verbatim text is unimportant. -# -# For HTML output RDoc makes a small effort to determine if a verbatim section -# contains Ruby source code. If so, the verbatim block will be marked up as -# HTML. Triggers include "def", "class", "module", "require", the "hash -# rocket"# (=>) or a block call with a parameter. -# -# === Headers -# -# A line starting with an equal sign (=) is treated as a -# heading. Level one headings have one equals sign, level two headings -# have two, and so on until level six, which is the maximum -# (seven hyphens or more result in a level six heading). -# -# For example, the above header was obtained with: -# -# === Headers -# -# In HTML output headers have an id matching their name. The above example's -# HTML is: -# -#

Headers

-# -# If a heading is inside a method body the id will be prefixed with the -# method's id. If the above header where in the documentation for a method -# such as: -# -# ## -# # This method does fun things -# # -# # = Example -# # -# # Example of fun things goes here ... -# -# def do_fun_things -# end -# -# The header's id would be: -# -#

Example

-# -# The label can be linked-to using SomeClass@Headers. See -# {Links}[rdoc-ref:RDoc::Markup@Links] for further details. -# -# === Rules -# -# A line starting with three or more hyphens (at the current indent) -# generates a horizontal rule. -# -# --- -# -# produces: -# -# --- -# -# === Simple Lists -# -# If a paragraph starts with a "*", "-", "." or ".", -# then it is taken to be the start of a list. The margin is increased to be -# the first non-space following the list start flag. Subsequent lines -# should be indented to this new margin until the list ends. For example: -# -# * this is a list with three paragraphs in -# the first item. This is the first paragraph. -# -# And this is the second paragraph. -# -# 1. This is an indented, numbered list. -# 2. This is the second item in that list -# -# This is the third conventional paragraph in the -# first list item. -# -# * This is the second item in the original list -# -# produces: -# -# * this is a list with three paragraphs in -# the first item. This is the first paragraph. -# -# And this is the second paragraph. -# -# 1. This is an indented, numbered list. -# 2. This is the second item in that list -# -# This is the third conventional paragraph in the -# first list item. -# -# * This is the second item in the original list -# -# === Labeled Lists -# -# You can also construct labeled lists, sometimes called description -# or definition lists. Do this by putting the label in square brackets -# and indenting the list body: -# -# [cat] a small furry mammal -# that seems to sleep a lot -# -# [ant] a little insect that is known -# to enjoy picnics -# -# produces: -# -# [cat] a small furry mammal -# that seems to sleep a lot -# -# [ant] a little insect that is known -# to enjoy picnics -# -# If you want the list bodies to line up to the left of the labels, -# use two colons: -# -# cat:: a small furry mammal -# that seems to sleep a lot -# -# ant:: a little insect that is known -# to enjoy picnics -# -# produces: -# -# cat:: a small furry mammal -# that seems to sleep a lot -# -# ant:: a little insect that is known -# to enjoy picnics -# -# Notice that blank lines right after the label are ignored in labeled lists: -# -# [one] -# -# definition 1 -# -# [two] -# -# definition 2 -# -# produces the same output as -# -# [one] definition 1 -# [two] definition 2 -# -# -# === Lists and Verbatim -# -# If you want to introduce a verbatim section right after a list, it has to be -# less indented than the list item bodies, but more indented than the list -# label, letter, digit or bullet. For instance: -# -# * point 1 -# -# * point 2, first paragraph -# -# point 2, second paragraph -# verbatim text inside point 2 -# point 2, third paragraph -# verbatim text outside of the list (the list is therefore closed) -# regular paragraph after the list -# -# produces: -# -# * point 1 -# -# * point 2, first paragraph -# -# point 2, second paragraph -# verbatim text inside point 2 -# point 2, third paragraph -# verbatim text outside of the list (the list is therefore closed) -# regular paragraph after the list -# -# == Text Markup -# -# === Bold, Italic, Typewriter Text -# -# You can use markup within text (except verbatim) to change the -# appearance of parts of that text. Out of the box, RDoc::Markup -# supports word-based and general markup. -# -# Word-based markup uses flag characters around individual words: -# -# \*_word_\*:: displays _word_ in a *bold* font -# \__word_\_:: displays _word_ in an _emphasized_ font -# \+_word_\+:: displays _word_ in a +code+ font -# -# General markup affects text between a start delimiter and an end -# delimiter. Not surprisingly, these delimiters look like HTML markup. -# -# \_text_:: displays _text_ in a *bold* font -# \_text_:: displays _text_ in an _emphasized_ font -# (alternate tag: \) -# \_text_\:: displays _text_ in a +code+ font -# (alternate tag: \) -# -# Unlike conventional Wiki markup, general markup can cross line -# boundaries. You can turn off the interpretation of markup by -# preceding the first character with a backslash (see Escaping -# Text Markup, below). -# -# === Links -# -# Links to starting with +http:+, +https:+, +mailto:+, +ftp:+ or +www.+ -# are recognized. An HTTP url that references an external image is converted -# into an inline image element. -# -# Classes and methods will be automatically linked to their definition. For -# example, RDoc::Markup will link to this documentation. By default -# methods will only be automatically linked if they contain an _ (all -# methods can be automatically linked through the --hyperlink-all -# command line option). -# -# Single-word methods can be linked by using the # character for -# instance methods or :: for class methods. For example, -# #convert links to #convert. A class or method may be combined like -# RDoc::Markup#convert. -# -# A heading inside the documentation can be linked by following the class -# or method by an @ then the heading name. -# RDoc::Markup@Links will link to this section like this: -# RDoc::Markup@Links. Spaces in headings with multiple words must be escaped -# with + like RDoc::Markup@Escaping+Text+Markup. -# Punctuation and other special characters must be escaped like CGI.escape. -# -# The @ can also be used to link to sections. If a section and a -# heading share the same name the section is preferred for the link. -# -# Links can also be of the form label[url], in which case +label+ is -# used in the displayed text, and +url+ is used as the target. If +label+ -# contains multiple words, put it in braces: {multi word label}[url]. -# The +url+ may be an +http:+-type link or a cross-reference to a class, -# module or method with a label. -# -# Links with the rdoc-image: scheme will create an image tag for -# HTML output. Only fully-qualified URLs are supported. -# -# Links with the rdoc-ref: scheme will link to the referenced class, -# module, method, file, etc. If the referenced item is does not exist -# no link will be generated and rdoc-ref: will be removed from the -# resulting text. -# -# Links starting with rdoc-label:label_name will link to the -# +label_name+. You can create a label for the current link (for -# bidirectional links) by supplying a name for the current link like -# rdoc-label:label-other:label-mine. -# -# Links starting with +link:+ refer to local files whose path is relative to -# the --op directory. Use rdoc-ref: instead of -# link: to link to files generated by RDoc as the link target may -# be different across RDoc generators. -# -# Example links: -# -# https://github.com/ruby/rdoc -# mailto:user@example.com -# {RDoc Documentation}[http://rdoc.rubyforge.org] -# {RDoc Markup}[rdoc-ref:RDoc::Markup] +# See RDoc::MarkupReference. # # === Escaping Text Markup # From c348f5a91c6c5b4a90082d1e64312b4fb0dc7abc Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 28 Jul 2022 16:36:54 -0500 Subject: [PATCH 055/142] [ruby/date] [DOC] Enhanced RDoc for <=> (https://github.com/ruby/date/pull/65) https://github.com/ruby/date/commit/0cdbaa92e9 --- ext/date/date_core.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index a1dc9387e04cfc..9214333eed4227 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -6708,19 +6708,43 @@ cmp_dd(VALUE self, VALUE other) /* * call-seq: - * d <=> other -> -1, 0, +1 or nil + * self <=> other -> -1, 0, 1 or nil * - * Compares the two dates and returns -1, zero, 1 or nil. The other - * should be a date object or a numeric value as an astronomical - * Julian day number. + * Compares +self+ and +other+, returning: * - * Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1 - * Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0 - * Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1 - * Date.new(2001,2,3) <=> Object.new #=> nil - * Date.new(2001,2,3) <=> Rational(4903887,2) #=> 0 + * - -1 if +other+ is larger. + * - 0 if the two are equal. + * - 1 if +other+ is smaller. + * - +nil+ if the two are incomparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => # + * prev_date = d.prev_day # => # + * next_date = d.next_day # => # + * d <=> next_date # => -1 + * d <=> d # => 0 + * d <=> prev_date # => 1 + * + * - A DateTime object: + * + * d <=> DateTime.new(2022, 7, 26) # => 1 + * d <=> DateTime.new(2022, 7, 27) # => 0 + * d <=> DateTime.new(2022, 7, 29) # => -1 + * + * - A numeric (compares self.ajd to +other+): + * + * d <=> 2459789 # => -1 + * d <=> 2459788 # => -1 + * d <=> 2459787 # => 1 + * d <=> d.ajd # => 0 + * + * - Any other object: + * + * d <=> Object.new # => nil * - * See also Comparable. */ static VALUE d_lite_cmp(VALUE self, VALUE other) From 0d68286be93b2c7e588e42849ead0526ff55126c Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 28 Jul 2022 16:12:46 -0700 Subject: [PATCH 056/142] Revert "Try reproducing the MinGW hang on time command (#6168)" This reverts commit bee5089d6789401f265f87b2f23f1bd7ec63cec8. Looking at https://github.com/ruby/ruby/runs/7564065637?check_suite_focus=true, we concluded that the ruby process for test-all is stuck before exit when this issue reproduces. However, because of our limited bandwidth to support MinGW, we're not investigating this, and therefore we need to keep skipping tests that hang on this environment. --- .github/workflows/mingw.yml | 2 +- test/rinda/test_rinda.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 2842a19f4885c0..80b7a92f15223c 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -135,7 +135,7 @@ jobs: run: | # Actions uses UTF8, causes test failures, similar to normal OS setup chcp.com 437 - time make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} + make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} env: RUBY_TESTOPTS: >- -j${{env.TEST_JOBS}} --retry --job-status=normal --show-skip --timeout-scale=1.5 diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb index d937cd0f45557f..d8340e0fc48dff 100644 --- a/test/rinda/test_rinda.rb +++ b/test/rinda/test_rinda.rb @@ -496,6 +496,10 @@ class TupleSpaceProxyTest < Test::Unit::TestCase include TupleSpaceTestModule def setup + if RUBY_PLATFORM.match?(/mingw/) + @omitted = true + omit 'This test seems to randomly hang on GitHub Actions MinGW UCRT64' + end super ThreadGroup.new.add(Thread.current) @ts_base = Rinda::TupleSpace.new(1) @@ -503,6 +507,9 @@ def setup @server = DRb.start_service("druby://localhost:0") end def teardown + return if @omitted + @omitted = false + # implementation-dependent @ts_base.instance_eval{ if th = @keeper From f29f1d22c3d62b72b8943eefb384cd7a52251ea1 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 29 Jul 2022 09:10:36 +0900 Subject: [PATCH 057/142] [ruby/rdoc] Fix formatting blockquote in verbatim Reported at https://github.com/ruby/rdoc/pull/907#discussion_r932505816 https://github.com/ruby/rdoc/commit/86384ac7f9 --- lib/rdoc/markup/parser.rb | 2 ++ test/rdoc/test_rdoc_markup_to_html.rb | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/rdoc/markup/parser.rb b/lib/rdoc/markup/parser.rb index 1b54a519d1292a..b0fcb61f50299b 100644 --- a/lib/rdoc/markup/parser.rb +++ b/lib/rdoc/markup/parser.rb @@ -287,6 +287,8 @@ def build_verbatim margin line << ' ' * indent when :BREAK, :TEXT then line << data + when :BLOCKQUOTE then + line << '>>>' else # *LIST_TOKENS list_marker = case type when :BULLET then data diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb index e5d7a35710678e..3cf42d7c5e8826 100644 --- a/test/rdoc/test_rdoc_markup_to_html.rb +++ b/test/rdoc/test_rdoc_markup_to_html.rb @@ -812,6 +812,17 @@ def test_list_verbatim_2 assert_equal expected, @m.convert(str, @to) end + def test_block_quote_in_verbatim + str = "BlockQuote\n >>>\n" + + expected = <<-EXPECTED +

BlockQuote

+
>>>
+ EXPECTED + + assert_equal expected, @m.convert(str, @to).gsub(/^\n/, "") + end + def test_parseable_eh valid_syntax = [ 'def x() end', From bfd09b1116bcc747bab922b23c7322e4ec66c2c2 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 29 Jul 2022 14:59:56 +0900 Subject: [PATCH 058/142] Merge rubygems master from https://github.com/rubygems/rubygems/commit/446cc57a7ccdf1924deb291be9571219e7ba8523 --- lib/bundler/cli.rb | 2 + lib/bundler/definition.rb | 31 ++++++++++-- lib/bundler/installer.rb | 9 +++- lib/bundler/man/bundle-config.1 | 7 +++ lib/bundler/man/bundle-config.1.ronn | 5 ++ lib/bundler/man/bundle-inject.1 | 5 +- lib/bundler/man/bundle-inject.1.ronn | 4 +- lib/bundler/man/bundle-install.1 | 4 ++ lib/bundler/man/bundle-install.1.ronn | 6 +++ lib/bundler/man/bundle.1 | 5 +- lib/bundler/man/bundle.1.ronn | 3 +- lib/bundler/ruby_version.rb | 10 ++-- lib/bundler/rubygems_ext.rb | 9 ++++ lib/bundler/settings.rb | 1 + lib/bundler/source/metadata.rb | 2 +- spec/bundler/bundler/ruby_version_spec.rb | 10 ++-- spec/bundler/commands/install_spec.rb | 52 +++++++++++++++++++-- spec/bundler/commands/lock_spec.rb | 4 +- spec/bundler/commands/update_spec.rb | 10 ++-- spec/bundler/install/gemfile/ruby_spec.rb | 14 +++--- spec/bundler/install/gems/resolving_spec.rb | 12 ++--- spec/bundler/install/gemspecs_spec.rb | 3 +- spec/bundler/lock/lockfile_spec.rb | 4 +- spec/bundler/other/platform_spec.rb | 16 +++---- spec/bundler/support/helpers.rb | 2 +- spec/bundler/support/platforms.rb | 2 +- 26 files changed, 174 insertions(+), 58 deletions(-) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index e1c284130be5d1..e9ef47f9ba7af1 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -218,6 +218,8 @@ def remove(*gems) "Specify the number of jobs to run in parallel" method_option "local", :type => :boolean, :banner => "Do not attempt to fetch gems remotely and use the gem cache instead" + method_option "prefer-local", :type => :boolean, :banner => + "Only attempt to fetch gems remotely if not present locally, even if newer versions are available remotely" method_option "no-cache", :type => :boolean, :banner => "Don't update the existing gem cache." method_option "redownload", :type => :boolean, :aliases => "--force", :banner => diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 4cb829470a7cb0..3e93b451710029 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -70,6 +70,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti @unlock = unlock @optional_groups = optional_groups @remote = false + @prefer_local = false @specs = nil @ruby_version = ruby_version @gemfiles = gemfiles @@ -170,6 +171,13 @@ def resolve_only_locally! resolve end + def resolve_prefering_local! + @prefer_local = true + @remote = true + sources.remote! + resolve + end + def resolve_with_cache! sources.cached! resolve @@ -528,6 +536,19 @@ def precompute_source_requirements_for_indirect_dependencies? @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source? end + def pin_locally_available_names(source_requirements) + source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements| + local_source = original_source.dup + local_source.local_only! + + new_source_requirements[name] = if local_source.specs.search(name).any? + local_source + else + original_source + end + end + end + def current_ruby_platform_locked? return false unless generic_local_platform == Gem::Platform::RUBY return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY) @@ -765,7 +786,7 @@ def converge_specs(specs) def metadata_dependencies @metadata_dependencies ||= [ - Dependency.new("Ruby\0", RubyVersion.system.gem_version), + Dependency.new("Ruby\0", Gem.ruby_version), Dependency.new("RubyGems\0", Gem::VERSION), ] end @@ -792,7 +813,9 @@ def source_requirements # specs will be available later when the resolver knows where to # look for that gemspec (or its dependencies) source_requirements = if precompute_source_requirements_for_indirect_dependencies? - { :default => sources.default_source }.merge(source_map.all_requirements) + all_requirements = source_map.all_requirements + all_requirements = pin_locally_available_names(all_requirements) if @prefer_local + { :default => sources.default_source }.merge(all_requirements) else { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements) end @@ -806,7 +829,9 @@ def source_requirements end def requested_groups - groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with] + values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with] + values &= Bundler.settings[:only] unless Bundler.settings[:only].empty? + values end def lockfiles_equal?(current, proposed, preserve_unknown_sections) diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index f195d3660042f6..b7b0e36dfd85fc 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -268,7 +268,14 @@ def resolve_if_needed(options) return false if @definition.nothing_changed? && !@definition.missing_specs? end - options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely! + if options["local"] + @definition.resolve_with_cache! + elsif options["prefer-local"] + @definition.resolve_prefering_local! + else + @definition.resolve_remotely! + end + true end diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 76b444d8c6e681..b5cee57f29a6ed 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -74,6 +74,10 @@ Creates a directory (defaults to \fB~/bin\fR) and place any executables from the In deployment mode, Bundler will \'roll\-out\' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\. . .TP +\fBonly\fR +A space\-separated list of groups to install only gems of the specified groups\. +. +.TP \fBpath\fR The location to install the specified gems to\. This defaults to Rubygems\' setting\. Bundler shares this location with Rubygems, \fBgem install \.\.\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \.\.\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\. . @@ -223,6 +227,9 @@ The following is a list of all configuration keys and their purpose\. You can le \fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\. . .IP "\(bu" 4 +\fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\. +. +.IP "\(bu" 4 \fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\. . .IP "\(bu" 4 diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 8a636641c0294f..e2af773141f3be 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -74,6 +74,9 @@ The options that can be configured are: `production` use. Please check carefully if you want to have this option enabled in `development` or `test` environments. +* `only`: + A space-separated list of groups to install only gems of the specified groups. + * `path`: The location to install the specified gems to. This defaults to Rubygems' setting. Bundler shares this location with Rubygems, `gem install ...` will @@ -218,6 +221,8 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). Whether `bundle package` should skip installing gems. * `no_prune` (`BUNDLE_NO_PRUNE`): Whether Bundler should leave outdated gems unpruned when caching. +* `only` (`BUNDLE_ONLY`): + A space-separated list of groups to install only gems of the specified groups. * `path` (`BUNDLE_PATH`): The location on disk where all gems in your bundle will be located regardless of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1 index 0f6627d9a3e5a8..53f2eaae0a59be 100644 --- a/lib/bundler/man/bundle-inject.1 +++ b/lib/bundler/man/bundle-inject.1 @@ -30,4 +30,7 @@ bundle inject \'rack\' \'> 0\' .IP "" 0 . .P -This will inject the \'rack\' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock +This will inject the \'rack\' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock\. +. +.P +The \fBbundle inject\fR command was deprecated in Bundler 2\.1 and will be removed in Bundler 3\.0\. diff --git a/lib/bundler/man/bundle-inject.1.ronn b/lib/bundler/man/bundle-inject.1.ronn index f45434189647e3..95704eddadd36c 100644 --- a/lib/bundler/man/bundle-inject.1.ronn +++ b/lib/bundler/man/bundle-inject.1.ronn @@ -19,4 +19,6 @@ Example: bundle inject 'rack' '> 0' This will inject the 'rack' gem with a version greater than 0 in your -[`Gemfile(5)`][Gemfile(5)] and Gemfile.lock +[`Gemfile(5)`][Gemfile(5)] and Gemfile.lock. + +The `bundle inject` command was deprecated in Bundler 2.1 and will be removed in Bundler 3.0. diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1 index c742efd142451c..8e94fe24372266 100644 --- a/lib/bundler/man/bundle-install.1 +++ b/lib/bundler/man/bundle-install.1 @@ -70,6 +70,10 @@ The maximum number of parallel download and install jobs\. The default is the nu Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\. . .TP +\fB\-\-prefer\-local\fR +Force using locally installed gems, or gems already present in Rubygems\' cache or in \fBvendor/cache\fR, when resolving, even if newer versions are available remotely\. Only attempt to connect to \fBrubygems\.org\fR for gems that are not present locally\. +. +.TP \fB\-\-no\-cache\fR Do not update the cache in \fBvendor/cache\fR with the newly bundled gems\. This does not remove any gems in the cache but keeps the newly bundled gems from being cached during the install\. . diff --git a/lib/bundler/man/bundle-install.1.ronn b/lib/bundler/man/bundle-install.1.ronn index bec05187f355df..47200ac2d565d1 100644 --- a/lib/bundler/man/bundle-install.1.ronn +++ b/lib/bundler/man/bundle-install.1.ronn @@ -109,6 +109,12 @@ automatically and that requires `bundler` to silently remember them. Since appropriate platform-specific gem exists on `rubygems.org` it will not be found. +* `--prefer-local`: + Force using locally installed gems, or gems already present in Rubygems' cache + or in `vendor/cache`, when resolving, even if newer versions are available + remotely. Only attempt to connect to `rubygems.org` for gems that are not + present locally. + * `--no-cache`: Do not update the cache in `vendor/cache` with the newly bundled gems. This does not remove any gems in the cache but keeps the newly bundled gems from diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1 index c80ef51992d7cd..efc4d7e93f7f60 100644 --- a/lib/bundler/man/bundle.1 +++ b/lib/bundler/man/bundle.1 @@ -81,7 +81,7 @@ Show the source location of a particular gem in the bundle Show all of the outdated gems in the current bundle . .TP -\fBbundle console(1)\fR +\fBbundle console(1)\fR (deprecated) Start an IRB session in the current bundle . .TP @@ -129,5 +129,8 @@ These commands are obsolete and should no longer be used: .IP "\(bu" 4 \fBbundle cache(1)\fR . +.IP "\(bu" 4 +\fBbundle inject(1)\fR +. .IP "" 0 diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn index 86d771f024c60f..52a00d43ee7052 100644 --- a/lib/bundler/man/bundle.1.ronn +++ b/lib/bundler/man/bundle.1.ronn @@ -67,7 +67,7 @@ We divide `bundle` subcommands into primary commands and utilities: * [`bundle outdated(1)`](bundle-outdated.1.html): Show all of the outdated gems in the current bundle -* `bundle console(1)`: +* `bundle console(1)` (deprecated): Start an IRB session in the current bundle * [`bundle open(1)`](bundle-open.1.html): @@ -108,3 +108,4 @@ and execute it, passing down any extra arguments to it. These commands are obsolete and should no longer be used: * `bundle cache(1)` +* `bundle inject(1)` diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb index 3f51cf4528a656..9161c6afde4ef6 100644 --- a/lib/bundler/ruby_version.rb +++ b/lib/bundler/ruby_version.rb @@ -32,12 +32,12 @@ def initialize(versions, patchlevel, engine, engine_version) @engine = engine && engine.to_s || "ruby" @engine_versions = (engine_version && Array(engine_version)) || @versions @engine_gem_version = Gem::Requirement.create(@engine_versions.first).requirements.first.last - @patchlevel = patchlevel + @patchlevel = patchlevel || (@gem_version.prerelease? ? "-1" : nil) end def to_s(versions = self.versions) output = String.new("ruby #{versions_string(versions)}") - output << "p#{patchlevel}" if patchlevel + output << "p#{patchlevel}" if patchlevel && patchlevel != "-1" output << " (#{engine} #{versions_string(engine_versions)})" unless engine == "ruby" output @@ -46,7 +46,7 @@ def to_s(versions = self.versions) # @private PATTERN = / ruby\s - ([\d.]+) # ruby version + (\d+\.\d+\.\d+(?:\.\S+)?) # ruby version (?:p(-?\d+))? # optional patchlevel (?:\s\((\S+)\s(.+)\))? # optional engine info /xo.freeze @@ -103,8 +103,8 @@ def versions_string(versions) def self.system ruby_engine = RUBY_ENGINE.dup - ruby_version = RUBY_VERSION.dup - ruby_engine_version = RUBY_ENGINE_VERSION.dup + ruby_version = Gem.ruby_version.to_s + ruby_engine_version = RUBY_ENGINE == "ruby" ? ruby_version : RUBY_ENGINE_VERSION.dup patchlevel = RUBY_PATCHLEVEL.to_s @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version) diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index a47692d1f25dfe..e8e03fcf8f49eb 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -17,6 +17,15 @@ require_relative "match_platform" +# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler +# versions and ignore patchlevels +# (https://github.com/rubygems/rubygems/pull/5472, +# https://github.com/rubygems/rubygems/pull/5486). May be removed once RubyGems +# 3.3.12 support is dropped. +unless Gem.ruby_version.to_s == RUBY_VERSION || RUBY_PATCHLEVEL == -1 + Gem.instance_variable_set(:@ruby_version, Gem::Version.new(RUBY_VERSION)) +end + module Gem class Specification include ::Bundler::MatchPlatform diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 398c66055ac179..cf5675274e6087 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -57,6 +57,7 @@ class Settings ].freeze ARRAY_KEYS = %w[ + only with without ].freeze diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb index 185fe7082474a8..23531b8bd4bf0e 100644 --- a/lib/bundler/source/metadata.rb +++ b/lib/bundler/source/metadata.rb @@ -5,7 +5,7 @@ class Source class Metadata < Source def specs @specs ||= Index.build do |idx| - idx << Gem::Specification.new("Ruby\0", RubyVersion.system.gem_version) + idx << Gem::Specification.new("Ruby\0", Gem.ruby_version) idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s| s.required_rubygems_version = Gem::Requirement.default end diff --git a/spec/bundler/bundler/ruby_version_spec.rb b/spec/bundler/bundler/ruby_version_spec.rb index 3e3850031c2463..f1df12294dbb79 100644 --- a/spec/bundler/bundler/ruby_version_spec.rb +++ b/spec/bundler/bundler/ruby_version_spec.rb @@ -427,9 +427,8 @@ end describe "#version" do - it "should return a copy of the value of RUBY_VERSION" do - expect(subject.versions).to eq([RUBY_VERSION]) - expect(subject.versions.first).to_not be(RUBY_VERSION) + it "should return the value of Gem.ruby_version as a string" do + expect(subject.versions).to eq([Gem.ruby_version.to_s]) end end @@ -446,13 +445,12 @@ describe "#engine_version" do context "engine is ruby" do before do - stub_const("RUBY_ENGINE_VERSION", "2.2.4") + allow(Gem).to receive(:ruby_version).and_return(Gem::Version.new("2.2.4")) stub_const("RUBY_ENGINE", "ruby") end - it "should return a copy of the value of RUBY_ENGINE_VERSION" do + it "should return the value of Gem.ruby_version as a string" do expect(bundler_system_ruby_version.engine_versions).to eq(["2.2.4"]) - expect(bundler_system_ruby_version.engine_versions.first).to_not be(RUBY_ENGINE_VERSION) end end diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 57cff4e3b3e98a..7bf36ee0204422 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -522,14 +522,14 @@ ruby '~> 1.2' source "#{file_uri_for(gem_repo1)}" G - expect(err).to include("Your Ruby version is #{RUBY_VERSION}, but your Gemfile specified ~> 1.2") + expect(err).to include("Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified ~> 1.2") end end context "and using a supported Ruby version" do before do install_gemfile <<-G - ruby '~> #{RUBY_VERSION}' + ruby '~> #{Gem.ruby_version}' source "#{file_uri_for(gem_repo1)}" G end @@ -555,7 +555,7 @@ it "updates Gemfile.lock with updated yet still compatible ruby version" do install_gemfile <<-G - ruby '~> #{RUBY_VERSION[0..2]}' + ruby '~> #{current_ruby_minor}' source "#{file_uri_for(gem_repo1)}" G @@ -913,7 +913,7 @@ def run gemfile <<-G source "https://gem.repo4" - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" gem "loofah", "~> 2.12.0" G @@ -1000,6 +1000,50 @@ def run end end + context "with only option" do + before do + bundle "config set only a:b" + end + + it "installs only gems of the specified groups" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "rails" + gem "rack", group: :a + gem "rake", group: :b + gem "yard", group: :c + G + + expect(out).to include("Installing rack") + expect(out).to include("Installing rake") + expect(out).not_to include("Installing yard") + end + end + + context "with --prefer-local flag" do + before do + build_repo4 do + build_gem "foo", "1.0.1" + build_gem "foo", "1.0.0" + build_gem "bar", "1.0.0" + end + + system_gems "foo-1.0.0", :path => default_bundle_path, :gem_repo => gem_repo4 + end + + it "fetches remote sources only when not available locally" do + install_gemfile <<-G, :"prefer-local" => true, :verbose => true + source "#{file_uri_for(gem_repo4)}" + + gem "foo" + gem "bar" + G + + expect(out).to include("Using foo 1.0.0").and include("Fetching bar 1.0.0").and include("Installing bar 1.0.0") + expect(last_command).to be_success + end + end + context "with a symlinked configured as bundle path and a gem with symlinks" do before do symlinked_bundled_app = tmp("bundled_app-symlink") diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index b20a6ded43d10f..b314169a9850a7 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -541,11 +541,9 @@ def read_lockfile(file = "Gemfile.lock") end it "respects lower bound ruby requirements" do - skip "this spec does not work with prereleases because their version is actually lower than their reported `RUBY_VERSION`" if RUBY_PATCHLEVEL == -1 - build_repo4 do build_gem "our_private_gem", "0.1.0" do |s| - s.required_ruby_version = ">= #{RUBY_VERSION}" + s.required_ruby_version = ">= #{Gem.ruby_version}" end end diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index d45a5654753476..8ca537ac10da74 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -983,7 +983,7 @@ context "when the Gemfile removes the ruby" do before do install_gemfile <<-G - ruby '~> #{RUBY_VERSION}' + ruby '~> #{Gem.ruby_version}' source "#{file_uri_for(gem_repo1)}" G @@ -1013,12 +1013,12 @@ context "when the Gemfile specified an updated Ruby version" do before do install_gemfile <<-G - ruby '~> #{RUBY_VERSION}' + ruby '~> #{Gem.ruby_version}' source "#{file_uri_for(gem_repo1)}" G gemfile <<-G - ruby '~> #{RUBY_VERSION[0..2]}' + ruby '~> #{current_ruby_minor}' source "#{file_uri_for(gem_repo1)}" G end @@ -1047,7 +1047,7 @@ context "when a different Ruby is being used than has been versioned" do before do install_gemfile <<-G - ruby '~> #{RUBY_VERSION}' + ruby '~> #{Gem.ruby_version}' source "#{file_uri_for(gem_repo1)}" G @@ -1083,7 +1083,7 @@ L gemfile <<-G - ruby '~> #{RUBY_VERSION}' + ruby '~> #{Gem.ruby_version}' source "#{file_uri_for(gem_repo1)}" G end diff --git a/spec/bundler/install/gemfile/ruby_spec.rb b/spec/bundler/install/gemfile/ruby_spec.rb index ba250acfddf4a4..39f09031b7abca 100644 --- a/spec/bundler/install/gemfile/ruby_spec.rb +++ b/spec/bundler/install/gemfile/ruby_spec.rb @@ -11,13 +11,13 @@ def locked_ruby_version it "allows adding gems" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" gem "rack" G install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" gem "rack" gem "rack-obama" G @@ -28,7 +28,7 @@ def locked_ruby_version it "allows removing the ruby version requirement" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby "~> #{RUBY_VERSION}" + ruby "~> #{Gem.ruby_version}" gem "rack" G @@ -46,7 +46,7 @@ def locked_ruby_version it "allows changing the ruby version requirement to something compatible" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby ">= #{RUBY_VERSION[0..2]}.0" + ruby ">= #{current_ruby_minor}" gem "rack" G @@ -55,7 +55,7 @@ def locked_ruby_version install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby ">= #{RUBY_VERSION}" + ruby ">= #{Gem.ruby_version}" gem "rack" G @@ -93,7 +93,7 @@ def locked_ruby_version install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby ">= #{RUBY_VERSION[0..2]}.0" + ruby ">= #{current_ruby_minor}" gem "rack" G @@ -104,7 +104,7 @@ def locked_ruby_version it "allows requirements with trailing whitespace" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - ruby "#{RUBY_VERSION}\\n \t\\n" + ruby "#{Gem.ruby_version}\\n \t\\n" gem "rack" G diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index b136dea8bd3329..1679ad4460499d 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -211,7 +211,7 @@ end install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" source "http://localgemserver.test/" gem 'rack' G @@ -232,7 +232,7 @@ end install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" source "http://localgemserver.test/" gem 'rack' G @@ -309,7 +309,7 @@ end install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" source "http://localgemserver.test/" gem 'rack' gem 'foo1' @@ -333,7 +333,7 @@ simulate_platform mingw do install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - ruby "#{RUBY_VERSION}" + ruby "#{Gem.ruby_version}" source "http://localgemserver.test/" gem 'rack' G @@ -354,8 +354,8 @@ end end - let(:ruby_requirement) { %("#{RUBY_VERSION}") } - let(:error_message_requirement) { "= #{RUBY_VERSION}" } + let(:ruby_requirement) { %("#{Gem.ruby_version}") } + let(:error_message_requirement) { "= #{Gem.ruby_version}" } it "raises a proper error that mentions the current Ruby version during resolution" do install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false diff --git a/spec/bundler/install/gemspecs_spec.rb b/spec/bundler/install/gemspecs_spec.rb index 3684d8749df09b..7b58ea98391504 100644 --- a/spec/bundler/install/gemspecs_spec.rb +++ b/spec/bundler/install/gemspecs_spec.rb @@ -94,7 +94,8 @@ module Persistent💎 end context "when ruby version is specified in gemspec and gemfile" do - it "installs when patch level is not specified and the version matches" do + it "installs when patch level is not specified and the version matches", + :if => RUBY_PATCHLEVEL >= 0 do build_lib("foo", :path => bundled_app) do |s| s.required_ruby_version = "~> #{RUBY_VERSION}.0" end diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index b21765ec4d563e..29f8863591b44f 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -1174,7 +1174,7 @@ it "captures the Ruby version in the lockfile" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}/" - ruby '#{RUBY_VERSION}' + ruby '#{Gem.ruby_version}' gem "rack", "> 0.9", "< 1.0" G @@ -1191,7 +1191,7 @@ rack (> 0.9, < 1.0) RUBY VERSION - ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} + #{Bundler::RubyVersion.system} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/other/platform_spec.rb b/spec/bundler/other/platform_spec.rb index c157345cab7687..691a219e62d9d9 100644 --- a/spec/bundler/other/platform_spec.rb +++ b/spec/bundler/other/platform_spec.rb @@ -19,7 +19,7 @@ * #{specific_local_platform} Your Gemfile specifies a Ruby version requirement: -* ruby #{RUBY_VERSION} +* ruby #{Gem.ruby_version} Your current platform satisfies the Ruby version requirement. G @@ -42,7 +42,7 @@ * #{specific_local_platform} Your Gemfile specifies a Ruby version requirement: -* ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} +* #{Bundler::RubyVersion.system.single_version_string} Your current platform satisfies the Ruby version requirement. G @@ -85,7 +85,7 @@ Your Gemfile specifies a Ruby version requirement: * ruby #{not_local_ruby_version} -Your Ruby version is #{RUBY_VERSION}, but your Gemfile specified #{not_local_ruby_version} +Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified #{not_local_ruby_version} G end end @@ -255,18 +255,18 @@ end end - let(:ruby_version_correct) { "ruby \"#{RUBY_VERSION}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{local_engine_version}\"" } - let(:ruby_version_correct_engineless) { "ruby \"#{RUBY_VERSION}\"" } + let(:ruby_version_correct) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{local_engine_version}\"" } + let(:ruby_version_correct_engineless) { "ruby \"#{Gem.ruby_version}\"" } let(:ruby_version_correct_patchlevel) { "#{ruby_version_correct}, :patchlevel => '#{RUBY_PATCHLEVEL}'" } let(:ruby_version_incorrect) { "ruby \"#{not_local_ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{not_local_ruby_version}\"" } - let(:engine_incorrect) { "ruby \"#{RUBY_VERSION}\", :engine => \"#{not_local_tag}\", :engine_version => \"#{RUBY_VERSION}\"" } - let(:engine_version_incorrect) { "ruby \"#{RUBY_VERSION}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{not_local_engine_version}\"" } + let(:engine_incorrect) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{not_local_tag}\", :engine_version => \"#{Gem.ruby_version}\"" } + let(:engine_version_incorrect) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{not_local_engine_version}\"" } let(:patchlevel_incorrect) { "#{ruby_version_correct}, :patchlevel => '#{not_local_patchlevel}'" } let(:patchlevel_fixnum) { "#{ruby_version_correct}, :patchlevel => #{RUBY_PATCHLEVEL}1" } def should_be_ruby_version_incorrect expect(exitstatus).to eq(18) - expect(err).to be_include("Your Ruby version is #{RUBY_VERSION}, but your Gemfile specified #{not_local_ruby_version}") + expect(err).to be_include("Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified #{not_local_ruby_version}") end def should_be_engine_incorrect diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 03c0df3b508884..af6e33885348fe 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -476,7 +476,7 @@ def env_for_missing_prerelease_default_gem_activation end def current_ruby_minor - Gem.ruby_version.segments[0..1].join(".") + Gem.ruby_version.segments.tap {|s| s.delete_at(2) }.join(".") end def next_ruby_minor diff --git a/spec/bundler/support/platforms.rb b/spec/bundler/support/platforms.rb index 48479723e47f13..1ad7778403f350 100644 --- a/spec/bundler/support/platforms.rb +++ b/spec/bundler/support/platforms.rb @@ -71,7 +71,7 @@ def local_ruby_engine end def local_engine_version - RUBY_ENGINE_VERSION + RUBY_ENGINE == "ruby" ? Gem.ruby_version : RUBY_ENGINE_VERSION end def not_local_engine_version From def1d44aa193fb7640a78d864810734bba786e6d Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Thu, 28 Jul 2022 08:39:16 +0000 Subject: [PATCH 059/142] [rubygems/rubygems] Add package/pack aliases to man pages for cache Signed-off-by: Takuya Noguchi https://github.com/rubygems/rubygems/commit/1685e3a9dc --- lib/bundler/man/bundle-cache.1 | 6 ++++++ lib/bundler/man/bundle-cache.1.ronn | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1 index 49030158811e82..fdaaa3b92ac38b 100644 --- a/lib/bundler/man/bundle-cache.1 +++ b/lib/bundler/man/bundle-cache.1 @@ -9,6 +9,9 @@ .SH "SYNOPSIS" \fBbundle cache\fR . +.P +alias: \fBpackage\fR, \fBpack\fR +. .SH "DESCRIPTION" Copy all of the \fB\.gem\fR files needed to run the application into the \fBvendor/cache\fR directory\. In the future, when running [bundle install(1)][bundle\-install], use the gems in the cache in preference to the ones on \fBrubygems\.org\fR\. . @@ -53,3 +56,6 @@ One way to be sure that you have the right platformed versions of all your gems . .P By default, bundle cache(1) \fIbundle\-cache\.1\.html\fR fetches and also installs the gems to the default location\. To package the dependencies to \fBvendor/cache\fR without installing them to the local install location, you can run \fBbundle cache \-\-no\-install\fR\. +. +.SH "HISTORY" +In Bundler 2\.1, \fBcache\fR took in the functionalities of \fBpackage\fR and now \fBpackage\fR and \fBpack\fR are aliases of \fBcache\fR\. diff --git a/lib/bundler/man/bundle-cache.1.ronn b/lib/bundler/man/bundle-cache.1.ronn index 383adb2ba3bf31..46906d2b485d95 100644 --- a/lib/bundler/man/bundle-cache.1.ronn +++ b/lib/bundler/man/bundle-cache.1.ronn @@ -5,6 +5,8 @@ bundle-cache(1) -- Package your needed `.gem` files into your application `bundle cache` +alias: `package`, `pack` + ## DESCRIPTION Copy all of the `.gem` files needed to run the application into the @@ -70,3 +72,8 @@ By default, [bundle cache(1)](bundle-cache.1.html) fetches and also installs the gems to the default location. To package the dependencies to `vendor/cache` without installing them to the local install location, you can run `bundle cache --no-install`. + +## HISTORY + +In Bundler 2.1, `cache` took in the functionalities of `package` and now +`package` and `pack` are aliases of `cache`. From d1e726cce727fab7083993eb75237472a462cd72 Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Thu, 28 Jul 2022 01:30:02 +0000 Subject: [PATCH 060/142] [rubygems/rubygems] Fix dead links to deprecated bundle-package(1) with bundler-cache(1) Signed-off-by: Takuya Noguchi https://github.com/rubygems/rubygems/commit/9c2e80a10f --- lib/bundler/man/bundle-config.1 | 2 +- lib/bundler/man/bundle-config.1.ronn | 2 +- lib/bundler/man/bundle.1 | 7 ++----- lib/bundler/man/bundle.1.ronn | 5 ++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index b5cee57f29a6ed..9ab1f81c83369d 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -298,7 +298,7 @@ The following is a list of all configuration keys and their purpose\. You can le .IP "" 0 . .P -In general, you should set these settings per\-application by using the applicable flag to the bundle install(1) \fIbundle\-install\.1\.html\fR or bundle package(1) \fIbundle\-package\.1\.html\fR command\. +In general, you should set these settings per\-application by using the applicable flag to the bundle install(1) \fIbundle\-install\.1\.html\fR or bundle cache(1) \fIbundle\-cache\.1\.html\fR command\. . .P You can set them globally either via environment variables or \fBbundle config\fR, whichever is preferable for your setup\. If you use both, environment variables will take preference over global settings\. diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index e2af773141f3be..62afe77af8ea16 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -280,7 +280,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). A `:`-separated list of groups whose gems bundler should not install. In general, you should set these settings per-application by using the applicable -flag to the [bundle install(1)](bundle-install.1.html) or [bundle package(1)](bundle-package.1.html) command. +flag to the [bundle install(1)](bundle-install.1.html) or [bundle cache(1)](bundle-cache.1.html) command. You can set them globally either via environment variables or `bundle config`, whichever is preferable for your setup. If you use both, environment variables diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1 index efc4d7e93f7f60..f683e78cc6e25e 100644 --- a/lib/bundler/man/bundle.1 +++ b/lib/bundler/man/bundle.1 @@ -43,8 +43,8 @@ Install the gems specified by the \fBGemfile\fR or \fBGemfile\.lock\fR Update dependencies to their latest versions . .TP -\fBbundle package(1)\fR \fIbundle\-package\.1\.html\fR -Package the \.gem files required by your application into the \fBvendor/cache\fR directory +\fBbundle cache(1)\fR \fIbundle\-cache\.1\.html\fR +Package the \.gem files required by your application into the \fBvendor/cache\fR directory (aliases: \fBbundle package\fR, \fBbundle pack\fR) . .TP \fBbundle exec(1)\fR \fIbundle\-exec\.1\.html\fR @@ -127,9 +127,6 @@ When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bund These commands are obsolete and should no longer be used: . .IP "\(bu" 4 -\fBbundle cache(1)\fR -. -.IP "\(bu" 4 \fBbundle inject(1)\fR . .IP "" 0 diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn index 52a00d43ee7052..8f0159eee549c5 100644 --- a/lib/bundler/man/bundle.1.ronn +++ b/lib/bundler/man/bundle.1.ronn @@ -36,9 +36,9 @@ We divide `bundle` subcommands into primary commands and utilities: * [`bundle update(1)`](bundle-update.1.html): Update dependencies to their latest versions -* [`bundle package(1)`](bundle-package.1.html): +* [`bundle cache(1)`](bundle-cache.1.html): Package the .gem files required by your application into the - `vendor/cache` directory + `vendor/cache` directory (aliases: `bundle package`, `bundle pack`) * [`bundle exec(1)`](bundle-exec.1.html): Execute a script in the current bundle @@ -107,5 +107,4 @@ and execute it, passing down any extra arguments to it. These commands are obsolete and should no longer be used: -* `bundle cache(1)` * `bundle inject(1)` From 3725454161b55681e5b4ec3b7ca23a4126e23736 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 29 Jul 2022 15:47:02 +0900 Subject: [PATCH 061/142] Merge ruby/fileutils from https://github.com/ruby/fileutils/commit/332025bc0299254f97a06d64e580f60fea4e7125 --- lib/fileutils.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 003b4bdd827f5a..7eb66dda0c83a3 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -440,6 +440,8 @@ def fu_mkdir(path, mode) #:nodoc: # Raises an exception if a directory does not exist # or if for any reason a directory cannot be removed. # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def rmdir(list, parents: nil, noop: nil, verbose: nil) list = fu_list(list) fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose @@ -1261,6 +1263,8 @@ def rm_f(list, noop: nil, verbose: nil) # rm -r src0.dat src0.txt # rm -r src1 # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) list = fu_list(list) fu_output_message "rm -r#{force ? 'f' : ''} #{list.join ' '}" if verbose @@ -1290,6 +1294,8 @@ def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil) # # FileUtils.rmtree is an alias for FileUtils.rm_rf. # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def rm_rf(list, noop: nil, verbose: nil, secure: nil) rm_r list, force: true, noop: noop, verbose: verbose, secure: secure end @@ -1311,6 +1317,8 @@ def rm_rf(list, noop: nil, verbose: nil, secure: nil) # Optional argument +force+ specifies whether to ignore # raised exceptions of StandardError and its descendants. # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def remove_entry_secure(path, force = false) unless fu_have_symlink? remove_entry path, force @@ -1431,6 +1439,8 @@ def remove_entry(path, force = false) # Optional argument +force+ specifies whether to ignore # raised exceptions of StandardError and its descendants. # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def remove_file(path, force = false) Entry_.new(path).remove_file rescue @@ -1448,6 +1458,8 @@ def remove_file(path, force = false) # Optional argument +force+ specifies whether to ignore # raised exceptions of StandardError and its descendants. # + # Related: {methods for deleting}[rdoc-ref:FileUtils@Deleting]. + # def remove_dir(path, force = false) remove_entry path, force # FIXME?? check if it is a directory end @@ -1546,7 +1558,7 @@ def compare_stream(a, b) # using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown]. # - mode: permissions - changes the permissions. # using {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod]. - # - noop: true - does not remove entries; returns +nil+. + # - noop: true - does not copy entries; returns +nil+. # - owner: owner - changes the owner if not +nil+, # using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown]. # - preserve: true - preserve timestamps From 419ad1e13e6287d0b7a6ba1dfeb485d2f889bf9e Mon Sep 17 00:00:00 2001 From: konsolebox Date: Thu, 9 Jun 2022 19:43:24 +0800 Subject: [PATCH 062/142] [ruby/optparse] Also accept '-' as an optional argument (https://github.com/ruby/optparse/pull/35) https://github.com/ruby/optparse/commit/f2b8318631 --- lib/optparse.rb | 6 +++--- test/optparse/test_placearg.rb | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/optparse.rb b/lib/optparse.rb index ec37bde3bdd446..1d42c79045664d 100644 --- a/lib/optparse.rb +++ b/lib/optparse.rb @@ -765,15 +765,15 @@ def pretty_head # :nodoc: end # - # Switch that takes an argument, which does not begin with '-'. + # Switch that takes an argument, which does not begin with '-' or is '-'. # class PlacedArgument < self # - # Returns nil if argument is not present or begins with '-'. + # Returns nil if argument is not present or begins with '-' and is not '-'. # def parse(arg, argv, &error) - if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0])) + if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0])) return nil, block, nil end opt = (val = parse_arg(val, &error))[1] diff --git a/test/optparse/test_placearg.rb b/test/optparse/test_placearg.rb index 94cfb0e819b3e6..ed0e4d3e6c61e0 100644 --- a/test/optparse/test_placearg.rb +++ b/test/optparse/test_placearg.rb @@ -18,6 +18,8 @@ def setup def test_short assert_equal(%w"", no_error {@opt.parse!(%w"-x -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"-x -")}) + assert_equal("-", @flag) @flag = false assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")}) assert_equal("foo", @flag) @@ -30,6 +32,8 @@ def test_short def test_abbrev assert_equal(%w"", no_error {@opt.parse!(%w"-o -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"-o -")}) + assert_equal("-", @flag) @flag = false assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")}) assert_equal("foo", @flag) @@ -42,6 +46,8 @@ def test_abbrev def test_long assert_equal(%w"", no_error {@opt.parse!(%w"--opt -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"--opt -")}) + assert_equal("-", @flag) assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt= foo")}) assert_equal("", @flag) assert_equal(%w"", no_error {@opt.parse!(%w"--opt=foo")}) From 4bf97a8ec45e63f4d60a4146b8f99bd629c1f629 Mon Sep 17 00:00:00 2001 From: Luka Dornhecker Date: Sun, 22 May 2022 17:47:26 +0200 Subject: [PATCH 063/142] fix typo in Time#xmlschema documentation --- lib/time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/time.rb b/lib/time.rb index bd20a1a8e9b79b..43c4d802e5b603 100644 --- a/lib/time.rb +++ b/lib/time.rb @@ -701,7 +701,7 @@ def httpdate # # If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise. # - # +fractional_digits+ specifies a number of digits to use for fractional + # +fraction_digits+ specifies a number of digits to use for fractional # seconds. Its default value is 0. # # require 'time' From 66b52f046f3e4c5d24781a142f9633e07c42d6d9 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 20 May 2021 12:40:04 +0200 Subject: [PATCH 064/142] [flori/json] Stop including the parser source __LINE__ in exceptions It makes testing for JSON errors very tedious. You either have to use a Regexp or to regularly update all your assertions when JSON is upgraded. https://github.com/flori/json/commit/de9eb1d28e --- ext/json/generator/generator.c | 4 ++-- ext/json/parser/parser.c | 14 +++++++------- ext/json/parser/parser.rl | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index e3a83472e113fc..98d0ea46c385dd 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -997,10 +997,10 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St if (!allow_nan) { if (isinf(value)) { fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); + rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp)); } else if (isnan(value)) { fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); + rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp)); } } fbuffer_append_str(buffer, tmp); diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index 8b860c4101c47f..9bd7f1971ef460 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -948,7 +948,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); } } np = JSON_parse_float(json, p, pe, result); @@ -990,7 +990,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul if (json->allow_nan) { *result = CInfinity; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 8); } } @@ -1002,7 +1002,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul if (json->allow_nan) { *result = CNaN; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2); } } @@ -2348,7 +2348,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul if(cs >= JSON_array_first_final) { return p + 1; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); return NULL; } } @@ -2413,7 +2413,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int } rb_enc_raise( EXC_ENCODING eParserError, - "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p + "incomplete unicode character escape sequence at '%s'", p ); } else { UTF32 ch = unescape_unicode((unsigned char *) ++pe); @@ -2426,7 +2426,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int } rb_enc_raise( EXC_ENCODING eParserError, - "%u: incomplete surrogate pair at '%s'", __LINE__, p + "incomplete surrogate pair at '%s'", p ); } if (pe[0] == '\\' && pe[1] == 'u') { @@ -3225,7 +3225,7 @@ static VALUE cParser_parse(VALUE self) if (cs >= JSON_first_final && p == pe) { return result; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); return Qnil; } } diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl index 2dee80ee3b8ea0..2dbdc7ef245170 100644 --- a/ext/json/parser/parser.rl +++ b/ext/json/parser/parser.rl @@ -222,14 +222,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->allow_nan) { *result = CNaN; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2); } } action parse_infinity { if (json->allow_nan) { *result = CInfinity; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 8); } } action parse_string { @@ -245,7 +245,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu fexec p + 10; fhold; fbreak; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); } } np = JSON_parse_float(json, fpc, pe, result); @@ -447,7 +447,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul if(cs >= JSON_array_first_final) { return p + 1; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); return NULL; } } @@ -512,7 +512,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int } rb_enc_raise( EXC_ENCODING eParserError, - "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p + "incomplete unicode character escape sequence at '%s'", p ); } else { UTF32 ch = unescape_unicode((unsigned char *) ++pe); @@ -525,7 +525,7 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int } rb_enc_raise( EXC_ENCODING eParserError, - "%u: incomplete surrogate pair at '%s'", __LINE__, p + "incomplete surrogate pair at '%s'", p ); } if (pe[0] == '\\' && pe[1] == 'u') { @@ -864,7 +864,7 @@ static VALUE cParser_parse(VALUE self) if (cs >= JSON_first_final && p == pe) { return result; } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); + rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p); return Qnil; } } From b2cc74a50dd492e95bd76252046c25495f06a586 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Oct 2021 13:53:18 -0700 Subject: [PATCH 065/142] [flori/json] test parsing of unicode, mixing literal characters with escaped https://github.com/flori/json/commit/82fe866da2 --- test/json/json_parser_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index 00b254fc6a6941..146ff7c0477f01 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -115,6 +115,10 @@ def test_parse_bigdecimals assert_equal(BigDecimal("0.901234567890123456789E1"),JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"] ) end + def test_parse_string_mixed_unicode + assert_equal(["éé"], JSON.parse("[\"\\u00e9é\"]")) + end + if Array.method_defined?(:permutation) def test_parse_more_complex_arrays a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }] From 4e886d2adeaa3ae8a408fa549f19f203b82d9550 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 29 Jul 2022 17:06:18 +0900 Subject: [PATCH 066/142] Update parser-text.rb with https://github.com/ruby/racc/commit/4ecc13c9cbd4663268c34b0a5c99cf5307de7c60 --- lib/racc/parser-text.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/racc/parser-text.rb b/lib/racc/parser-text.rb index 4188fa853dba47..0579f4ce9b13fd 100644 --- a/lib/racc/parser-text.rb +++ b/lib/racc/parser-text.rb @@ -22,7 +22,7 @@ module Racc class ParseError < StandardError; end end unless defined?(::ParseError) - ParseError = Racc::ParseError + ParseError = Racc::ParseError # :nodoc: end # Racc is a LALR(1) parser generator. From 62849b337988268b4209c58b6de02d0002c78988 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 29 Jul 2022 17:07:36 +0900 Subject: [PATCH 067/142] Keep gitignore for libyaml source with psych --- tool/sync_default_gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index 47f6f1c840025a..e3b940e2d5a20c 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -184,7 +184,7 @@ def sync_default_gems(gem) rm_rf(%w[ext/psych/lib/psych.{bundle,so} ext/psych/lib/2.*]) rm_rf(["ext/psych/yaml/LICENSE"]) cp_r("#{upstream}/psych.gemspec", "ext/psych") - `git checkout ext/psych/depend` + `git checkout ext/psych/depend ext/psych/.gitignore` when "fiddle" rm_rf(%w[ext/fiddle test/fiddle]) cp_r("#{upstream}/ext/fiddle", "ext") From f78e46d404f156cc05066c4d895fd6bdef4aec7c Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Fri, 29 Jul 2022 09:40:12 -0500 Subject: [PATCH 068/142] [ruby/rdoc] Add block quotes (https://github.com/ruby/rdoc/pull/907) Also adjusts which blocks may be nested. https://github.com/ruby/rdoc/commit/dde1860441 --- doc/rdoc/markup_reference.rb | 66 +++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index cc682f987edfc0..49ad996c2d22e0 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -57,6 +57,7 @@ # - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. # - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. # - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. # - {Bullet lists}[rdoc-ref:RDoc::MarkupReference@Bullet+Lists]. # - {Numbered lists}[rdoc-ref:RDoc::MarkupReference@Numbered+Lists]. # - {Lettered lists}[rdoc-ref:RDoc::MarkupReference@Lettered+Lists]. @@ -99,7 +100,10 @@ # # - Verbatim text blocks. # - Code blocks. +# - Block quotes. # - Lists of any type. +# - Headings. +# - Horizontal rules. # # ==== Verbatim Text Blocks # @@ -169,6 +173,49 @@ # Pro tip: If your indented Ruby code does not get highlighted, # it may contain a syntax error. # +# ==== Block Quotes +# +# You can use the characters >>> (unindented), +# followed by indented text, to treat the text +# as a {block quote}[https://en.wikipedia.org/wiki/Block_quotation]: +# +# Example input: +# +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# Rendered HTML: +# +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# A block quote may contain nested blocks, including: +# +# - Other block quotes. +# - Paragraphs. +# - Verbatim text blocks. +# - Code blocks. +# - Lists of any type. +# - Headings. +# - Horizontal rules. +# +# Note that, unlike verbatim text, single newlines are not honored, +# but that a double newline begins a new paragraph in the block quote. +# # ==== Lists # # Each type of list item is marked by a special beginning: @@ -190,6 +237,16 @@ # A list item may be continued on additional lines that are aligned # with the first line. See examples below. # +# A list item may contain nested blocks, including: +# +# - Other lists of any type. +# - Paragraphs. +# - Verbatim text blocks. +# - Code blocks. +# - Block quotes. +# - Headings. +# - Horizontal rules. +# # ===== Bullet Lists # # A bullet list item begins with a hyphen or asterisk. @@ -291,15 +348,6 @@ # [bar baz] Yet another. # bam:: Last one. # -# ===== Blocks Nested in Lists -# -# A list item may contain nested blocks, including: -# -# - Paragraphs. -# - Verbatim text blocks. -# - Code blocks. -# - Other lists of any type. -# # ==== Headings # # A heading begins with up to six equal-signs, followed by heading text. From b515fdcc32a6a7d484c73f090fa2a58a8662e6ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 24 Jul 2022 21:58:13 +0200 Subject: [PATCH 069/142] [rubygems/rubygems] No need to set anything at all unless standalone is given https://github.com/rubygems/rubygems/commit/d695c8da3e --- lib/bundler/cli/install.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index e9b85f7f6f4b30..1601fc6a9876df 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -147,8 +147,11 @@ def normalize_groups def normalize_settings Bundler.settings.set_command_option :path, nil if options[:system] Bundler.settings.set_command_option_if_given :path, options[:path] - Bundler.settings.temporary(:path_relative_to_cwd => false) do - Bundler.settings.set_command_option :path, "bundle" if options["standalone"] && Bundler.settings[:path].nil? + + if options["standalone"] && Bundler.settings[:path].nil? + Bundler.settings.temporary(:path_relative_to_cwd => false) do + Bundler.settings.set_command_option :path, "bundle" + end end bin_option = options["binstubs"] From 030050cdfa9ae65cbbcd0f708aa2459e0ef17c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 24 Jul 2022 22:32:34 +0200 Subject: [PATCH 070/142] [rubygems/rubygems] Make `--standalone` play nice with `--local` I'm not sure if using relative paths in the generated script is best for this case, since it makes the script not movable, but that can be improved later. https://github.com/rubygems/rubygems/commit/7f5bdbb842 --- lib/bundler/cli/install.rb | 2 +- lib/bundler/installer/standalone.rb | 2 +- spec/bundler/install/gems/standalone_spec.rb | 28 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index 1601fc6a9876df..851ae9b840f8d6 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -148,7 +148,7 @@ def normalize_settings Bundler.settings.set_command_option :path, nil if options[:system] Bundler.settings.set_command_option_if_given :path, options[:path] - if options["standalone"] && Bundler.settings[:path].nil? + if options["standalone"] && Bundler.settings[:path].nil? && !options["local"] Bundler.settings.temporary(:path_relative_to_cwd => false) do Bundler.settings.set_command_option :path, "bundle" end diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb index 248b677233107a..2756626f8a6504 100644 --- a/lib/bundler/installer/standalone.rb +++ b/lib/bundler/installer/standalone.rb @@ -47,7 +47,7 @@ def extensions_dir end def bundler_path - Bundler.root.join(Bundler.settings[:path], "bundler") + Bundler.root.join(Bundler.settings[:path].to_s, "bundler") end def gem_path(path, spec) diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb index a5302877c1f4f2..238006c02bebba 100644 --- a/spec/bundler/install/gems/standalone_spec.rb +++ b/spec/bundler/install/gems/standalone_spec.rb @@ -461,3 +461,31 @@ include_examples("bundle install --standalone") end + +RSpec.describe "bundle install --standalone --local" do + before do + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "rack" + G + + system_gems "rack-1.0.0", :path => default_bundle_path + end + + it "generates script pointing to system gems" do + bundle "install --standalone --local --verbose" + + expect(out).to include("Using rack 1.0.0") + + load_error_ruby <<-RUBY, "spec" + require "./bundler/setup" + + require "rack" + puts RACK + require "spec" + RUBY + + expect(out).to eq("1.0.0") + expect(err).to eq("ZOMG LOAD ERROR") + end +end From 2346f3be64bc2098a54d0e8a36efd0982106c63d Mon Sep 17 00:00:00 2001 From: git Date: Sat, 30 Jul 2022 04:24:39 +0900 Subject: [PATCH 071/142] * 2022-07-30 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index b079c749d0dd9a..da18c1d27d0ac5 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 29 +#define RUBY_RELEASE_DAY 30 #include "ruby/version.h" #include "ruby/internal/abi.h" From 53175643ef826775d0a51fc48fdd79a4cf01dc70 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Fri, 29 Jul 2022 14:50:56 -0500 Subject: [PATCH 072/142] [ruby/date] [DOC] Enhanced RDoc (https://github.com/ruby/date/pull/66) Treats: #=== #to_s #inspect #strftme #asctime #iso3601 #rfc3339 #rfc2822 #httpdate #jisx0301 https://github.com/ruby/date/commit/aed66fedf6 --- ext/date/date_core.c | 144 ++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 51 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 9214333eed4227..d8048194ce8516 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -6344,9 +6344,9 @@ d_lite_prev_day(int argc, VALUE *argv, VALUE self) * * Returns a new \Date object representing the following day: * - * d = Date.today - * d.to_s # => "2022-07-11" - * d.next.to_s # => "2022-07-12" + * d = Date.new(2001, 2, 3) + * d.to_s # => "2001-02-03" + * d.next.to_s # => "2001-02-04" * * Date#succ is an alias for Date#next. */ @@ -6732,13 +6732,13 @@ cmp_dd(VALUE self, VALUE other) * * d <=> DateTime.new(2022, 7, 26) # => 1 * d <=> DateTime.new(2022, 7, 27) # => 0 - * d <=> DateTime.new(2022, 7, 29) # => -1 + * d <=> DateTime.new(2022, 7, 28) # => -1 * * - A numeric (compares self.ajd to +other+): * - * d <=> 2459789 # => -1 * d <=> 2459788 # => -1 * d <=> 2459787 # => 1 + * d <=> 2459786 # => 1 * d <=> d.ajd # => 0 * * - Any other object: @@ -6804,20 +6804,39 @@ equal_gen(VALUE self, VALUE other) /* * call-seq: - * d === other -> bool - * - * Returns true if they are the same day. - * - * Date.new(2001,2,3) === Date.new(2001,2,3) - * #=> true - * Date.new(2001,2,3) === Date.new(2001,2,4) - * #=> false - * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12) - * #=> true - * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00') - * #=> true - * DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00') - * #=> false + * self === other -> true, false, or nil. + * + * Returns +true+ if +self+ and +other+ represent the same date, + * +false+ if not, +nil+ if the two are not comparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => # + * prev_date = d.prev_day # => # + * next_date = d.next_day # => # + * d === prev_date # => false + * d === d # => true + * d === next_date # => false + * + * - A DateTime object: + * + * d === DateTime.new(2022, 7, 26) # => false + * d === DateTime.new(2022, 7, 27) # => true + * d === DateTime.new(2022, 7, 28) # => false + * + * - A numeric (compares self.jd to +other+): + * + * d === 2459788 # => true + * d === 2459787 # => false + * d === 2459786 # => false + * d === d.jd # => true + * + * - An object not comparable: + * + * d === Object.new # => nil + * */ static VALUE d_lite_equal(VALUE self, VALUE other) @@ -6880,12 +6899,14 @@ static VALUE strftimev(const char *, VALUE, /* * call-seq: - * d.to_s -> string + * to_s -> string * - * Returns a string in an ISO 8601 format. (This method doesn't use the - * expanded representations.) + * Returns a string representation of the date in +self+ + * in {ISO 8601 extended date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications] + * ('%Y-%m-%d'): + * + * Date.new(2001, 2, 3).to_s # => "2001-02-03" * - * Date.new(2001,2,3).to_s #=> "2001-02-03" */ static VALUE d_lite_to_s(VALUE self) @@ -6966,14 +6987,13 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s) /* * call-seq: - * d.inspect -> string + * inspect -> string + * + * Returns a string representation of +self+: * - * Returns the value as a string for inspection. + * Date.new(2001, 2, 3).inspect + * # => "#" * - * Date.new(2001,2,3).inspect - * #=> "#" - * DateTime.new(2001,2,3,4,5,6,'-7').inspect - * #=> "#" */ static VALUE d_lite_inspect(VALUE self) @@ -7155,12 +7175,12 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self, /* * call-seq: - * strftime(format = '%F') -> string + * strftime(format = '%F') -> string * - * Returns a string representation of +self+, + * Returns a string representation of the date in +self+, * formatted according the given +format+: * - * Date.today.strftime # => "2022-07-01" + * Date.new(2001, 2, 3).strftime # => "2001-02-03" * * For other formats, see * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. @@ -7192,13 +7212,17 @@ strftimev(const char *fmt, VALUE self, /* * call-seq: - * d.asctime -> string - * d.ctime -> string + * asctime -> string + * + * Equivalent to #strftime with argument '%a %b %e %T %Y' + * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers] + * '%c'): * - * Returns a string in asctime(3) format (but without "\n\0" at the - * end). This method is equivalent to strftime('%c'). + * Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001" * - * See also asctime(3) or ctime(3). + * See {asctime}[https://linux.die.net/man/3/asctime]. + * + * Date#ctime is an alias for Date#asctime. */ static VALUE d_lite_asctime(VALUE self) @@ -7208,10 +7232,15 @@ d_lite_asctime(VALUE self) /* * call-seq: - * d.iso8601 -> string - * d.xmlschema -> string + * iso8601 -> string + * + * Equivalent to #strftime with argument '%Y-%m-%d' + * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers] + * '%F'); * - * This method is equivalent to strftime('%F'). + * Date.new(2001, 2, 3).iso8601 # => "2001-02-03" + * + * Date#xmlschema is an alias for Date#iso8601. */ static VALUE d_lite_iso8601(VALUE self) @@ -7221,9 +7250,13 @@ d_lite_iso8601(VALUE self) /* * call-seq: - * d.rfc3339 -> string + * rfc3339 -> string + * + * Equivalent to #strftime with argument '%FT%T%:z'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00" * - * This method is equivalent to strftime('%FT%T%:z'). */ static VALUE d_lite_rfc3339(VALUE self) @@ -7233,10 +7266,14 @@ d_lite_rfc3339(VALUE self) /* * call-seq: - * d.rfc2822 -> string - * d.rfc822 -> string + * rfc2822 -> string + * + * Equivalent to #strftime with argument '%a, %-d %b %Y %T %z'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" * - * This method is equivalent to strftime('%a, %-d %b %Y %T %z'). + * Date#rfc822 is an alias for Date#rfc2822. */ static VALUE d_lite_rfc2822(VALUE self) @@ -7246,10 +7283,13 @@ d_lite_rfc2822(VALUE self) /* * call-seq: - * d.httpdate -> string + * httpdate -> string + * + * Equivalent to #strftime with argument '%a, %d %b %Y %T GMT'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" * - * This method is equivalent to strftime('%a, %d %b %Y %T GMT'). - * See also RFC 2616. */ static VALUE d_lite_httpdate(VALUE self) @@ -7300,11 +7340,13 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y) /* * call-seq: - * d.jisx0301 -> string + * jisx0301 -> string * - * Returns a string in a JIS X 0301 format. + * Returns a string representation of the date in +self+ + * in JIS X 0301 format. + * + * Date.new(2001, 2, 3).jisx0301 # => "H13.02.03" * - * Date.new(2001,2,3).jisx0301 #=> "H13.02.03" */ static VALUE d_lite_jisx0301(VALUE self) From fbd24793cb7be2429edafcf11d7dd4a7d11f5c95 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 6 Jul 2022 22:14:25 -0700 Subject: [PATCH 073/142] Add --enable-yjit=stats configure option --- configure.ac | 27 +++++++++++++++++++-------- yjit/Cargo.toml | 3 +++ yjit/yjit.mk | 7 +++++-- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 4fe1623966bae4..46ea0388656645 100644 --- a/configure.ac +++ b/configure.ac @@ -3736,7 +3736,7 @@ CARGO= CARGO_BUILD_ARGS= YJIT_LIBS= AS_CASE(["${YJIT_SUPPORT}"], -[yes|dev], [ +[yes|dev|stats], [ AS_IF([test x"$enable_jit_support" = "xno"], AC_MSG_ERROR([--disable-jit-support but --enable-yjit. YJIT requires JIT support]) ) @@ -3744,16 +3744,27 @@ AS_CASE(["${YJIT_SUPPORT}"], AS_IF([test x"$RUSTC" = "xno"], AC_MSG_ERROR([rustc is required. Installation instructions available at https://www.rust-lang.org/tools/install]) ) - AS_IF([test x"$YJIT_SUPPORT" = "xyes"], - [rb_rust_target_subdir=release - CARGO_BUILD_ARGS='--release'], - [rb_rust_target_subdir=debug - CARGO_BUILD_ARGS='--features stats,disasm,asm_comments' + + AS_CASE(["${YJIT_SUPPORT}"], + [yes], [ + rb_rust_target_subdir=release + ], + [dev], [ + rb_rust_target_subdir=debug + CARGO_BUILD_ARGS='--features stats,disasm,asm_comments' + AC_DEFINE(RUBY_DEBUG, 1) + ], + [stats], [ + rb_rust_target_subdir=stats + CARGO_BUILD_ARGS='--profile stats --features stats,disasm,asm_comments' + ]) + + AS_IF([test -n "${CARGO_BUILD_ARGS}"], [ AC_CHECK_TOOL(CARGO, [cargo], [no]) AS_IF([test x"$CARGO" = "xno"], AC_MSG_ERROR([cargo is required. Installation instructions available at https://www.rust-lang.org/tools/install]) - ) - AC_DEFINE(RUBY_DEBUG, 1)]) + ])) + YJIT_LIBS="yjit/target/${rb_rust_target_subdir}/libyjit.a" YJIT_OBJ='yjit.$(OBJEXT)' AC_DEFINE(USE_YJIT, 1) diff --git a/yjit/Cargo.toml b/yjit/Cargo.toml index a5208049cbc84a..c7ff31ec2cd20e 100644 --- a/yjit/Cargo.toml +++ b/yjit/Cargo.toml @@ -30,6 +30,9 @@ debug = true debug-assertions = true overflow-checks = true +[profile.stats] +inherits = "release" + [profile.release] # NOTE: --enable-yjit builds use `rustc` without going through Cargo. You # might want to update the `rustc` invocation if you change this profile. diff --git a/yjit/yjit.mk b/yjit/yjit.mk index eb1f5d1fe19d02..efd4ff0c40652e 100644 --- a/yjit/yjit.mk +++ b/yjit/yjit.mk @@ -25,13 +25,16 @@ yjit-static-lib-no: $(ECHO) 'Error: Tried to build YJIT without configuring it first. Check `make showconfig`?' @false -yjit-static-lib-dev: - $(ECHO) 'building Rust YJIT (dev mode)' +yjit-static-lib-cargo: + $(ECHO) 'building Rust YJIT ($(YJIT_SUPPORT) mode)' $(Q)$(CHDIR) $(top_srcdir)/yjit && \ CARGO_TARGET_DIR='$(CARGO_TARGET_DIR)' \ CARGO_TERM_PROGRESS_WHEN='never' \ $(CARGO) $(CARGO_VERBOSE) build $(CARGO_BUILD_ARGS) +yjit-static-lib-dev: yjit-static-lib-cargo +yjit-static-lib-stats: yjit-static-lib-cargo + # This PHONY prerequisite makes it so that we always run cargo. When there are # no Rust changes on rebuild, Cargo does not touch the mtime of the static # library and GNU make avoids relinking. $(empty) seems to be important to From 0e85586ecc983ebb4541cd046949428d1ef5d635 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Fri, 29 Jul 2022 15:07:06 -0700 Subject: [PATCH 074/142] Add --enable-yjit=dev_nodebug configure option --- configure.ac | 8 ++++++-- yjit/Cargo.toml | 3 +++ yjit/yjit.mk | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 46ea0388656645..864a9a4e8b0499 100644 --- a/configure.ac +++ b/configure.ac @@ -3736,7 +3736,7 @@ CARGO= CARGO_BUILD_ARGS= YJIT_LIBS= AS_CASE(["${YJIT_SUPPORT}"], -[yes|dev|stats], [ +[yes|dev|stats|dev_nodebug], [ AS_IF([test x"$enable_jit_support" = "xno"], AC_MSG_ERROR([--disable-jit-support but --enable-yjit. YJIT requires JIT support]) ) @@ -3754,9 +3754,13 @@ AS_CASE(["${YJIT_SUPPORT}"], CARGO_BUILD_ARGS='--features stats,disasm,asm_comments' AC_DEFINE(RUBY_DEBUG, 1) ], + [dev_nodebug], [ + rb_rust_target_subdir=dev_nodebug + CARGO_BUILD_ARGS='--profile dev_nodebug --features stats,disasm,asm_comments' + ], [stats], [ rb_rust_target_subdir=stats - CARGO_BUILD_ARGS='--profile stats --features stats,disasm,asm_comments' + CARGO_BUILD_ARGS='--profile stats --features stats' ]) AS_IF([test -n "${CARGO_BUILD_ARGS}"], [ diff --git a/yjit/Cargo.toml b/yjit/Cargo.toml index c7ff31ec2cd20e..4641de205f1d32 100644 --- a/yjit/Cargo.toml +++ b/yjit/Cargo.toml @@ -33,6 +33,9 @@ overflow-checks = true [profile.stats] inherits = "release" +[profile.dev_nodebug] +inherits = "release" + [profile.release] # NOTE: --enable-yjit builds use `rustc` without going through Cargo. You # might want to update the `rustc` invocation if you change this profile. diff --git a/yjit/yjit.mk b/yjit/yjit.mk index efd4ff0c40652e..9e3155deb33195 100644 --- a/yjit/yjit.mk +++ b/yjit/yjit.mk @@ -33,6 +33,7 @@ yjit-static-lib-cargo: $(CARGO) $(CARGO_VERBOSE) build $(CARGO_BUILD_ARGS) yjit-static-lib-dev: yjit-static-lib-cargo +yjit-static-lib-dev_nodebug: yjit-static-lib-cargo yjit-static-lib-stats: yjit-static-lib-cargo # This PHONY prerequisite makes it so that we always run cargo. When there are From af265d73fb2726fcd405d86d37d28bbf03de3b04 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 01:18:04 +0900 Subject: [PATCH 075/142] [ruby/rdoc] Fix blockquote with word in verbatim https://github.com/ruby/rdoc/commit/75eee668a5 --- lib/rdoc/markup/parser.rb | 16 ++++++++++------ test/rdoc/test_rdoc_markup_to_html.rb | 9 +++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/rdoc/markup/parser.rb b/lib/rdoc/markup/parser.rb index b0fcb61f50299b..0029df7e65e7f9 100644 --- a/lib/rdoc/markup/parser.rb +++ b/lib/rdoc/markup/parser.rb @@ -289,6 +289,10 @@ def build_verbatim margin line << data when :BLOCKQUOTE then line << '>>>' + peek_type, _, peek_column = peek_token + if peek_type != :NEWLINE and peek_column + line << ' ' * (peek_column - column - 3) + end else # *LIST_TOKENS list_marker = case type when :BULLET then data @@ -374,11 +378,8 @@ def parse parent, indent = 0 unget parse_text parent, indent when :BLOCKQUOTE then - type, _, column = get - if type == :NEWLINE - type, _, column = get - end - unget if type + nil while (type, = get; type) and type != :NEWLINE + _, _, column, = peek_token bq = RDoc::Markup::BlockQuote.new p :blockquote_start => [data, column] if @debug parse bq, column @@ -546,7 +547,10 @@ def tokenize input [:NOTE, @s[1], *pos] # >>> followed by end of line => :BLOCKQUOTE when @s.scan(/>>> *(\w+)?$/) then - [:BLOCKQUOTE, @s[1], *pos] + if word = @s[1] + @s.unscan(word) + end + [:BLOCKQUOTE, word, *pos] # anything else: :TEXT else @s.scan(/(.*?)( )?\r?$/) diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb index 3cf42d7c5e8826..a5927dccaee92e 100644 --- a/test/rdoc/test_rdoc_markup_to_html.rb +++ b/test/rdoc/test_rdoc_markup_to_html.rb @@ -821,6 +821,15 @@ def test_block_quote_in_verbatim EXPECTED assert_equal expected, @m.convert(str, @to).gsub(/^\n/, "") + + str = "BlockQuote\n >>> word\n" + + expected = <<-EXPECTED +

BlockQuote

+
>>>  word
+ EXPECTED + + assert_equal expected, @m.convert(str, @to).gsub(/^\n/, "") end def test_parseable_eh From 48b09aae7ec5632209229dcc294dd0d75a93a17f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 16:36:07 +0900 Subject: [PATCH 076/142] [ruby/digest] Revert tab-expansion in external files https://github.com/ruby/digest/commit/5ca2b5b91e --- ext/digest/md5/md5.c | 124 ++-- ext/digest/md5/md5.h | 4 +- ext/digest/rmd160/rmd160.c | 512 +++++++------- ext/digest/rmd160/rmd160.h | 8 +- ext/digest/sha1/sha1.c | 26 +- ext/digest/sha1/sha1.h | 6 +- ext/digest/sha2/sha2.c | 1374 ++++++++++++++++++------------------ ext/digest/sha2/sha2.h | 12 +- 8 files changed, 1033 insertions(+), 1033 deletions(-) diff --git a/ext/digest/md5/md5.c b/ext/digest/md5/md5.c index 52a787abdb20ff..3a7fe2cdad27b6 100644 --- a/ext/digest/md5/md5.c +++ b/ext/digest/md5/md5.c @@ -34,8 +34,8 @@ that follows (in reverse chronological order): 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; - made test program self-checking. + unsigned in ANSI C, signed in traditional"; + made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. @@ -64,32 +64,32 @@ int main(void) { static const char *const test[7*2] = { - "", "d41d8cd98f00b204e9800998ecf8427e", - "a", "0cc175b9c0f1b6a831c399e269772661", - "abc", "900150983cd24fb0d6963f7d28e17f72", - "message digest", "f96b697d7cb7938d525a2f31aaf161d0", - "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - "d174ab98d277d9f5a5611c2c9f419d9f", - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" + "", "d41d8cd98f00b204e9800998ecf8427e", + "a", "0cc175b9c0f1b6a831c399e269772661", + "abc", "900150983cd24fb0d6963f7d28e17f72", + "message digest", "f96b697d7cb7938d525a2f31aaf161d0", + "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "d174ab98d277d9f5a5611c2c9f419d9f", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" }; int i; for (i = 0; i < 7*2; i += 2) { - MD5_CTX state; - uint8_t digest[16]; - char hex_output[16*2 + 1]; - int di; - - MD5_Init(&state); - MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); - MD5_Final(digest, &state); - printf("MD5 (\"%s\") = ", test[i]); - for (di = 0; di < 16; ++di) - sprintf(hex_output + di * 2, "%02x", digest[di]); - puts(hex_output); - if (strcmp(hex_output, test[i + 1])) - printf("**** ERROR, should be: %s\n", test[i + 1]); + MD5_CTX state; + uint8_t digest[16]; + char hex_output[16*2 + 1]; + int di; + + MD5_Init(&state); + MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); + MD5_Final(digest, &state); + printf("MD5 (\"%s\") = ", test[i]); + for (di = 0; di < 16; ++di) + sprintf(hex_output + di * 2, "%02x", digest[di]); + puts(hex_output); + if (strcmp(hex_output, test[i + 1])) + printf("**** ERROR, should be: %s\n", test[i + 1]); } return 0; } @@ -106,18 +106,18 @@ main(void) { int i; for (i = 1; i <= 64; ++i) { - unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); - - /* - * The following nonsense is only to avoid compiler warnings about - * "integer constant is unsigned in ANSI C, signed with -traditional". - */ - if (v >> 31) { - printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, - v, (unsigned long)(unsigned int)(~v)); - } else { - printf("#define T%d 0x%08lx\n", i, v); - } + unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); + + /* + * The following nonsense is only to avoid compiler warnings about + * "integer constant is unsigned in ANSI C, signed with -traditional". + */ + if (v >> 31) { + printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, + v, (unsigned long)(unsigned int)(~v)); + } else { + printf("#define T%d 0x%08lx\n", i, v); + } } return 0; } @@ -199,8 +199,8 @@ static void md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) { uint32_t - a = pms->state[0], b = pms->state[1], - c = pms->state[2], d = pms->state[3]; + a = pms->state[0], b = pms->state[1], + c = pms->state[2], d = pms->state[3]; uint32_t t; #ifdef WORDS_BIGENDIAN @@ -214,7 +214,7 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) int i; for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); #else @@ -226,12 +226,12 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) const uint32_t *X; if (!(((uintptr_t)data) & 3)) { - /* data are properly aligned */ - X = (const uint32_t *)data; + /* data are properly aligned */ + X = (const uint32_t *)data; } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; } #endif @@ -370,55 +370,55 @@ MD5_Update(MD5_CTX *pms, const uint8_t *data, size_t nbytes) uint32_t nbits = (uint32_t)(nbytes << 3); if (nbytes == 0) - return; + return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) - pms->count[1]++; + pms->count[1]++; /* Process an initial partial block. */ if (offset) { - size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buffer + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buffer); + size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buffer + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buffer); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); + md5_process(pms, p); /* Process a final partial block. */ if (left) - memcpy(pms->buffer, p, left); + memcpy(pms->buffer, p, left); } int MD5_Finish(MD5_CTX *pms, uint8_t *digest) { static const uint8_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t data[8]; size_t i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) - data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ MD5_Update(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ MD5_Update(pms, data, 8); for (i = 0; i < 16; ++i) - digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); + digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); return 1; } diff --git a/ext/digest/md5/md5.h b/ext/digest/md5/md5.h index 0b04f9fc4eab58..1b3383c5eecde7 100644 --- a/ext/digest/md5/md5.h +++ b/ext/digest/md5/md5.h @@ -34,8 +34,8 @@ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . + added conditionalization for C++ compilation from Martin + Purschke . 1999-05-03 lpd Original version. */ diff --git a/ext/digest/rmd160/rmd160.c b/ext/digest/rmd160/rmd160.c index 0ea78dcd642d0a..058d004f3a672d 100644 --- a/ext/digest/rmd160/rmd160.c +++ b/ext/digest/rmd160/rmd160.c @@ -128,17 +128,17 @@ int RMD160_Init(RMD160_CTX *context) { - _DIAGASSERT(context != NULL); - - /* ripemd-160 initialization constants */ - context->state[0] = 0x67452301U; - context->state[1] = 0xefcdab89U; - context->state[2] = 0x98badcfeU; - context->state[3] = 0x10325476U; - context->state[4] = 0xc3d2e1f0U; - context->length[0] = context->length[1] = 0; - context->buflen = 0; - return 1; + _DIAGASSERT(context != NULL); + + /* ripemd-160 initialization constants */ + context->state[0] = 0x67452301U; + context->state[1] = 0xefcdab89U; + context->state[2] = 0x98badcfeU; + context->state[3] = 0x10325476U; + context->state[4] = 0xc3d2e1f0U; + context->length[0] = context->length[1] = 0; + context->buflen = 0; + return 1; } /********************************************************************/ @@ -146,205 +146,205 @@ RMD160_Init(RMD160_CTX *context) void RMD160_Transform(uint32_t state[5], const uint32_t block[16]) { - uint32_t aa, bb, cc, dd, ee; - uint32_t aaa, bbb, ccc, ddd, eee; - - _DIAGASSERT(state != NULL); - _DIAGASSERT(block != NULL); - - aa = aaa = state[0]; - bb = bbb = state[1]; - cc = ccc = state[2]; - dd = ddd = state[3]; - ee = eee = state[4]; - - /* round 1 */ - FF(aa, bb, cc, dd, ee, block[ 0], 11); - FF(ee, aa, bb, cc, dd, block[ 1], 14); - FF(dd, ee, aa, bb, cc, block[ 2], 15); - FF(cc, dd, ee, aa, bb, block[ 3], 12); - FF(bb, cc, dd, ee, aa, block[ 4], 5); - FF(aa, bb, cc, dd, ee, block[ 5], 8); - FF(ee, aa, bb, cc, dd, block[ 6], 7); - FF(dd, ee, aa, bb, cc, block[ 7], 9); - FF(cc, dd, ee, aa, bb, block[ 8], 11); - FF(bb, cc, dd, ee, aa, block[ 9], 13); - FF(aa, bb, cc, dd, ee, block[10], 14); - FF(ee, aa, bb, cc, dd, block[11], 15); - FF(dd, ee, aa, bb, cc, block[12], 6); - FF(cc, dd, ee, aa, bb, block[13], 7); - FF(bb, cc, dd, ee, aa, block[14], 9); - FF(aa, bb, cc, dd, ee, block[15], 8); - - /* round 2 */ - GG(ee, aa, bb, cc, dd, block[ 7], 7); - GG(dd, ee, aa, bb, cc, block[ 4], 6); - GG(cc, dd, ee, aa, bb, block[13], 8); - GG(bb, cc, dd, ee, aa, block[ 1], 13); - GG(aa, bb, cc, dd, ee, block[10], 11); - GG(ee, aa, bb, cc, dd, block[ 6], 9); - GG(dd, ee, aa, bb, cc, block[15], 7); - GG(cc, dd, ee, aa, bb, block[ 3], 15); - GG(bb, cc, dd, ee, aa, block[12], 7); - GG(aa, bb, cc, dd, ee, block[ 0], 12); - GG(ee, aa, bb, cc, dd, block[ 9], 15); - GG(dd, ee, aa, bb, cc, block[ 5], 9); - GG(cc, dd, ee, aa, bb, block[ 2], 11); - GG(bb, cc, dd, ee, aa, block[14], 7); - GG(aa, bb, cc, dd, ee, block[11], 13); - GG(ee, aa, bb, cc, dd, block[ 8], 12); - - /* round 3 */ - HH(dd, ee, aa, bb, cc, block[ 3], 11); - HH(cc, dd, ee, aa, bb, block[10], 13); - HH(bb, cc, dd, ee, aa, block[14], 6); - HH(aa, bb, cc, dd, ee, block[ 4], 7); - HH(ee, aa, bb, cc, dd, block[ 9], 14); - HH(dd, ee, aa, bb, cc, block[15], 9); - HH(cc, dd, ee, aa, bb, block[ 8], 13); - HH(bb, cc, dd, ee, aa, block[ 1], 15); - HH(aa, bb, cc, dd, ee, block[ 2], 14); - HH(ee, aa, bb, cc, dd, block[ 7], 8); - HH(dd, ee, aa, bb, cc, block[ 0], 13); - HH(cc, dd, ee, aa, bb, block[ 6], 6); - HH(bb, cc, dd, ee, aa, block[13], 5); - HH(aa, bb, cc, dd, ee, block[11], 12); - HH(ee, aa, bb, cc, dd, block[ 5], 7); - HH(dd, ee, aa, bb, cc, block[12], 5); - - /* round 4 */ - II(cc, dd, ee, aa, bb, block[ 1], 11); - II(bb, cc, dd, ee, aa, block[ 9], 12); - II(aa, bb, cc, dd, ee, block[11], 14); - II(ee, aa, bb, cc, dd, block[10], 15); - II(dd, ee, aa, bb, cc, block[ 0], 14); - II(cc, dd, ee, aa, bb, block[ 8], 15); - II(bb, cc, dd, ee, aa, block[12], 9); - II(aa, bb, cc, dd, ee, block[ 4], 8); - II(ee, aa, bb, cc, dd, block[13], 9); - II(dd, ee, aa, bb, cc, block[ 3], 14); - II(cc, dd, ee, aa, bb, block[ 7], 5); - II(bb, cc, dd, ee, aa, block[15], 6); - II(aa, bb, cc, dd, ee, block[14], 8); - II(ee, aa, bb, cc, dd, block[ 5], 6); - II(dd, ee, aa, bb, cc, block[ 6], 5); - II(cc, dd, ee, aa, bb, block[ 2], 12); - - /* round 5 */ - JJ(bb, cc, dd, ee, aa, block[ 4], 9); - JJ(aa, bb, cc, dd, ee, block[ 0], 15); - JJ(ee, aa, bb, cc, dd, block[ 5], 5); - JJ(dd, ee, aa, bb, cc, block[ 9], 11); - JJ(cc, dd, ee, aa, bb, block[ 7], 6); - JJ(bb, cc, dd, ee, aa, block[12], 8); - JJ(aa, bb, cc, dd, ee, block[ 2], 13); - JJ(ee, aa, bb, cc, dd, block[10], 12); - JJ(dd, ee, aa, bb, cc, block[14], 5); - JJ(cc, dd, ee, aa, bb, block[ 1], 12); - JJ(bb, cc, dd, ee, aa, block[ 3], 13); - JJ(aa, bb, cc, dd, ee, block[ 8], 14); - JJ(ee, aa, bb, cc, dd, block[11], 11); - JJ(dd, ee, aa, bb, cc, block[ 6], 8); - JJ(cc, dd, ee, aa, bb, block[15], 5); - JJ(bb, cc, dd, ee, aa, block[13], 6); - - /* parallel round 1 */ - JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); - JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); - JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); - JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); - JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); - JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); - JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); - JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); - - /* parallel round 2 */ - III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); - III(ddd, eee, aaa, bbb, ccc, block[11], 13); - III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); - III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); - III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); - III(eee, aaa, bbb, ccc, ddd, block[13], 8); - III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); - III(ccc, ddd, eee, aaa, bbb, block[10], 11); - III(bbb, ccc, ddd, eee, aaa, block[14], 7); - III(aaa, bbb, ccc, ddd, eee, block[15], 7); - III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); - III(ddd, eee, aaa, bbb, ccc, block[12], 7); - III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); - III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); - III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); - III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); - - /* parallel round 3 */ - HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); - HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); - HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); - HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); - HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); - HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); - HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); - HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); - HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); - HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); - HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); - HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); - HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); - HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); - HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); - HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); - - /* parallel round 4 */ - GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); - GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); - GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); - GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); - GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); - GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); - GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); - GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); - GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); - GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); - GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); - GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); - GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); - GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); - GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); - GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); - - /* parallel round 5 */ - FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); - FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); - FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); - FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); - FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); - FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); - FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); - FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); - FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); - FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); - FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); - FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); - FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); - FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); - - /* combine results */ - ddd += cc + state[1]; /* final result for state[0] */ - state[1] = state[2] + dd + eee; - state[2] = state[3] + ee + aaa; - state[3] = state[4] + aa + bbb; - state[4] = state[0] + bb + ccc; - state[0] = ddd; + uint32_t aa, bb, cc, dd, ee; + uint32_t aaa, bbb, ccc, ddd, eee; + + _DIAGASSERT(state != NULL); + _DIAGASSERT(block != NULL); + + aa = aaa = state[0]; + bb = bbb = state[1]; + cc = ccc = state[2]; + dd = ddd = state[3]; + ee = eee = state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, block[ 0], 11); + FF(ee, aa, bb, cc, dd, block[ 1], 14); + FF(dd, ee, aa, bb, cc, block[ 2], 15); + FF(cc, dd, ee, aa, bb, block[ 3], 12); + FF(bb, cc, dd, ee, aa, block[ 4], 5); + FF(aa, bb, cc, dd, ee, block[ 5], 8); + FF(ee, aa, bb, cc, dd, block[ 6], 7); + FF(dd, ee, aa, bb, cc, block[ 7], 9); + FF(cc, dd, ee, aa, bb, block[ 8], 11); + FF(bb, cc, dd, ee, aa, block[ 9], 13); + FF(aa, bb, cc, dd, ee, block[10], 14); + FF(ee, aa, bb, cc, dd, block[11], 15); + FF(dd, ee, aa, bb, cc, block[12], 6); + FF(cc, dd, ee, aa, bb, block[13], 7); + FF(bb, cc, dd, ee, aa, block[14], 9); + FF(aa, bb, cc, dd, ee, block[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, block[ 7], 7); + GG(dd, ee, aa, bb, cc, block[ 4], 6); + GG(cc, dd, ee, aa, bb, block[13], 8); + GG(bb, cc, dd, ee, aa, block[ 1], 13); + GG(aa, bb, cc, dd, ee, block[10], 11); + GG(ee, aa, bb, cc, dd, block[ 6], 9); + GG(dd, ee, aa, bb, cc, block[15], 7); + GG(cc, dd, ee, aa, bb, block[ 3], 15); + GG(bb, cc, dd, ee, aa, block[12], 7); + GG(aa, bb, cc, dd, ee, block[ 0], 12); + GG(ee, aa, bb, cc, dd, block[ 9], 15); + GG(dd, ee, aa, bb, cc, block[ 5], 9); + GG(cc, dd, ee, aa, bb, block[ 2], 11); + GG(bb, cc, dd, ee, aa, block[14], 7); + GG(aa, bb, cc, dd, ee, block[11], 13); + GG(ee, aa, bb, cc, dd, block[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, block[ 3], 11); + HH(cc, dd, ee, aa, bb, block[10], 13); + HH(bb, cc, dd, ee, aa, block[14], 6); + HH(aa, bb, cc, dd, ee, block[ 4], 7); + HH(ee, aa, bb, cc, dd, block[ 9], 14); + HH(dd, ee, aa, bb, cc, block[15], 9); + HH(cc, dd, ee, aa, bb, block[ 8], 13); + HH(bb, cc, dd, ee, aa, block[ 1], 15); + HH(aa, bb, cc, dd, ee, block[ 2], 14); + HH(ee, aa, bb, cc, dd, block[ 7], 8); + HH(dd, ee, aa, bb, cc, block[ 0], 13); + HH(cc, dd, ee, aa, bb, block[ 6], 6); + HH(bb, cc, dd, ee, aa, block[13], 5); + HH(aa, bb, cc, dd, ee, block[11], 12); + HH(ee, aa, bb, cc, dd, block[ 5], 7); + HH(dd, ee, aa, bb, cc, block[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, block[ 1], 11); + II(bb, cc, dd, ee, aa, block[ 9], 12); + II(aa, bb, cc, dd, ee, block[11], 14); + II(ee, aa, bb, cc, dd, block[10], 15); + II(dd, ee, aa, bb, cc, block[ 0], 14); + II(cc, dd, ee, aa, bb, block[ 8], 15); + II(bb, cc, dd, ee, aa, block[12], 9); + II(aa, bb, cc, dd, ee, block[ 4], 8); + II(ee, aa, bb, cc, dd, block[13], 9); + II(dd, ee, aa, bb, cc, block[ 3], 14); + II(cc, dd, ee, aa, bb, block[ 7], 5); + II(bb, cc, dd, ee, aa, block[15], 6); + II(aa, bb, cc, dd, ee, block[14], 8); + II(ee, aa, bb, cc, dd, block[ 5], 6); + II(dd, ee, aa, bb, cc, block[ 6], 5); + II(cc, dd, ee, aa, bb, block[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, block[ 4], 9); + JJ(aa, bb, cc, dd, ee, block[ 0], 15); + JJ(ee, aa, bb, cc, dd, block[ 5], 5); + JJ(dd, ee, aa, bb, cc, block[ 9], 11); + JJ(cc, dd, ee, aa, bb, block[ 7], 6); + JJ(bb, cc, dd, ee, aa, block[12], 8); + JJ(aa, bb, cc, dd, ee, block[ 2], 13); + JJ(ee, aa, bb, cc, dd, block[10], 12); + JJ(dd, ee, aa, bb, cc, block[14], 5); + JJ(cc, dd, ee, aa, bb, block[ 1], 12); + JJ(bb, cc, dd, ee, aa, block[ 3], 13); + JJ(aa, bb, cc, dd, ee, block[ 8], 14); + JJ(ee, aa, bb, cc, dd, block[11], 11); + JJ(dd, ee, aa, bb, cc, block[ 6], 8); + JJ(cc, dd, ee, aa, bb, block[15], 5); + JJ(bb, cc, dd, ee, aa, block[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, block[11], 13); + III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, block[13], 8); + III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, block[10], 11); + III(bbb, ccc, ddd, eee, aaa, block[14], 7); + III(aaa, bbb, ccc, ddd, eee, block[15], 7); + III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, block[12], 7); + III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); + + /* combine results */ + ddd += cc + state[1]; /* final result for state[0] */ + state[1] = state[2] + dd + eee; + state[2] = state[3] + ee + aaa; + state[3] = state[4] + aa + bbb; + state[4] = state[0] + bb + ccc; + state[0] = ddd; } /********************************************************************/ @@ -352,26 +352,26 @@ RMD160_Transform(uint32_t state[5], const uint32_t block[16]) void RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) { - uint32_t X[16]; - uint32_t ofs = 0; - uint32_t i; + uint32_t X[16]; + uint32_t ofs = 0; + uint32_t i; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(context != NULL); - _DIAGASSERT(data != NULL); + _DIAGASSERT(context != NULL); + _DIAGASSERT(data != NULL); - /* update length[] */ + /* update length[] */ #if SIZEOF_SIZE_T * CHAR_BIT > 32 - context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); + context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); #else - if (context->length[0] + nbytes < context->length[0]) - context->length[1]++; /* overflow to msb of length */ + if (context->length[0] + nbytes < context->length[0]) + context->length[1]++; /* overflow to msb of length */ #endif - context->length[0] += (uint32_t)nbytes; + context->length[0] += (uint32_t)nbytes; - (void)memset(X, 0, sizeof(X)); + (void)memset(X, 0, sizeof(X)); if ( context->buflen + nbytes < 64 ) { @@ -416,48 +416,48 @@ RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) int RMD160_Finish(RMD160_CTX *context, uint8_t digest[20]) { - uint32_t i; - uint32_t X[16]; + uint32_t i; + uint32_t X[16]; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(digest != NULL); - _DIAGASSERT(context != NULL); + _DIAGASSERT(digest != NULL); + _DIAGASSERT(context != NULL); - /* append the bit m_n == 1 */ - context->bbuffer[context->buflen] = (uint8_t)'\200'; + /* append the bit m_n == 1 */ + context->bbuffer[context->buflen] = (uint8_t)'\200'; - (void)memset(context->bbuffer + context->buflen + 1, 0, - 63 - context->buflen); + (void)memset(context->bbuffer + context->buflen + 1, 0, + 63 - context->buflen); #ifndef WORDS_BIGENDIAN - (void)memcpy(X, context->bbuffer, sizeof(X)); + (void)memcpy(X, context->bbuffer, sizeof(X)); #else - for (j=0; j < 16; j++) - X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); + for (j=0; j < 16; j++) + X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); #endif - if ((context->buflen) > 55) { - /* length goes to next block */ - RMD160_Transform(context->state, X); - (void)memset(X, 0, sizeof(X)); - } - - /* append length in bits */ - X[14] = context->length[0] << 3; - X[15] = (context->length[0] >> 29) | - (context->length[1] << 3); - RMD160_Transform(context->state, X); - - if (digest != NULL) { - for (i = 0; i < 20; i += 4) { - /* extracts the 8 least significant bits. */ - digest[i] = context->state[i>>2]; - digest[i + 1] = (context->state[i>>2] >> 8); - digest[i + 2] = (context->state[i>>2] >> 16); - digest[i + 3] = (context->state[i>>2] >> 24); - } - } - return 1; + if ((context->buflen) > 55) { + /* length goes to next block */ + RMD160_Transform(context->state, X); + (void)memset(X, 0, sizeof(X)); + } + + /* append length in bits */ + X[14] = context->length[0] << 3; + X[15] = (context->length[0] >> 29) | + (context->length[1] << 3); + RMD160_Transform(context->state, X); + + if (digest != NULL) { + for (i = 0; i < 20; i += 4) { + /* extracts the 8 least significant bits. */ + digest[i] = context->state[i>>2]; + digest[i + 1] = (context->state[i>>2] >> 8); + digest[i + 2] = (context->state[i>>2] >> 16); + digest[i + 3] = (context->state[i>>2] >> 24); + } + } + return 1; } /************************ end of file rmd160.c **********************/ diff --git a/ext/digest/rmd160/rmd160.h b/ext/digest/rmd160/rmd160.h index 617b262d906753..6324709d9602f2 100644 --- a/ext/digest/rmd160/rmd160.h +++ b/ext/digest/rmd160/rmd160.h @@ -29,10 +29,10 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; /* state (ABCDE) */ - uint32_t length[2]; /* number of bits */ - uint8_t bbuffer[64]; /* overflow buffer */ - uint32_t buflen; /* number of chars in bbuffer */ + uint32_t state[5]; /* state (ABCDE) */ + uint32_t length[2]; /* number of bits */ + uint8_t bbuffer[64]; /* overflow buffer */ + uint32_t buflen; /* number of chars in bbuffer */ } RMD160_CTX; #ifdef RUBY diff --git a/ext/digest/sha1/sha1.c b/ext/digest/sha1/sha1.c index afe952f8ba8c52..53112275498795 100644 --- a/ext/digest/sha1/sha1.c +++ b/ext/digest/sha1/sha1.c @@ -227,16 +227,16 @@ void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) j = context->count[0]; if ((context->count[0] += len << 3) < j) - context->count[1] += (len>>29)+1; + context->count[1] += (len>>29)+1; j = (j >> 3) & 63; if ((j + len) > 63) { - (void)memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1_Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) - SHA1_Transform(context->state, &data[i]); - j = 0; + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1_Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1_Transform(context->state, &data[i]); + j = 0; } else { - i = 0; + i = 0; } (void)memcpy(&context->buffer[j], &data[i], len - i); } @@ -254,18 +254,18 @@ int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) _DIAGASSERT(context != 0); for (i = 0; i < 8; i++) { - finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1_Update(context, (const uint8_t *)"\200", 1); while ((context->count[0] & 504) != 448) - SHA1_Update(context, (const uint8_t *)"\0", 1); + SHA1_Update(context, (const uint8_t *)"\0", 1); SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ if (digest) { - for (i = 0; i < 20; i++) - digest[i] = (uint8_t) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + for (i = 0; i < 20; i++) + digest[i] = (uint8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } return 1; } diff --git a/ext/digest/sha1/sha1.h b/ext/digest/sha1/sha1.h index e1d01b76ab14e0..2accc46d465d00 100644 --- a/ext/digest/sha1/sha1.h +++ b/ext/digest/sha1/sha1.h @@ -14,9 +14,9 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; - uint32_t count[2]; - uint8_t buffer[64]; + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; } SHA1_CTX; #ifdef RUBY diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index 2a9dbd4fce0cb1..21d5acbe964287 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -136,17 +136,17 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ - ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ - (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ - ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ + ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ + (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ + ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ @@ -156,10 +156,10 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ * 64-bit words): */ #define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ } /* @@ -235,102 +235,102 @@ void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ static const sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ static const sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ static const sha2_word64 K512[80] = { - ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), - ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), - ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), - ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), - ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), - ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), - ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), - ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), - ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), - ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), - ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), - ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), - ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), - ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), - ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), - ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), - ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), - ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), - ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), - ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), - ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), - ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), - ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), - ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), - ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), - ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), - ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), - ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), - ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), - ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), - ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), - ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), - ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), - ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), - ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), - ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), - ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), - ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), - ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), - ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) + ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), + ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), + ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), + ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), + ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), + ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), + ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), + ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), + ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), + ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), + ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), + ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), + ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), + ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), + ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), + ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), + ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), + ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), + ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), + ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), + ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), + ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), + ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), + ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), + ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), + ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), + ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), + ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), + ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), + ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), + ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), + ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), + ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), + ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), + ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), + ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), + ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), + ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), + ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), + ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) }; /* Initial hash value H for SHA-384 */ static const sha2_word64 sha384_initial_hash_value[8] = { - ULL(0xcbbb9d5dc1059ed8), - ULL(0x629a292a367cd507), - ULL(0x9159015a3070dd17), - ULL(0x152fecd8f70e5939), - ULL(0x67332667ffc00b31), - ULL(0x8eb44a8768581511), - ULL(0xdb0c2e0d64f98fa7), - ULL(0x47b5481dbefa4fa4) + ULL(0xcbbb9d5dc1059ed8), + ULL(0x629a292a367cd507), + ULL(0x9159015a3070dd17), + ULL(0x152fecd8f70e5939), + ULL(0x67332667ffc00b31), + ULL(0x8eb44a8768581511), + ULL(0xdb0c2e0d64f98fa7), + ULL(0x47b5481dbefa4fa4) }; /* Initial hash value H for SHA-512 */ static const sha2_word64 sha512_initial_hash_value[8] = { - ULL(0x6a09e667f3bcc908), - ULL(0xbb67ae8584caa73b), - ULL(0x3c6ef372fe94f82b), - ULL(0xa54ff53a5f1d36f1), - ULL(0x510e527fade682d1), - ULL(0x9b05688c2b3e6c1f), - ULL(0x1f83d9abfb41bd6b), - ULL(0x5be0cd19137e2179) + ULL(0x6a09e667f3bcc908), + ULL(0xbb67ae8584caa73b), + ULL(0x3c6ef372fe94f82b), + ULL(0xa54ff53a5f1d36f1), + ULL(0x510e527fade682d1), + ULL(0x9b05688c2b3e6c1f), + ULL(0x1f83d9abfb41bd6b), + ULL(0x5be0cd19137e2179) }; /* @@ -342,13 +342,13 @@ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ int SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; - return 1; + if (context == (SHA256_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -358,328 +358,328 @@ int SHA256_Init(SHA256_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Copy data while converting to host byte order */ - REVERSE32(*data++,W256[j]); - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); - SHA256_Transform(context, (sha2_word32*)context->buffer); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); + SHA256_Transform(context, (sha2_word32*)context->buffer); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; } int SHA256_Final(sha2_byte digest[SHA256_DIGEST_LENGTH], SHA256_CTX* context) { - sha2_word32 *d = (sha2_word32*)digest; - unsigned int usedspace; + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - } - } else { - /* Set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, - sizeof(sha2_word64)); - - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, + sizeof(sha2_word64)); + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif - } + } - /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(*context)); - usedspace = 0; - return 1; + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); + usedspace = 0; + return 1; } char *SHA256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - if (buffer != (char*)0) { - SHA256_Final(digest, context); - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; + SHA256_CTX context; - SHA256_Init(&context); - SHA256_Update(&context, data, len); - return SHA256_End(&context, digest); + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ int SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA512_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -688,394 +688,394 @@ int SHA512_Init(SHA512_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - REVERSE64(*data++, W512[j]); - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); - SHA512_Transform(context, (sha2_word64*)context->buffer); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); + SHA512_Transform(context, (sha2_word64*)context->buffer); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { - unsigned int usedspace; + unsigned int usedspace; - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); - } - } else { - /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Store the length of input data (in bits): */ - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], - sizeof(sha2_word64)); - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], - sizeof(sha2_word64)); - - /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], + sizeof(sha2_word64)); + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], + sizeof(sha2_word64)); + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); } int SHA512_Final(sha2_byte digest[SHA512_DIGEST_LENGTH], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last(context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - if (buffer != (char*)0) { - SHA512_Final(digest, context); - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; + SHA512_CTX context; - SHA512_Init(&context); - SHA512_Update(&context, data, len); - return SHA512_End(&context, digest); + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ int SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA384_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); + SHA512_Update((SHA512_CTX*)context, data, len); } int SHA384_Final(sha2_byte digest[SHA384_DIGEST_LENGTH], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA384_End(SHA384_CTX* context, char buffer[SHA384_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - if (buffer != (char*)0) { - SHA384_Final(digest, context); - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; + SHA384_CTX context; - SHA384_Init(&context); - SHA384_Update(&context, data, len); - return SHA384_End(&context, digest); + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); } diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h index c2a29b99ad5273..e58f15ae1297bd 100644 --- a/ext/digest/sha2/sha2.h +++ b/ext/digest/sha2/sha2.h @@ -120,14 +120,14 @@ typedef unsigned long long uint64_t; /* 8-bytes (64-bits) */ * cc -DSHA2_USE_INTTYPES_H ... */ typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; typedef SHA512_CTX SHA384_CTX; From 8a65cf3b61c60e4cb886f59a73ff6db44364bfa9 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 30 Jul 2022 16:41:32 +0900 Subject: [PATCH 077/142] * expand tabs. [ci skip] Tabs were expanded because the file did not have any tab indentation in unedited lines. Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook. --- ext/digest/md5/md5.c | 124 ++-- ext/digest/md5/md5.h | 4 +- ext/digest/rmd160/rmd160.c | 512 +++++++------- ext/digest/rmd160/rmd160.h | 8 +- ext/digest/sha1/sha1.c | 26 +- ext/digest/sha1/sha1.h | 6 +- ext/digest/sha2/sha2.c | 1374 ++++++++++++++++++------------------ ext/digest/sha2/sha2.h | 12 +- 8 files changed, 1033 insertions(+), 1033 deletions(-) diff --git a/ext/digest/md5/md5.c b/ext/digest/md5/md5.c index 3a7fe2cdad27b6..52a787abdb20ff 100644 --- a/ext/digest/md5/md5.c +++ b/ext/digest/md5/md5.c @@ -34,8 +34,8 @@ that follows (in reverse chronological order): 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; - made test program self-checking. + unsigned in ANSI C, signed in traditional"; + made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. @@ -64,32 +64,32 @@ int main(void) { static const char *const test[7*2] = { - "", "d41d8cd98f00b204e9800998ecf8427e", - "a", "0cc175b9c0f1b6a831c399e269772661", - "abc", "900150983cd24fb0d6963f7d28e17f72", - "message digest", "f96b697d7cb7938d525a2f31aaf161d0", - "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - "d174ab98d277d9f5a5611c2c9f419d9f", - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" + "", "d41d8cd98f00b204e9800998ecf8427e", + "a", "0cc175b9c0f1b6a831c399e269772661", + "abc", "900150983cd24fb0d6963f7d28e17f72", + "message digest", "f96b697d7cb7938d525a2f31aaf161d0", + "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "d174ab98d277d9f5a5611c2c9f419d9f", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" }; int i; for (i = 0; i < 7*2; i += 2) { - MD5_CTX state; - uint8_t digest[16]; - char hex_output[16*2 + 1]; - int di; - - MD5_Init(&state); - MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); - MD5_Final(digest, &state); - printf("MD5 (\"%s\") = ", test[i]); - for (di = 0; di < 16; ++di) - sprintf(hex_output + di * 2, "%02x", digest[di]); - puts(hex_output); - if (strcmp(hex_output, test[i + 1])) - printf("**** ERROR, should be: %s\n", test[i + 1]); + MD5_CTX state; + uint8_t digest[16]; + char hex_output[16*2 + 1]; + int di; + + MD5_Init(&state); + MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); + MD5_Final(digest, &state); + printf("MD5 (\"%s\") = ", test[i]); + for (di = 0; di < 16; ++di) + sprintf(hex_output + di * 2, "%02x", digest[di]); + puts(hex_output); + if (strcmp(hex_output, test[i + 1])) + printf("**** ERROR, should be: %s\n", test[i + 1]); } return 0; } @@ -106,18 +106,18 @@ main(void) { int i; for (i = 1; i <= 64; ++i) { - unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); - - /* - * The following nonsense is only to avoid compiler warnings about - * "integer constant is unsigned in ANSI C, signed with -traditional". - */ - if (v >> 31) { - printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, - v, (unsigned long)(unsigned int)(~v)); - } else { - printf("#define T%d 0x%08lx\n", i, v); - } + unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); + + /* + * The following nonsense is only to avoid compiler warnings about + * "integer constant is unsigned in ANSI C, signed with -traditional". + */ + if (v >> 31) { + printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, + v, (unsigned long)(unsigned int)(~v)); + } else { + printf("#define T%d 0x%08lx\n", i, v); + } } return 0; } @@ -199,8 +199,8 @@ static void md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) { uint32_t - a = pms->state[0], b = pms->state[1], - c = pms->state[2], d = pms->state[3]; + a = pms->state[0], b = pms->state[1], + c = pms->state[2], d = pms->state[3]; uint32_t t; #ifdef WORDS_BIGENDIAN @@ -214,7 +214,7 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) int i; for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); #else @@ -226,12 +226,12 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) const uint32_t *X; if (!(((uintptr_t)data) & 3)) { - /* data are properly aligned */ - X = (const uint32_t *)data; + /* data are properly aligned */ + X = (const uint32_t *)data; } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; } #endif @@ -370,55 +370,55 @@ MD5_Update(MD5_CTX *pms, const uint8_t *data, size_t nbytes) uint32_t nbits = (uint32_t)(nbytes << 3); if (nbytes == 0) - return; + return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) - pms->count[1]++; + pms->count[1]++; /* Process an initial partial block. */ if (offset) { - size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buffer + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buffer); + size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buffer + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buffer); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); + md5_process(pms, p); /* Process a final partial block. */ if (left) - memcpy(pms->buffer, p, left); + memcpy(pms->buffer, p, left); } int MD5_Finish(MD5_CTX *pms, uint8_t *digest) { static const uint8_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t data[8]; size_t i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) - data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ MD5_Update(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ MD5_Update(pms, data, 8); for (i = 0; i < 16; ++i) - digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); + digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); return 1; } diff --git a/ext/digest/md5/md5.h b/ext/digest/md5/md5.h index 1b3383c5eecde7..0b04f9fc4eab58 100644 --- a/ext/digest/md5/md5.h +++ b/ext/digest/md5/md5.h @@ -34,8 +34,8 @@ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . + added conditionalization for C++ compilation from Martin + Purschke . 1999-05-03 lpd Original version. */ diff --git a/ext/digest/rmd160/rmd160.c b/ext/digest/rmd160/rmd160.c index 058d004f3a672d..0ea78dcd642d0a 100644 --- a/ext/digest/rmd160/rmd160.c +++ b/ext/digest/rmd160/rmd160.c @@ -128,17 +128,17 @@ int RMD160_Init(RMD160_CTX *context) { - _DIAGASSERT(context != NULL); - - /* ripemd-160 initialization constants */ - context->state[0] = 0x67452301U; - context->state[1] = 0xefcdab89U; - context->state[2] = 0x98badcfeU; - context->state[3] = 0x10325476U; - context->state[4] = 0xc3d2e1f0U; - context->length[0] = context->length[1] = 0; - context->buflen = 0; - return 1; + _DIAGASSERT(context != NULL); + + /* ripemd-160 initialization constants */ + context->state[0] = 0x67452301U; + context->state[1] = 0xefcdab89U; + context->state[2] = 0x98badcfeU; + context->state[3] = 0x10325476U; + context->state[4] = 0xc3d2e1f0U; + context->length[0] = context->length[1] = 0; + context->buflen = 0; + return 1; } /********************************************************************/ @@ -146,205 +146,205 @@ RMD160_Init(RMD160_CTX *context) void RMD160_Transform(uint32_t state[5], const uint32_t block[16]) { - uint32_t aa, bb, cc, dd, ee; - uint32_t aaa, bbb, ccc, ddd, eee; - - _DIAGASSERT(state != NULL); - _DIAGASSERT(block != NULL); - - aa = aaa = state[0]; - bb = bbb = state[1]; - cc = ccc = state[2]; - dd = ddd = state[3]; - ee = eee = state[4]; - - /* round 1 */ - FF(aa, bb, cc, dd, ee, block[ 0], 11); - FF(ee, aa, bb, cc, dd, block[ 1], 14); - FF(dd, ee, aa, bb, cc, block[ 2], 15); - FF(cc, dd, ee, aa, bb, block[ 3], 12); - FF(bb, cc, dd, ee, aa, block[ 4], 5); - FF(aa, bb, cc, dd, ee, block[ 5], 8); - FF(ee, aa, bb, cc, dd, block[ 6], 7); - FF(dd, ee, aa, bb, cc, block[ 7], 9); - FF(cc, dd, ee, aa, bb, block[ 8], 11); - FF(bb, cc, dd, ee, aa, block[ 9], 13); - FF(aa, bb, cc, dd, ee, block[10], 14); - FF(ee, aa, bb, cc, dd, block[11], 15); - FF(dd, ee, aa, bb, cc, block[12], 6); - FF(cc, dd, ee, aa, bb, block[13], 7); - FF(bb, cc, dd, ee, aa, block[14], 9); - FF(aa, bb, cc, dd, ee, block[15], 8); - - /* round 2 */ - GG(ee, aa, bb, cc, dd, block[ 7], 7); - GG(dd, ee, aa, bb, cc, block[ 4], 6); - GG(cc, dd, ee, aa, bb, block[13], 8); - GG(bb, cc, dd, ee, aa, block[ 1], 13); - GG(aa, bb, cc, dd, ee, block[10], 11); - GG(ee, aa, bb, cc, dd, block[ 6], 9); - GG(dd, ee, aa, bb, cc, block[15], 7); - GG(cc, dd, ee, aa, bb, block[ 3], 15); - GG(bb, cc, dd, ee, aa, block[12], 7); - GG(aa, bb, cc, dd, ee, block[ 0], 12); - GG(ee, aa, bb, cc, dd, block[ 9], 15); - GG(dd, ee, aa, bb, cc, block[ 5], 9); - GG(cc, dd, ee, aa, bb, block[ 2], 11); - GG(bb, cc, dd, ee, aa, block[14], 7); - GG(aa, bb, cc, dd, ee, block[11], 13); - GG(ee, aa, bb, cc, dd, block[ 8], 12); - - /* round 3 */ - HH(dd, ee, aa, bb, cc, block[ 3], 11); - HH(cc, dd, ee, aa, bb, block[10], 13); - HH(bb, cc, dd, ee, aa, block[14], 6); - HH(aa, bb, cc, dd, ee, block[ 4], 7); - HH(ee, aa, bb, cc, dd, block[ 9], 14); - HH(dd, ee, aa, bb, cc, block[15], 9); - HH(cc, dd, ee, aa, bb, block[ 8], 13); - HH(bb, cc, dd, ee, aa, block[ 1], 15); - HH(aa, bb, cc, dd, ee, block[ 2], 14); - HH(ee, aa, bb, cc, dd, block[ 7], 8); - HH(dd, ee, aa, bb, cc, block[ 0], 13); - HH(cc, dd, ee, aa, bb, block[ 6], 6); - HH(bb, cc, dd, ee, aa, block[13], 5); - HH(aa, bb, cc, dd, ee, block[11], 12); - HH(ee, aa, bb, cc, dd, block[ 5], 7); - HH(dd, ee, aa, bb, cc, block[12], 5); - - /* round 4 */ - II(cc, dd, ee, aa, bb, block[ 1], 11); - II(bb, cc, dd, ee, aa, block[ 9], 12); - II(aa, bb, cc, dd, ee, block[11], 14); - II(ee, aa, bb, cc, dd, block[10], 15); - II(dd, ee, aa, bb, cc, block[ 0], 14); - II(cc, dd, ee, aa, bb, block[ 8], 15); - II(bb, cc, dd, ee, aa, block[12], 9); - II(aa, bb, cc, dd, ee, block[ 4], 8); - II(ee, aa, bb, cc, dd, block[13], 9); - II(dd, ee, aa, bb, cc, block[ 3], 14); - II(cc, dd, ee, aa, bb, block[ 7], 5); - II(bb, cc, dd, ee, aa, block[15], 6); - II(aa, bb, cc, dd, ee, block[14], 8); - II(ee, aa, bb, cc, dd, block[ 5], 6); - II(dd, ee, aa, bb, cc, block[ 6], 5); - II(cc, dd, ee, aa, bb, block[ 2], 12); - - /* round 5 */ - JJ(bb, cc, dd, ee, aa, block[ 4], 9); - JJ(aa, bb, cc, dd, ee, block[ 0], 15); - JJ(ee, aa, bb, cc, dd, block[ 5], 5); - JJ(dd, ee, aa, bb, cc, block[ 9], 11); - JJ(cc, dd, ee, aa, bb, block[ 7], 6); - JJ(bb, cc, dd, ee, aa, block[12], 8); - JJ(aa, bb, cc, dd, ee, block[ 2], 13); - JJ(ee, aa, bb, cc, dd, block[10], 12); - JJ(dd, ee, aa, bb, cc, block[14], 5); - JJ(cc, dd, ee, aa, bb, block[ 1], 12); - JJ(bb, cc, dd, ee, aa, block[ 3], 13); - JJ(aa, bb, cc, dd, ee, block[ 8], 14); - JJ(ee, aa, bb, cc, dd, block[11], 11); - JJ(dd, ee, aa, bb, cc, block[ 6], 8); - JJ(cc, dd, ee, aa, bb, block[15], 5); - JJ(bb, cc, dd, ee, aa, block[13], 6); - - /* parallel round 1 */ - JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); - JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); - JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); - JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); - JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); - JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); - JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); - JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); - - /* parallel round 2 */ - III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); - III(ddd, eee, aaa, bbb, ccc, block[11], 13); - III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); - III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); - III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); - III(eee, aaa, bbb, ccc, ddd, block[13], 8); - III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); - III(ccc, ddd, eee, aaa, bbb, block[10], 11); - III(bbb, ccc, ddd, eee, aaa, block[14], 7); - III(aaa, bbb, ccc, ddd, eee, block[15], 7); - III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); - III(ddd, eee, aaa, bbb, ccc, block[12], 7); - III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); - III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); - III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); - III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); - - /* parallel round 3 */ - HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); - HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); - HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); - HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); - HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); - HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); - HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); - HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); - HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); - HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); - HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); - HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); - HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); - HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); - HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); - HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); - - /* parallel round 4 */ - GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); - GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); - GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); - GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); - GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); - GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); - GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); - GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); - GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); - GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); - GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); - GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); - GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); - GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); - GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); - GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); - - /* parallel round 5 */ - FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); - FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); - FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); - FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); - FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); - FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); - FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); - FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); - FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); - FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); - FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); - FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); - FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); - FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); - - /* combine results */ - ddd += cc + state[1]; /* final result for state[0] */ - state[1] = state[2] + dd + eee; - state[2] = state[3] + ee + aaa; - state[3] = state[4] + aa + bbb; - state[4] = state[0] + bb + ccc; - state[0] = ddd; + uint32_t aa, bb, cc, dd, ee; + uint32_t aaa, bbb, ccc, ddd, eee; + + _DIAGASSERT(state != NULL); + _DIAGASSERT(block != NULL); + + aa = aaa = state[0]; + bb = bbb = state[1]; + cc = ccc = state[2]; + dd = ddd = state[3]; + ee = eee = state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, block[ 0], 11); + FF(ee, aa, bb, cc, dd, block[ 1], 14); + FF(dd, ee, aa, bb, cc, block[ 2], 15); + FF(cc, dd, ee, aa, bb, block[ 3], 12); + FF(bb, cc, dd, ee, aa, block[ 4], 5); + FF(aa, bb, cc, dd, ee, block[ 5], 8); + FF(ee, aa, bb, cc, dd, block[ 6], 7); + FF(dd, ee, aa, bb, cc, block[ 7], 9); + FF(cc, dd, ee, aa, bb, block[ 8], 11); + FF(bb, cc, dd, ee, aa, block[ 9], 13); + FF(aa, bb, cc, dd, ee, block[10], 14); + FF(ee, aa, bb, cc, dd, block[11], 15); + FF(dd, ee, aa, bb, cc, block[12], 6); + FF(cc, dd, ee, aa, bb, block[13], 7); + FF(bb, cc, dd, ee, aa, block[14], 9); + FF(aa, bb, cc, dd, ee, block[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, block[ 7], 7); + GG(dd, ee, aa, bb, cc, block[ 4], 6); + GG(cc, dd, ee, aa, bb, block[13], 8); + GG(bb, cc, dd, ee, aa, block[ 1], 13); + GG(aa, bb, cc, dd, ee, block[10], 11); + GG(ee, aa, bb, cc, dd, block[ 6], 9); + GG(dd, ee, aa, bb, cc, block[15], 7); + GG(cc, dd, ee, aa, bb, block[ 3], 15); + GG(bb, cc, dd, ee, aa, block[12], 7); + GG(aa, bb, cc, dd, ee, block[ 0], 12); + GG(ee, aa, bb, cc, dd, block[ 9], 15); + GG(dd, ee, aa, bb, cc, block[ 5], 9); + GG(cc, dd, ee, aa, bb, block[ 2], 11); + GG(bb, cc, dd, ee, aa, block[14], 7); + GG(aa, bb, cc, dd, ee, block[11], 13); + GG(ee, aa, bb, cc, dd, block[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, block[ 3], 11); + HH(cc, dd, ee, aa, bb, block[10], 13); + HH(bb, cc, dd, ee, aa, block[14], 6); + HH(aa, bb, cc, dd, ee, block[ 4], 7); + HH(ee, aa, bb, cc, dd, block[ 9], 14); + HH(dd, ee, aa, bb, cc, block[15], 9); + HH(cc, dd, ee, aa, bb, block[ 8], 13); + HH(bb, cc, dd, ee, aa, block[ 1], 15); + HH(aa, bb, cc, dd, ee, block[ 2], 14); + HH(ee, aa, bb, cc, dd, block[ 7], 8); + HH(dd, ee, aa, bb, cc, block[ 0], 13); + HH(cc, dd, ee, aa, bb, block[ 6], 6); + HH(bb, cc, dd, ee, aa, block[13], 5); + HH(aa, bb, cc, dd, ee, block[11], 12); + HH(ee, aa, bb, cc, dd, block[ 5], 7); + HH(dd, ee, aa, bb, cc, block[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, block[ 1], 11); + II(bb, cc, dd, ee, aa, block[ 9], 12); + II(aa, bb, cc, dd, ee, block[11], 14); + II(ee, aa, bb, cc, dd, block[10], 15); + II(dd, ee, aa, bb, cc, block[ 0], 14); + II(cc, dd, ee, aa, bb, block[ 8], 15); + II(bb, cc, dd, ee, aa, block[12], 9); + II(aa, bb, cc, dd, ee, block[ 4], 8); + II(ee, aa, bb, cc, dd, block[13], 9); + II(dd, ee, aa, bb, cc, block[ 3], 14); + II(cc, dd, ee, aa, bb, block[ 7], 5); + II(bb, cc, dd, ee, aa, block[15], 6); + II(aa, bb, cc, dd, ee, block[14], 8); + II(ee, aa, bb, cc, dd, block[ 5], 6); + II(dd, ee, aa, bb, cc, block[ 6], 5); + II(cc, dd, ee, aa, bb, block[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, block[ 4], 9); + JJ(aa, bb, cc, dd, ee, block[ 0], 15); + JJ(ee, aa, bb, cc, dd, block[ 5], 5); + JJ(dd, ee, aa, bb, cc, block[ 9], 11); + JJ(cc, dd, ee, aa, bb, block[ 7], 6); + JJ(bb, cc, dd, ee, aa, block[12], 8); + JJ(aa, bb, cc, dd, ee, block[ 2], 13); + JJ(ee, aa, bb, cc, dd, block[10], 12); + JJ(dd, ee, aa, bb, cc, block[14], 5); + JJ(cc, dd, ee, aa, bb, block[ 1], 12); + JJ(bb, cc, dd, ee, aa, block[ 3], 13); + JJ(aa, bb, cc, dd, ee, block[ 8], 14); + JJ(ee, aa, bb, cc, dd, block[11], 11); + JJ(dd, ee, aa, bb, cc, block[ 6], 8); + JJ(cc, dd, ee, aa, bb, block[15], 5); + JJ(bb, cc, dd, ee, aa, block[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, block[11], 13); + III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, block[13], 8); + III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, block[10], 11); + III(bbb, ccc, ddd, eee, aaa, block[14], 7); + III(aaa, bbb, ccc, ddd, eee, block[15], 7); + III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, block[12], 7); + III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); + + /* combine results */ + ddd += cc + state[1]; /* final result for state[0] */ + state[1] = state[2] + dd + eee; + state[2] = state[3] + ee + aaa; + state[3] = state[4] + aa + bbb; + state[4] = state[0] + bb + ccc; + state[0] = ddd; } /********************************************************************/ @@ -352,26 +352,26 @@ RMD160_Transform(uint32_t state[5], const uint32_t block[16]) void RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) { - uint32_t X[16]; - uint32_t ofs = 0; - uint32_t i; + uint32_t X[16]; + uint32_t ofs = 0; + uint32_t i; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(context != NULL); - _DIAGASSERT(data != NULL); + _DIAGASSERT(context != NULL); + _DIAGASSERT(data != NULL); - /* update length[] */ + /* update length[] */ #if SIZEOF_SIZE_T * CHAR_BIT > 32 - context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); + context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); #else - if (context->length[0] + nbytes < context->length[0]) - context->length[1]++; /* overflow to msb of length */ + if (context->length[0] + nbytes < context->length[0]) + context->length[1]++; /* overflow to msb of length */ #endif - context->length[0] += (uint32_t)nbytes; + context->length[0] += (uint32_t)nbytes; - (void)memset(X, 0, sizeof(X)); + (void)memset(X, 0, sizeof(X)); if ( context->buflen + nbytes < 64 ) { @@ -416,48 +416,48 @@ RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) int RMD160_Finish(RMD160_CTX *context, uint8_t digest[20]) { - uint32_t i; - uint32_t X[16]; + uint32_t i; + uint32_t X[16]; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(digest != NULL); - _DIAGASSERT(context != NULL); + _DIAGASSERT(digest != NULL); + _DIAGASSERT(context != NULL); - /* append the bit m_n == 1 */ - context->bbuffer[context->buflen] = (uint8_t)'\200'; + /* append the bit m_n == 1 */ + context->bbuffer[context->buflen] = (uint8_t)'\200'; - (void)memset(context->bbuffer + context->buflen + 1, 0, - 63 - context->buflen); + (void)memset(context->bbuffer + context->buflen + 1, 0, + 63 - context->buflen); #ifndef WORDS_BIGENDIAN - (void)memcpy(X, context->bbuffer, sizeof(X)); + (void)memcpy(X, context->bbuffer, sizeof(X)); #else - for (j=0; j < 16; j++) - X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); + for (j=0; j < 16; j++) + X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); #endif - if ((context->buflen) > 55) { - /* length goes to next block */ - RMD160_Transform(context->state, X); - (void)memset(X, 0, sizeof(X)); - } - - /* append length in bits */ - X[14] = context->length[0] << 3; - X[15] = (context->length[0] >> 29) | - (context->length[1] << 3); - RMD160_Transform(context->state, X); - - if (digest != NULL) { - for (i = 0; i < 20; i += 4) { - /* extracts the 8 least significant bits. */ - digest[i] = context->state[i>>2]; - digest[i + 1] = (context->state[i>>2] >> 8); - digest[i + 2] = (context->state[i>>2] >> 16); - digest[i + 3] = (context->state[i>>2] >> 24); - } - } - return 1; + if ((context->buflen) > 55) { + /* length goes to next block */ + RMD160_Transform(context->state, X); + (void)memset(X, 0, sizeof(X)); + } + + /* append length in bits */ + X[14] = context->length[0] << 3; + X[15] = (context->length[0] >> 29) | + (context->length[1] << 3); + RMD160_Transform(context->state, X); + + if (digest != NULL) { + for (i = 0; i < 20; i += 4) { + /* extracts the 8 least significant bits. */ + digest[i] = context->state[i>>2]; + digest[i + 1] = (context->state[i>>2] >> 8); + digest[i + 2] = (context->state[i>>2] >> 16); + digest[i + 3] = (context->state[i>>2] >> 24); + } + } + return 1; } /************************ end of file rmd160.c **********************/ diff --git a/ext/digest/rmd160/rmd160.h b/ext/digest/rmd160/rmd160.h index 6324709d9602f2..617b262d906753 100644 --- a/ext/digest/rmd160/rmd160.h +++ b/ext/digest/rmd160/rmd160.h @@ -29,10 +29,10 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; /* state (ABCDE) */ - uint32_t length[2]; /* number of bits */ - uint8_t bbuffer[64]; /* overflow buffer */ - uint32_t buflen; /* number of chars in bbuffer */ + uint32_t state[5]; /* state (ABCDE) */ + uint32_t length[2]; /* number of bits */ + uint8_t bbuffer[64]; /* overflow buffer */ + uint32_t buflen; /* number of chars in bbuffer */ } RMD160_CTX; #ifdef RUBY diff --git a/ext/digest/sha1/sha1.c b/ext/digest/sha1/sha1.c index 53112275498795..afe952f8ba8c52 100644 --- a/ext/digest/sha1/sha1.c +++ b/ext/digest/sha1/sha1.c @@ -227,16 +227,16 @@ void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) j = context->count[0]; if ((context->count[0] += len << 3) < j) - context->count[1] += (len>>29)+1; + context->count[1] += (len>>29)+1; j = (j >> 3) & 63; if ((j + len) > 63) { - (void)memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1_Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) - SHA1_Transform(context->state, &data[i]); - j = 0; + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1_Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1_Transform(context->state, &data[i]); + j = 0; } else { - i = 0; + i = 0; } (void)memcpy(&context->buffer[j], &data[i], len - i); } @@ -254,18 +254,18 @@ int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) _DIAGASSERT(context != 0); for (i = 0; i < 8; i++) { - finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1_Update(context, (const uint8_t *)"\200", 1); while ((context->count[0] & 504) != 448) - SHA1_Update(context, (const uint8_t *)"\0", 1); + SHA1_Update(context, (const uint8_t *)"\0", 1); SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ if (digest) { - for (i = 0; i < 20; i++) - digest[i] = (uint8_t) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + for (i = 0; i < 20; i++) + digest[i] = (uint8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } return 1; } diff --git a/ext/digest/sha1/sha1.h b/ext/digest/sha1/sha1.h index 2accc46d465d00..e1d01b76ab14e0 100644 --- a/ext/digest/sha1/sha1.h +++ b/ext/digest/sha1/sha1.h @@ -14,9 +14,9 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; - uint32_t count[2]; - uint8_t buffer[64]; + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; } SHA1_CTX; #ifdef RUBY diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index 21d5acbe964287..2a9dbd4fce0cb1 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -136,17 +136,17 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ - ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ - (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ - ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ + ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ + (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ + ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ @@ -156,10 +156,10 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ * 64-bit words): */ #define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ } /* @@ -235,102 +235,102 @@ void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ static const sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ static const sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ static const sha2_word64 K512[80] = { - ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), - ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), - ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), - ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), - ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), - ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), - ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), - ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), - ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), - ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), - ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), - ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), - ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), - ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), - ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), - ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), - ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), - ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), - ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), - ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), - ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), - ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), - ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), - ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), - ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), - ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), - ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), - ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), - ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), - ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), - ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), - ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), - ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), - ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), - ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), - ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), - ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), - ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), - ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), - ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) + ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), + ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), + ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), + ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), + ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), + ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), + ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), + ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), + ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), + ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), + ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), + ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), + ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), + ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), + ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), + ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), + ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), + ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), + ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), + ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), + ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), + ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), + ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), + ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), + ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), + ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), + ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), + ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), + ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), + ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), + ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), + ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), + ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), + ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), + ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), + ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), + ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), + ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), + ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), + ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) }; /* Initial hash value H for SHA-384 */ static const sha2_word64 sha384_initial_hash_value[8] = { - ULL(0xcbbb9d5dc1059ed8), - ULL(0x629a292a367cd507), - ULL(0x9159015a3070dd17), - ULL(0x152fecd8f70e5939), - ULL(0x67332667ffc00b31), - ULL(0x8eb44a8768581511), - ULL(0xdb0c2e0d64f98fa7), - ULL(0x47b5481dbefa4fa4) + ULL(0xcbbb9d5dc1059ed8), + ULL(0x629a292a367cd507), + ULL(0x9159015a3070dd17), + ULL(0x152fecd8f70e5939), + ULL(0x67332667ffc00b31), + ULL(0x8eb44a8768581511), + ULL(0xdb0c2e0d64f98fa7), + ULL(0x47b5481dbefa4fa4) }; /* Initial hash value H for SHA-512 */ static const sha2_word64 sha512_initial_hash_value[8] = { - ULL(0x6a09e667f3bcc908), - ULL(0xbb67ae8584caa73b), - ULL(0x3c6ef372fe94f82b), - ULL(0xa54ff53a5f1d36f1), - ULL(0x510e527fade682d1), - ULL(0x9b05688c2b3e6c1f), - ULL(0x1f83d9abfb41bd6b), - ULL(0x5be0cd19137e2179) + ULL(0x6a09e667f3bcc908), + ULL(0xbb67ae8584caa73b), + ULL(0x3c6ef372fe94f82b), + ULL(0xa54ff53a5f1d36f1), + ULL(0x510e527fade682d1), + ULL(0x9b05688c2b3e6c1f), + ULL(0x1f83d9abfb41bd6b), + ULL(0x5be0cd19137e2179) }; /* @@ -342,13 +342,13 @@ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ int SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; - return 1; + if (context == (SHA256_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -358,328 +358,328 @@ int SHA256_Init(SHA256_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Copy data while converting to host byte order */ - REVERSE32(*data++,W256[j]); - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); - SHA256_Transform(context, (sha2_word32*)context->buffer); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); + SHA256_Transform(context, (sha2_word32*)context->buffer); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; } int SHA256_Final(sha2_byte digest[SHA256_DIGEST_LENGTH], SHA256_CTX* context) { - sha2_word32 *d = (sha2_word32*)digest; - unsigned int usedspace; + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - } - } else { - /* Set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, - sizeof(sha2_word64)); - - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, + sizeof(sha2_word64)); + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif - } + } - /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(*context)); - usedspace = 0; - return 1; + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); + usedspace = 0; + return 1; } char *SHA256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - if (buffer != (char*)0) { - SHA256_Final(digest, context); - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; + SHA256_CTX context; - SHA256_Init(&context); - SHA256_Update(&context, data, len); - return SHA256_End(&context, digest); + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ int SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA512_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -688,394 +688,394 @@ int SHA512_Init(SHA512_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - REVERSE64(*data++, W512[j]); - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); - SHA512_Transform(context, (sha2_word64*)context->buffer); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); + SHA512_Transform(context, (sha2_word64*)context->buffer); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { - unsigned int usedspace; + unsigned int usedspace; - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); - } - } else { - /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Store the length of input data (in bits): */ - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], - sizeof(sha2_word64)); - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], - sizeof(sha2_word64)); - - /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], + sizeof(sha2_word64)); + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], + sizeof(sha2_word64)); + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); } int SHA512_Final(sha2_byte digest[SHA512_DIGEST_LENGTH], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last(context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - if (buffer != (char*)0) { - SHA512_Final(digest, context); - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; + SHA512_CTX context; - SHA512_Init(&context); - SHA512_Update(&context, data, len); - return SHA512_End(&context, digest); + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ int SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA384_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); + SHA512_Update((SHA512_CTX*)context, data, len); } int SHA384_Final(sha2_byte digest[SHA384_DIGEST_LENGTH], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA384_End(SHA384_CTX* context, char buffer[SHA384_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - if (buffer != (char*)0) { - SHA384_Final(digest, context); - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; + SHA384_CTX context; - SHA384_Init(&context); - SHA384_Update(&context, data, len); - return SHA384_End(&context, digest); + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); } diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h index e58f15ae1297bd..c2a29b99ad5273 100644 --- a/ext/digest/sha2/sha2.h +++ b/ext/digest/sha2/sha2.h @@ -120,14 +120,14 @@ typedef unsigned long long uint64_t; /* 8-bytes (64-bits) */ * cc -DSHA2_USE_INTTYPES_H ... */ typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; typedef SHA512_CTX SHA384_CTX; From 39dc9f9093901d40d2998653948d5da38b18ee2c Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 30 Jul 2022 17:03:13 +0900 Subject: [PATCH 078/142] Revert "* expand tabs. [ci skip]" This reverts commit 8a65cf3b61c60e4cb886f59a73ff6db44364bfa9. --- ext/digest/md5/md5.c | 124 ++-- ext/digest/md5/md5.h | 4 +- ext/digest/rmd160/rmd160.c | 512 +++++++------- ext/digest/rmd160/rmd160.h | 8 +- ext/digest/sha1/sha1.c | 26 +- ext/digest/sha1/sha1.h | 6 +- ext/digest/sha2/sha2.c | 1374 ++++++++++++++++++------------------ ext/digest/sha2/sha2.h | 12 +- 8 files changed, 1033 insertions(+), 1033 deletions(-) diff --git a/ext/digest/md5/md5.c b/ext/digest/md5/md5.c index 52a787abdb20ff..3a7fe2cdad27b6 100644 --- a/ext/digest/md5/md5.c +++ b/ext/digest/md5/md5.c @@ -34,8 +34,8 @@ that follows (in reverse chronological order): 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; - made test program self-checking. + unsigned in ANSI C, signed in traditional"; + made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. @@ -64,32 +64,32 @@ int main(void) { static const char *const test[7*2] = { - "", "d41d8cd98f00b204e9800998ecf8427e", - "a", "0cc175b9c0f1b6a831c399e269772661", - "abc", "900150983cd24fb0d6963f7d28e17f72", - "message digest", "f96b697d7cb7938d525a2f31aaf161d0", - "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - "d174ab98d277d9f5a5611c2c9f419d9f", - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" + "", "d41d8cd98f00b204e9800998ecf8427e", + "a", "0cc175b9c0f1b6a831c399e269772661", + "abc", "900150983cd24fb0d6963f7d28e17f72", + "message digest", "f96b697d7cb7938d525a2f31aaf161d0", + "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "d174ab98d277d9f5a5611c2c9f419d9f", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" }; int i; for (i = 0; i < 7*2; i += 2) { - MD5_CTX state; - uint8_t digest[16]; - char hex_output[16*2 + 1]; - int di; - - MD5_Init(&state); - MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); - MD5_Final(digest, &state); - printf("MD5 (\"%s\") = ", test[i]); - for (di = 0; di < 16; ++di) - sprintf(hex_output + di * 2, "%02x", digest[di]); - puts(hex_output); - if (strcmp(hex_output, test[i + 1])) - printf("**** ERROR, should be: %s\n", test[i + 1]); + MD5_CTX state; + uint8_t digest[16]; + char hex_output[16*2 + 1]; + int di; + + MD5_Init(&state); + MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i])); + MD5_Final(digest, &state); + printf("MD5 (\"%s\") = ", test[i]); + for (di = 0; di < 16; ++di) + sprintf(hex_output + di * 2, "%02x", digest[di]); + puts(hex_output); + if (strcmp(hex_output, test[i + 1])) + printf("**** ERROR, should be: %s\n", test[i + 1]); } return 0; } @@ -106,18 +106,18 @@ main(void) { int i; for (i = 1; i <= 64; ++i) { - unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); - - /* - * The following nonsense is only to avoid compiler warnings about - * "integer constant is unsigned in ANSI C, signed with -traditional". - */ - if (v >> 31) { - printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, - v, (unsigned long)(unsigned int)(~v)); - } else { - printf("#define T%d 0x%08lx\n", i, v); - } + unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); + + /* + * The following nonsense is only to avoid compiler warnings about + * "integer constant is unsigned in ANSI C, signed with -traditional". + */ + if (v >> 31) { + printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, + v, (unsigned long)(unsigned int)(~v)); + } else { + printf("#define T%d 0x%08lx\n", i, v); + } } return 0; } @@ -199,8 +199,8 @@ static void md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) { uint32_t - a = pms->state[0], b = pms->state[1], - c = pms->state[2], d = pms->state[3]; + a = pms->state[0], b = pms->state[1], + c = pms->state[2], d = pms->state[3]; uint32_t t; #ifdef WORDS_BIGENDIAN @@ -214,7 +214,7 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) int i; for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); #else @@ -226,12 +226,12 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) const uint32_t *X; if (!(((uintptr_t)data) & 3)) { - /* data are properly aligned */ - X = (const uint32_t *)data; + /* data are properly aligned */ + X = (const uint32_t *)data; } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; } #endif @@ -370,55 +370,55 @@ MD5_Update(MD5_CTX *pms, const uint8_t *data, size_t nbytes) uint32_t nbits = (uint32_t)(nbytes << 3); if (nbytes == 0) - return; + return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) - pms->count[1]++; + pms->count[1]++; /* Process an initial partial block. */ if (offset) { - size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buffer + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buffer); + size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buffer + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buffer); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); + md5_process(pms, p); /* Process a final partial block. */ if (left) - memcpy(pms->buffer, p, left); + memcpy(pms->buffer, p, left); } int MD5_Finish(MD5_CTX *pms, uint8_t *digest) { static const uint8_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t data[8]; size_t i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) - data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ MD5_Update(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ MD5_Update(pms, data, 8); for (i = 0; i < 16; ++i) - digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); + digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3)); return 1; } diff --git a/ext/digest/md5/md5.h b/ext/digest/md5/md5.h index 0b04f9fc4eab58..1b3383c5eecde7 100644 --- a/ext/digest/md5/md5.h +++ b/ext/digest/md5/md5.h @@ -34,8 +34,8 @@ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . + added conditionalization for C++ compilation from Martin + Purschke . 1999-05-03 lpd Original version. */ diff --git a/ext/digest/rmd160/rmd160.c b/ext/digest/rmd160/rmd160.c index 0ea78dcd642d0a..058d004f3a672d 100644 --- a/ext/digest/rmd160/rmd160.c +++ b/ext/digest/rmd160/rmd160.c @@ -128,17 +128,17 @@ int RMD160_Init(RMD160_CTX *context) { - _DIAGASSERT(context != NULL); - - /* ripemd-160 initialization constants */ - context->state[0] = 0x67452301U; - context->state[1] = 0xefcdab89U; - context->state[2] = 0x98badcfeU; - context->state[3] = 0x10325476U; - context->state[4] = 0xc3d2e1f0U; - context->length[0] = context->length[1] = 0; - context->buflen = 0; - return 1; + _DIAGASSERT(context != NULL); + + /* ripemd-160 initialization constants */ + context->state[0] = 0x67452301U; + context->state[1] = 0xefcdab89U; + context->state[2] = 0x98badcfeU; + context->state[3] = 0x10325476U; + context->state[4] = 0xc3d2e1f0U; + context->length[0] = context->length[1] = 0; + context->buflen = 0; + return 1; } /********************************************************************/ @@ -146,205 +146,205 @@ RMD160_Init(RMD160_CTX *context) void RMD160_Transform(uint32_t state[5], const uint32_t block[16]) { - uint32_t aa, bb, cc, dd, ee; - uint32_t aaa, bbb, ccc, ddd, eee; - - _DIAGASSERT(state != NULL); - _DIAGASSERT(block != NULL); - - aa = aaa = state[0]; - bb = bbb = state[1]; - cc = ccc = state[2]; - dd = ddd = state[3]; - ee = eee = state[4]; - - /* round 1 */ - FF(aa, bb, cc, dd, ee, block[ 0], 11); - FF(ee, aa, bb, cc, dd, block[ 1], 14); - FF(dd, ee, aa, bb, cc, block[ 2], 15); - FF(cc, dd, ee, aa, bb, block[ 3], 12); - FF(bb, cc, dd, ee, aa, block[ 4], 5); - FF(aa, bb, cc, dd, ee, block[ 5], 8); - FF(ee, aa, bb, cc, dd, block[ 6], 7); - FF(dd, ee, aa, bb, cc, block[ 7], 9); - FF(cc, dd, ee, aa, bb, block[ 8], 11); - FF(bb, cc, dd, ee, aa, block[ 9], 13); - FF(aa, bb, cc, dd, ee, block[10], 14); - FF(ee, aa, bb, cc, dd, block[11], 15); - FF(dd, ee, aa, bb, cc, block[12], 6); - FF(cc, dd, ee, aa, bb, block[13], 7); - FF(bb, cc, dd, ee, aa, block[14], 9); - FF(aa, bb, cc, dd, ee, block[15], 8); - - /* round 2 */ - GG(ee, aa, bb, cc, dd, block[ 7], 7); - GG(dd, ee, aa, bb, cc, block[ 4], 6); - GG(cc, dd, ee, aa, bb, block[13], 8); - GG(bb, cc, dd, ee, aa, block[ 1], 13); - GG(aa, bb, cc, dd, ee, block[10], 11); - GG(ee, aa, bb, cc, dd, block[ 6], 9); - GG(dd, ee, aa, bb, cc, block[15], 7); - GG(cc, dd, ee, aa, bb, block[ 3], 15); - GG(bb, cc, dd, ee, aa, block[12], 7); - GG(aa, bb, cc, dd, ee, block[ 0], 12); - GG(ee, aa, bb, cc, dd, block[ 9], 15); - GG(dd, ee, aa, bb, cc, block[ 5], 9); - GG(cc, dd, ee, aa, bb, block[ 2], 11); - GG(bb, cc, dd, ee, aa, block[14], 7); - GG(aa, bb, cc, dd, ee, block[11], 13); - GG(ee, aa, bb, cc, dd, block[ 8], 12); - - /* round 3 */ - HH(dd, ee, aa, bb, cc, block[ 3], 11); - HH(cc, dd, ee, aa, bb, block[10], 13); - HH(bb, cc, dd, ee, aa, block[14], 6); - HH(aa, bb, cc, dd, ee, block[ 4], 7); - HH(ee, aa, bb, cc, dd, block[ 9], 14); - HH(dd, ee, aa, bb, cc, block[15], 9); - HH(cc, dd, ee, aa, bb, block[ 8], 13); - HH(bb, cc, dd, ee, aa, block[ 1], 15); - HH(aa, bb, cc, dd, ee, block[ 2], 14); - HH(ee, aa, bb, cc, dd, block[ 7], 8); - HH(dd, ee, aa, bb, cc, block[ 0], 13); - HH(cc, dd, ee, aa, bb, block[ 6], 6); - HH(bb, cc, dd, ee, aa, block[13], 5); - HH(aa, bb, cc, dd, ee, block[11], 12); - HH(ee, aa, bb, cc, dd, block[ 5], 7); - HH(dd, ee, aa, bb, cc, block[12], 5); - - /* round 4 */ - II(cc, dd, ee, aa, bb, block[ 1], 11); - II(bb, cc, dd, ee, aa, block[ 9], 12); - II(aa, bb, cc, dd, ee, block[11], 14); - II(ee, aa, bb, cc, dd, block[10], 15); - II(dd, ee, aa, bb, cc, block[ 0], 14); - II(cc, dd, ee, aa, bb, block[ 8], 15); - II(bb, cc, dd, ee, aa, block[12], 9); - II(aa, bb, cc, dd, ee, block[ 4], 8); - II(ee, aa, bb, cc, dd, block[13], 9); - II(dd, ee, aa, bb, cc, block[ 3], 14); - II(cc, dd, ee, aa, bb, block[ 7], 5); - II(bb, cc, dd, ee, aa, block[15], 6); - II(aa, bb, cc, dd, ee, block[14], 8); - II(ee, aa, bb, cc, dd, block[ 5], 6); - II(dd, ee, aa, bb, cc, block[ 6], 5); - II(cc, dd, ee, aa, bb, block[ 2], 12); - - /* round 5 */ - JJ(bb, cc, dd, ee, aa, block[ 4], 9); - JJ(aa, bb, cc, dd, ee, block[ 0], 15); - JJ(ee, aa, bb, cc, dd, block[ 5], 5); - JJ(dd, ee, aa, bb, cc, block[ 9], 11); - JJ(cc, dd, ee, aa, bb, block[ 7], 6); - JJ(bb, cc, dd, ee, aa, block[12], 8); - JJ(aa, bb, cc, dd, ee, block[ 2], 13); - JJ(ee, aa, bb, cc, dd, block[10], 12); - JJ(dd, ee, aa, bb, cc, block[14], 5); - JJ(cc, dd, ee, aa, bb, block[ 1], 12); - JJ(bb, cc, dd, ee, aa, block[ 3], 13); - JJ(aa, bb, cc, dd, ee, block[ 8], 14); - JJ(ee, aa, bb, cc, dd, block[11], 11); - JJ(dd, ee, aa, bb, cc, block[ 6], 8); - JJ(cc, dd, ee, aa, bb, block[15], 5); - JJ(bb, cc, dd, ee, aa, block[13], 6); - - /* parallel round 1 */ - JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); - JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); - JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); - JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); - JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); - JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); - JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); - JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); - JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); - JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); - JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); - - /* parallel round 2 */ - III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); - III(ddd, eee, aaa, bbb, ccc, block[11], 13); - III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); - III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); - III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); - III(eee, aaa, bbb, ccc, ddd, block[13], 8); - III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); - III(ccc, ddd, eee, aaa, bbb, block[10], 11); - III(bbb, ccc, ddd, eee, aaa, block[14], 7); - III(aaa, bbb, ccc, ddd, eee, block[15], 7); - III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); - III(ddd, eee, aaa, bbb, ccc, block[12], 7); - III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); - III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); - III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); - III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); - - /* parallel round 3 */ - HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); - HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); - HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); - HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); - HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); - HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); - HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); - HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); - HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); - HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); - HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); - HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); - HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); - HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); - HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); - HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); - - /* parallel round 4 */ - GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); - GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); - GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); - GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); - GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); - GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); - GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); - GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); - GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); - GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); - GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); - GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); - GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); - GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); - GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); - GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); - - /* parallel round 5 */ - FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); - FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); - FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); - FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); - FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); - FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); - FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); - FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); - FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); - FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); - FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); - FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); - FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); - FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); - FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); - - /* combine results */ - ddd += cc + state[1]; /* final result for state[0] */ - state[1] = state[2] + dd + eee; - state[2] = state[3] + ee + aaa; - state[3] = state[4] + aa + bbb; - state[4] = state[0] + bb + ccc; - state[0] = ddd; + uint32_t aa, bb, cc, dd, ee; + uint32_t aaa, bbb, ccc, ddd, eee; + + _DIAGASSERT(state != NULL); + _DIAGASSERT(block != NULL); + + aa = aaa = state[0]; + bb = bbb = state[1]; + cc = ccc = state[2]; + dd = ddd = state[3]; + ee = eee = state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, block[ 0], 11); + FF(ee, aa, bb, cc, dd, block[ 1], 14); + FF(dd, ee, aa, bb, cc, block[ 2], 15); + FF(cc, dd, ee, aa, bb, block[ 3], 12); + FF(bb, cc, dd, ee, aa, block[ 4], 5); + FF(aa, bb, cc, dd, ee, block[ 5], 8); + FF(ee, aa, bb, cc, dd, block[ 6], 7); + FF(dd, ee, aa, bb, cc, block[ 7], 9); + FF(cc, dd, ee, aa, bb, block[ 8], 11); + FF(bb, cc, dd, ee, aa, block[ 9], 13); + FF(aa, bb, cc, dd, ee, block[10], 14); + FF(ee, aa, bb, cc, dd, block[11], 15); + FF(dd, ee, aa, bb, cc, block[12], 6); + FF(cc, dd, ee, aa, bb, block[13], 7); + FF(bb, cc, dd, ee, aa, block[14], 9); + FF(aa, bb, cc, dd, ee, block[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, block[ 7], 7); + GG(dd, ee, aa, bb, cc, block[ 4], 6); + GG(cc, dd, ee, aa, bb, block[13], 8); + GG(bb, cc, dd, ee, aa, block[ 1], 13); + GG(aa, bb, cc, dd, ee, block[10], 11); + GG(ee, aa, bb, cc, dd, block[ 6], 9); + GG(dd, ee, aa, bb, cc, block[15], 7); + GG(cc, dd, ee, aa, bb, block[ 3], 15); + GG(bb, cc, dd, ee, aa, block[12], 7); + GG(aa, bb, cc, dd, ee, block[ 0], 12); + GG(ee, aa, bb, cc, dd, block[ 9], 15); + GG(dd, ee, aa, bb, cc, block[ 5], 9); + GG(cc, dd, ee, aa, bb, block[ 2], 11); + GG(bb, cc, dd, ee, aa, block[14], 7); + GG(aa, bb, cc, dd, ee, block[11], 13); + GG(ee, aa, bb, cc, dd, block[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, block[ 3], 11); + HH(cc, dd, ee, aa, bb, block[10], 13); + HH(bb, cc, dd, ee, aa, block[14], 6); + HH(aa, bb, cc, dd, ee, block[ 4], 7); + HH(ee, aa, bb, cc, dd, block[ 9], 14); + HH(dd, ee, aa, bb, cc, block[15], 9); + HH(cc, dd, ee, aa, bb, block[ 8], 13); + HH(bb, cc, dd, ee, aa, block[ 1], 15); + HH(aa, bb, cc, dd, ee, block[ 2], 14); + HH(ee, aa, bb, cc, dd, block[ 7], 8); + HH(dd, ee, aa, bb, cc, block[ 0], 13); + HH(cc, dd, ee, aa, bb, block[ 6], 6); + HH(bb, cc, dd, ee, aa, block[13], 5); + HH(aa, bb, cc, dd, ee, block[11], 12); + HH(ee, aa, bb, cc, dd, block[ 5], 7); + HH(dd, ee, aa, bb, cc, block[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, block[ 1], 11); + II(bb, cc, dd, ee, aa, block[ 9], 12); + II(aa, bb, cc, dd, ee, block[11], 14); + II(ee, aa, bb, cc, dd, block[10], 15); + II(dd, ee, aa, bb, cc, block[ 0], 14); + II(cc, dd, ee, aa, bb, block[ 8], 15); + II(bb, cc, dd, ee, aa, block[12], 9); + II(aa, bb, cc, dd, ee, block[ 4], 8); + II(ee, aa, bb, cc, dd, block[13], 9); + II(dd, ee, aa, bb, cc, block[ 3], 14); + II(cc, dd, ee, aa, bb, block[ 7], 5); + II(bb, cc, dd, ee, aa, block[15], 6); + II(aa, bb, cc, dd, ee, block[14], 8); + II(ee, aa, bb, cc, dd, block[ 5], 6); + II(dd, ee, aa, bb, cc, block[ 6], 5); + II(cc, dd, ee, aa, bb, block[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, block[ 4], 9); + JJ(aa, bb, cc, dd, ee, block[ 0], 15); + JJ(ee, aa, bb, cc, dd, block[ 5], 5); + JJ(dd, ee, aa, bb, cc, block[ 9], 11); + JJ(cc, dd, ee, aa, bb, block[ 7], 6); + JJ(bb, cc, dd, ee, aa, block[12], 8); + JJ(aa, bb, cc, dd, ee, block[ 2], 13); + JJ(ee, aa, bb, cc, dd, block[10], 12); + JJ(dd, ee, aa, bb, cc, block[14], 5); + JJ(cc, dd, ee, aa, bb, block[ 1], 12); + JJ(bb, cc, dd, ee, aa, block[ 3], 13); + JJ(aa, bb, cc, dd, ee, block[ 8], 14); + JJ(ee, aa, bb, cc, dd, block[11], 11); + JJ(dd, ee, aa, bb, cc, block[ 6], 8); + JJ(cc, dd, ee, aa, bb, block[15], 5); + JJ(bb, cc, dd, ee, aa, block[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, block[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, block[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, block[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, block[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, block[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, block[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, block[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, block[11], 13); + III(ccc, ddd, eee, aaa, bbb, block[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, block[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, block[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, block[13], 8); + III(ddd, eee, aaa, bbb, ccc, block[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, block[10], 11); + III(bbb, ccc, ddd, eee, aaa, block[14], 7); + III(aaa, bbb, ccc, ddd, eee, block[15], 7); + III(eee, aaa, bbb, ccc, ddd, block[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, block[12], 7); + III(ccc, ddd, eee, aaa, bbb, block[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, block[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, block[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, block[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, block[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, block[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, block[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, block[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, block[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, block[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, block[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, block[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, block[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, block[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, block[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, block[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, block[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, block[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, block[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, block[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, block[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, block[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, block[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, block[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, block[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, block[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, block[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, block[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, block[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, block[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, block[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, block[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, block[11] , 11); + + /* combine results */ + ddd += cc + state[1]; /* final result for state[0] */ + state[1] = state[2] + dd + eee; + state[2] = state[3] + ee + aaa; + state[3] = state[4] + aa + bbb; + state[4] = state[0] + bb + ccc; + state[0] = ddd; } /********************************************************************/ @@ -352,26 +352,26 @@ RMD160_Transform(uint32_t state[5], const uint32_t block[16]) void RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) { - uint32_t X[16]; - uint32_t ofs = 0; - uint32_t i; + uint32_t X[16]; + uint32_t ofs = 0; + uint32_t i; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(context != NULL); - _DIAGASSERT(data != NULL); + _DIAGASSERT(context != NULL); + _DIAGASSERT(data != NULL); - /* update length[] */ + /* update length[] */ #if SIZEOF_SIZE_T * CHAR_BIT > 32 - context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); + context->length[1] += (uint32_t)((context->length[0] + nbytes) >> 32); #else - if (context->length[0] + nbytes < context->length[0]) - context->length[1]++; /* overflow to msb of length */ + if (context->length[0] + nbytes < context->length[0]) + context->length[1]++; /* overflow to msb of length */ #endif - context->length[0] += (uint32_t)nbytes; + context->length[0] += (uint32_t)nbytes; - (void)memset(X, 0, sizeof(X)); + (void)memset(X, 0, sizeof(X)); if ( context->buflen + nbytes < 64 ) { @@ -416,48 +416,48 @@ RMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes) int RMD160_Finish(RMD160_CTX *context, uint8_t digest[20]) { - uint32_t i; - uint32_t X[16]; + uint32_t i; + uint32_t X[16]; #ifdef WORDS_BIGENDIAN - uint32_t j; + uint32_t j; #endif - _DIAGASSERT(digest != NULL); - _DIAGASSERT(context != NULL); + _DIAGASSERT(digest != NULL); + _DIAGASSERT(context != NULL); - /* append the bit m_n == 1 */ - context->bbuffer[context->buflen] = (uint8_t)'\200'; + /* append the bit m_n == 1 */ + context->bbuffer[context->buflen] = (uint8_t)'\200'; - (void)memset(context->bbuffer + context->buflen + 1, 0, - 63 - context->buflen); + (void)memset(context->bbuffer + context->buflen + 1, 0, + 63 - context->buflen); #ifndef WORDS_BIGENDIAN - (void)memcpy(X, context->bbuffer, sizeof(X)); + (void)memcpy(X, context->bbuffer, sizeof(X)); #else - for (j=0; j < 16; j++) - X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); + for (j=0; j < 16; j++) + X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j)); #endif - if ((context->buflen) > 55) { - /* length goes to next block */ - RMD160_Transform(context->state, X); - (void)memset(X, 0, sizeof(X)); - } - - /* append length in bits */ - X[14] = context->length[0] << 3; - X[15] = (context->length[0] >> 29) | - (context->length[1] << 3); - RMD160_Transform(context->state, X); - - if (digest != NULL) { - for (i = 0; i < 20; i += 4) { - /* extracts the 8 least significant bits. */ - digest[i] = context->state[i>>2]; - digest[i + 1] = (context->state[i>>2] >> 8); - digest[i + 2] = (context->state[i>>2] >> 16); - digest[i + 3] = (context->state[i>>2] >> 24); - } - } - return 1; + if ((context->buflen) > 55) { + /* length goes to next block */ + RMD160_Transform(context->state, X); + (void)memset(X, 0, sizeof(X)); + } + + /* append length in bits */ + X[14] = context->length[0] << 3; + X[15] = (context->length[0] >> 29) | + (context->length[1] << 3); + RMD160_Transform(context->state, X); + + if (digest != NULL) { + for (i = 0; i < 20; i += 4) { + /* extracts the 8 least significant bits. */ + digest[i] = context->state[i>>2]; + digest[i + 1] = (context->state[i>>2] >> 8); + digest[i + 2] = (context->state[i>>2] >> 16); + digest[i + 3] = (context->state[i>>2] >> 24); + } + } + return 1; } /************************ end of file rmd160.c **********************/ diff --git a/ext/digest/rmd160/rmd160.h b/ext/digest/rmd160/rmd160.h index 617b262d906753..6324709d9602f2 100644 --- a/ext/digest/rmd160/rmd160.h +++ b/ext/digest/rmd160/rmd160.h @@ -29,10 +29,10 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; /* state (ABCDE) */ - uint32_t length[2]; /* number of bits */ - uint8_t bbuffer[64]; /* overflow buffer */ - uint32_t buflen; /* number of chars in bbuffer */ + uint32_t state[5]; /* state (ABCDE) */ + uint32_t length[2]; /* number of bits */ + uint8_t bbuffer[64]; /* overflow buffer */ + uint32_t buflen; /* number of chars in bbuffer */ } RMD160_CTX; #ifdef RUBY diff --git a/ext/digest/sha1/sha1.c b/ext/digest/sha1/sha1.c index afe952f8ba8c52..53112275498795 100644 --- a/ext/digest/sha1/sha1.c +++ b/ext/digest/sha1/sha1.c @@ -227,16 +227,16 @@ void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) j = context->count[0]; if ((context->count[0] += len << 3) < j) - context->count[1] += (len>>29)+1; + context->count[1] += (len>>29)+1; j = (j >> 3) & 63; if ((j + len) > 63) { - (void)memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1_Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) - SHA1_Transform(context->state, &data[i]); - j = 0; + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1_Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1_Transform(context->state, &data[i]); + j = 0; } else { - i = 0; + i = 0; } (void)memcpy(&context->buffer[j], &data[i], len - i); } @@ -254,18 +254,18 @@ int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) _DIAGASSERT(context != 0); for (i = 0; i < 8; i++) { - finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1_Update(context, (const uint8_t *)"\200", 1); while ((context->count[0] & 504) != 448) - SHA1_Update(context, (const uint8_t *)"\0", 1); + SHA1_Update(context, (const uint8_t *)"\0", 1); SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ if (digest) { - for (i = 0; i < 20; i++) - digest[i] = (uint8_t) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + for (i = 0; i < 20; i++) + digest[i] = (uint8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } return 1; } diff --git a/ext/digest/sha1/sha1.h b/ext/digest/sha1/sha1.h index e1d01b76ab14e0..2accc46d465d00 100644 --- a/ext/digest/sha1/sha1.h +++ b/ext/digest/sha1/sha1.h @@ -14,9 +14,9 @@ #include "../defs.h" typedef struct { - uint32_t state[5]; - uint32_t count[2]; - uint8_t buffer[64]; + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; } SHA1_CTX; #ifdef RUBY diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index 2a9dbd4fce0cb1..21d5acbe964287 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -136,17 +136,17 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & (sha2_word32)0xff00ff00UL) >> 8) | ((tmp & (sha2_word32)0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ - ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ - (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ - ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \ + ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \ + (x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \ + ((tmp & ULL(0x0000ffff0000ffff)) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ @@ -156,10 +156,10 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ * 64-bit words): */ #define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ } /* @@ -235,102 +235,102 @@ void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ static const sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ static const sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ static const sha2_word64 K512[80] = { - ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), - ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), - ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), - ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), - ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), - ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), - ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), - ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), - ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), - ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), - ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), - ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), - ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), - ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), - ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), - ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), - ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), - ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), - ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), - ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), - ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), - ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), - ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), - ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), - ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), - ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), - ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), - ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), - ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), - ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), - ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), - ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), - ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), - ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), - ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), - ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), - ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), - ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), - ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), - ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) + ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), + ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), + ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), + ULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118), + ULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe), + ULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2), + ULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1), + ULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694), + ULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3), + ULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65), + ULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483), + ULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5), + ULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210), + ULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4), + ULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725), + ULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70), + ULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926), + ULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df), + ULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8), + ULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b), + ULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001), + ULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30), + ULL(0xd192e819d6ef5218), ULL(0xd69906245565a910), + ULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8), + ULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53), + ULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8), + ULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb), + ULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3), + ULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60), + ULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec), + ULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9), + ULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b), + ULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207), + ULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178), + ULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6), + ULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b), + ULL(0x28db77f523047d84), ULL(0x32caab7b40c72493), + ULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c), + ULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a), + ULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817) }; /* Initial hash value H for SHA-384 */ static const sha2_word64 sha384_initial_hash_value[8] = { - ULL(0xcbbb9d5dc1059ed8), - ULL(0x629a292a367cd507), - ULL(0x9159015a3070dd17), - ULL(0x152fecd8f70e5939), - ULL(0x67332667ffc00b31), - ULL(0x8eb44a8768581511), - ULL(0xdb0c2e0d64f98fa7), - ULL(0x47b5481dbefa4fa4) + ULL(0xcbbb9d5dc1059ed8), + ULL(0x629a292a367cd507), + ULL(0x9159015a3070dd17), + ULL(0x152fecd8f70e5939), + ULL(0x67332667ffc00b31), + ULL(0x8eb44a8768581511), + ULL(0xdb0c2e0d64f98fa7), + ULL(0x47b5481dbefa4fa4) }; /* Initial hash value H for SHA-512 */ static const sha2_word64 sha512_initial_hash_value[8] = { - ULL(0x6a09e667f3bcc908), - ULL(0xbb67ae8584caa73b), - ULL(0x3c6ef372fe94f82b), - ULL(0xa54ff53a5f1d36f1), - ULL(0x510e527fade682d1), - ULL(0x9b05688c2b3e6c1f), - ULL(0x1f83d9abfb41bd6b), - ULL(0x5be0cd19137e2179) + ULL(0x6a09e667f3bcc908), + ULL(0xbb67ae8584caa73b), + ULL(0x3c6ef372fe94f82b), + ULL(0xa54ff53a5f1d36f1), + ULL(0x510e527fade682d1), + ULL(0x9b05688c2b3e6c1f), + ULL(0x1f83d9abfb41bd6b), + ULL(0x5be0cd19137e2179) }; /* @@ -342,13 +342,13 @@ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ int SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; - return 1; + if (context == (SHA256_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -358,328 +358,328 @@ int SHA256_Init(SHA256_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Copy data while converting to host byte order */ - REVERSE32(*data++,W256[j]); - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); - SHA256_Transform(context, (sha2_word32*)context->buffer); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); + SHA256_Transform(context, (sha2_word32*)context->buffer); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; } int SHA256_Final(sha2_byte digest[SHA256_DIGEST_LENGTH], SHA256_CTX* context) { - sha2_word32 *d = (sha2_word32*)digest; - unsigned int usedspace; + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - } - } else { - /* Set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, - sizeof(sha2_word64)); - - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, + sizeof(sha2_word64)); + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif - } + } - /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(*context)); - usedspace = 0; - return 1; + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); + usedspace = 0; + return 1; } char *SHA256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - if (buffer != (char*)0) { - SHA256_Final(digest, context); - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; + SHA256_CTX context; - SHA256_Init(&context); - SHA256_Update(&context, data, len); - return SHA256_End(&context, digest); + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ int SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA512_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } #ifdef SHA2_UNROLL_TRANSFORM @@ -688,394 +688,394 @@ int SHA512_Init(SHA512_CTX* context) { #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - REVERSE64(*data++, W512[j]); - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); - SHA512_Transform(context, (sha2_word64*)context->buffer); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); + SHA512_Transform(context, (sha2_word64*)context->buffer); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { - unsigned int usedspace; + unsigned int usedspace; - usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); - } - } else { - /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Store the length of input data (in bits): */ - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], - sizeof(sha2_word64)); - MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], - sizeof(sha2_word64)); - - /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], + sizeof(sha2_word64)); + MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], + sizeof(sha2_word64)); + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); } int SHA512_Final(sha2_byte digest[SHA512_DIGEST_LENGTH], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last(context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - if (buffer != (char*)0) { - SHA512_Final(digest, context); - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; + SHA512_CTX context; - SHA512_Init(&context); - SHA512_Update(&context, data, len); - return SHA512_End(&context, digest); + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ int SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return 0; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; - return 1; + if (context == (SHA384_CTX*)0) { + return 0; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; + return 1; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); + SHA512_Update((SHA512_CTX*)context, data, len); } int SHA384_Final(sha2_byte digest[SHA384_DIGEST_LENGTH], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; + sha2_word64 *d = (sha2_word64*)digest; - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } #else - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif - } + } - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); - return 1; + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(*context)); + return 1; } char *SHA384_End(SHA384_CTX* context, char buffer[SHA384_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - if (buffer != (char*)0) { - SHA384_Final(digest, context); - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); - return buffer; + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; + SHA384_CTX context; - SHA384_Init(&context); - SHA384_Update(&context, data, len); - return SHA384_End(&context, digest); + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); } diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h index c2a29b99ad5273..e58f15ae1297bd 100644 --- a/ext/digest/sha2/sha2.h +++ b/ext/digest/sha2/sha2.h @@ -120,14 +120,14 @@ typedef unsigned long long uint64_t; /* 8-bytes (64-bits) */ * cc -DSHA2_USE_INTTYPES_H ... */ typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; typedef SHA512_CTX SHA384_CTX; From 1bebf215703fdce21e616ffaab016ccba4479765 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 17:13:00 +0900 Subject: [PATCH 079/142] Update .git-blame-ignore-revs [ci skip] --- .git-blame-ignore-revs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 87f33d7045c0a7..fc5d2693356011 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -8,3 +8,8 @@ # Enable Style/StringLiterals cop for RubyGems/Bundler d7ffd3fea402239b16833cc434404a7af82d44f3 + +# [ruby/digest] Revert tab-expansion in external files +48b09aae7ec5632209229dcc294dd0d75a93a17f +8a65cf3b61c60e4cb886f59a73ff6db44364bfa9 +39dc9f9093901d40d2998653948d5da38b18ee2c From f28287d34c03f472ffe90ea262bdde9affd4b965 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 17:24:43 +0900 Subject: [PATCH 080/142] [ruby/io-nonblock] Revert tab expansion --- ext/io/nonblock/nonblock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c index cbd43d993a60ff..b8a40ff38e94a2 100644 --- a/ext/io/nonblock/nonblock.c +++ b/ext/io/nonblock/nonblock.c @@ -42,7 +42,7 @@ rb_io_nonblock_p(VALUE io) rb_io_t *fptr; GetOpenFile(io, fptr); if (get_fcntl_flags(fptr->fd) & O_NONBLOCK) - return Qtrue; + return Qtrue; return Qfalse; } #else @@ -54,21 +54,21 @@ static void set_fcntl_flags(int fd, int f) { if (fcntl(fd, F_SETFL, f) == -1) - rb_sys_fail(0); + rb_sys_fail(0); } static int io_nonblock_set(int fd, int f, int nb) { if (nb) { - if ((f & O_NONBLOCK) != 0) - return 0; - f |= O_NONBLOCK; + if ((f & O_NONBLOCK) != 0) + return 0; + f |= O_NONBLOCK; } else { - if ((f & O_NONBLOCK) == 0) - return 0; - f &= ~O_NONBLOCK; + if ((f & O_NONBLOCK) == 0) + return 0; + f &= ~O_NONBLOCK; } set_fcntl_flags(fd, f); return 1; @@ -127,9 +127,9 @@ rb_io_nonblock_set(VALUE io, VALUE nb) rb_io_t *fptr; GetOpenFile(io, fptr); if (RTEST(nb)) - rb_io_set_nonblock(fptr); + rb_io_set_nonblock(fptr); else - io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); + io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); return io; } @@ -160,15 +160,15 @@ rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) GetOpenFile(io, fptr); if (argc > 0) { - VALUE v; - rb_scan_args(argc, argv, "01", &v); - nb = RTEST(v); + VALUE v; + rb_scan_args(argc, argv, "01", &v); + nb = RTEST(v); } f = get_fcntl_flags(fptr->fd); restore[0] = fptr->fd; restore[1] = f; if (!io_nonblock_set(fptr->fd, f, nb)) - return rb_yield(io); + return rb_yield(io); return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore); } #else From c258fb2775020ad5b851deef3da8d5591728f535 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 17:26:22 +0900 Subject: [PATCH 081/142] Update .git-blame-ignore-revs [ci skip] --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index fc5d2693356011..209aa9693a5bc9 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -13,3 +13,6 @@ d7ffd3fea402239b16833cc434404a7af82d44f3 48b09aae7ec5632209229dcc294dd0d75a93a17f 8a65cf3b61c60e4cb886f59a73ff6db44364bfa9 39dc9f9093901d40d2998653948d5da38b18ee2c + +# [ruby/io-nonblock] Revert tab expansion +f28287d34c03f472ffe90ea262bdde9affd4b965 From 0d842fecb4f75ab3b1d4097ebdb8e88f51558041 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 30 Jul 2022 17:26:37 +0900 Subject: [PATCH 082/142] * expand tabs. [ci skip] Tabs were expanded because the file did not have any tab indentation in unedited lines. Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook. --- ext/io/nonblock/nonblock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c index b8a40ff38e94a2..cbd43d993a60ff 100644 --- a/ext/io/nonblock/nonblock.c +++ b/ext/io/nonblock/nonblock.c @@ -42,7 +42,7 @@ rb_io_nonblock_p(VALUE io) rb_io_t *fptr; GetOpenFile(io, fptr); if (get_fcntl_flags(fptr->fd) & O_NONBLOCK) - return Qtrue; + return Qtrue; return Qfalse; } #else @@ -54,21 +54,21 @@ static void set_fcntl_flags(int fd, int f) { if (fcntl(fd, F_SETFL, f) == -1) - rb_sys_fail(0); + rb_sys_fail(0); } static int io_nonblock_set(int fd, int f, int nb) { if (nb) { - if ((f & O_NONBLOCK) != 0) - return 0; - f |= O_NONBLOCK; + if ((f & O_NONBLOCK) != 0) + return 0; + f |= O_NONBLOCK; } else { - if ((f & O_NONBLOCK) == 0) - return 0; - f &= ~O_NONBLOCK; + if ((f & O_NONBLOCK) == 0) + return 0; + f &= ~O_NONBLOCK; } set_fcntl_flags(fd, f); return 1; @@ -127,9 +127,9 @@ rb_io_nonblock_set(VALUE io, VALUE nb) rb_io_t *fptr; GetOpenFile(io, fptr); if (RTEST(nb)) - rb_io_set_nonblock(fptr); + rb_io_set_nonblock(fptr); else - io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); + io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); return io; } @@ -160,15 +160,15 @@ rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) GetOpenFile(io, fptr); if (argc > 0) { - VALUE v; - rb_scan_args(argc, argv, "01", &v); - nb = RTEST(v); + VALUE v; + rb_scan_args(argc, argv, "01", &v); + nb = RTEST(v); } f = get_fcntl_flags(fptr->fd); restore[0] = fptr->fd; restore[1] = f; if (!io_nonblock_set(fptr->fd, f, nb)) - return rb_yield(io); + return rb_yield(io); return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore); } #else From 4ba2c66761d6a293abdfba409241d31063cefd62 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 17:29:56 +0900 Subject: [PATCH 083/142] Revert "* expand tabs. [ci skip]" This reverts commit 0d842fecb4f75ab3b1d4097ebdb8e88f51558041. --- ext/io/nonblock/nonblock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c index cbd43d993a60ff..b8a40ff38e94a2 100644 --- a/ext/io/nonblock/nonblock.c +++ b/ext/io/nonblock/nonblock.c @@ -42,7 +42,7 @@ rb_io_nonblock_p(VALUE io) rb_io_t *fptr; GetOpenFile(io, fptr); if (get_fcntl_flags(fptr->fd) & O_NONBLOCK) - return Qtrue; + return Qtrue; return Qfalse; } #else @@ -54,21 +54,21 @@ static void set_fcntl_flags(int fd, int f) { if (fcntl(fd, F_SETFL, f) == -1) - rb_sys_fail(0); + rb_sys_fail(0); } static int io_nonblock_set(int fd, int f, int nb) { if (nb) { - if ((f & O_NONBLOCK) != 0) - return 0; - f |= O_NONBLOCK; + if ((f & O_NONBLOCK) != 0) + return 0; + f |= O_NONBLOCK; } else { - if ((f & O_NONBLOCK) == 0) - return 0; - f &= ~O_NONBLOCK; + if ((f & O_NONBLOCK) == 0) + return 0; + f &= ~O_NONBLOCK; } set_fcntl_flags(fd, f); return 1; @@ -127,9 +127,9 @@ rb_io_nonblock_set(VALUE io, VALUE nb) rb_io_t *fptr; GetOpenFile(io, fptr); if (RTEST(nb)) - rb_io_set_nonblock(fptr); + rb_io_set_nonblock(fptr); else - io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); + io_nonblock_set(fptr->fd, get_fcntl_flags(fptr->fd), RTEST(nb)); return io; } @@ -160,15 +160,15 @@ rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) GetOpenFile(io, fptr); if (argc > 0) { - VALUE v; - rb_scan_args(argc, argv, "01", &v); - nb = RTEST(v); + VALUE v; + rb_scan_args(argc, argv, "01", &v); + nb = RTEST(v); } f = get_fcntl_flags(fptr->fd); restore[0] = fptr->fd; restore[1] = f; if (!io_nonblock_set(fptr->fd, f, nb)) - return rb_yield(io); + return rb_yield(io); return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore); } #else From 233884542101737892ce3b56e03ce47731a78057 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 30 Jul 2022 17:32:57 +0900 Subject: [PATCH 084/142] Update .git-blame-ignore-revs [ci skip] --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 209aa9693a5bc9..c05a98e306c73d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -16,3 +16,5 @@ d7ffd3fea402239b16833cc434404a7af82d44f3 # [ruby/io-nonblock] Revert tab expansion f28287d34c03f472ffe90ea262bdde9affd4b965 +0d842fecb4f75ab3b1d4097ebdb8e88f51558041 +4ba2c66761d6a293abdfba409241d31063cefd62 From 1a73a6cdd2068b815430b775fe25186dab693faa Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Fri, 29 Jul 2022 13:56:54 +0900 Subject: [PATCH 085/142] Implement Enumerator::Product and Enumerator.product [Feature #18685] --- enumerator.c | 354 ++++++++++++++++++++++++++++++++++- test/ruby/test_enumerator.rb | 38 ++++ 2 files changed, 391 insertions(+), 1 deletion(-) diff --git a/enumerator.c b/enumerator.c index 89abf4b8881da7..ce2eacbd2a8d8a 100644 --- a/enumerator.c +++ b/enumerator.c @@ -125,7 +125,7 @@ */ VALUE rb_cEnumerator; static VALUE rb_cLazy; -static ID id_rewind, id_new, id_to_enum; +static ID id_rewind, id_new, id_to_enum, id_each_entry; static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force; static ID id_begin, id_end, id_step, id_exclude_end; static VALUE sym_each, sym_cycle, sym_yield; @@ -194,6 +194,12 @@ struct enum_chain { long pos; }; +static VALUE rb_cEnumProduct; + +struct enum_product { + VALUE enums; +}; + VALUE rb_cArithSeq; /* @@ -3347,6 +3353,335 @@ enumerator_plus(VALUE obj, VALUE eobj) return new_enum_chain(rb_ary_new_from_args(2, obj, eobj)); } +/* + * Document-class: Enumerator::Product + * + * Enumerator::Product generates a Cartesian product of any number of + * enumerable objects. Iterating over the product of enumerable + * objects is roughly equivalent to nested each_entry loops where the + * loop for the rightmost object is put innermost. + * + * innings = Enumerator::Product.new(1..9, ['top', 'bottom']) + * + * innings.each do |i, h| + * p [i, h] + * end + * # [1, "top"] + * # [1, "bottom"] + * # [2, "top"] + * # [2, "bottom"] + * # [3, "top"] + * # [3, "bottom"] + * # ... + * # [9, "top"] + * # [9, "bottom"] + * + * The method used against each enumerable object is `each_entry` + * instead of `each` so that the product of N enumerable objects + * yields exactly N arguments in each iteration. + * + * When no enumerator is given, it calls a given block once yielding + * an empty argument list. + * + * This type of objects can be created by Enumerator.product. + */ + +static void +enum_product_mark(void *p) +{ + struct enum_product *ptr = p; + rb_gc_mark_movable(ptr->enums); +} + +static void +enum_product_compact(void *p) +{ + struct enum_product *ptr = p; + ptr->enums = rb_gc_location(ptr->enums); +} + +#define enum_product_free RUBY_TYPED_DEFAULT_FREE + +static size_t +enum_product_memsize(const void *p) +{ + return sizeof(struct enum_product); +} + +static const rb_data_type_t enum_product_data_type = { + "product", + { + enum_product_mark, + enum_product_free, + enum_product_memsize, + enum_product_compact, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + +static struct enum_product * +enum_product_ptr(VALUE obj) +{ + struct enum_product *ptr; + + TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr); + if (!ptr || ptr->enums == Qundef) { + rb_raise(rb_eArgError, "uninitialized product"); + } + return ptr; +} + +/* :nodoc: */ +static VALUE +enum_product_allocate(VALUE klass) +{ + struct enum_product *ptr; + VALUE obj; + + obj = TypedData_Make_Struct(klass, struct enum_product, &enum_product_data_type, ptr); + ptr->enums = Qundef; + + return obj; +} + +/* + * call-seq: + * Enumerator::Product.new(*enums) -> enum + * + * Generates a new enumerator object that generates a Cartesian + * product of given enumerable objects. + * + * e = Enumerator::Product.new(1..3, [4, 5]) + * e.to_a #=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] + * e.size #=> 6 + */ +static VALUE +enum_product_initialize(VALUE obj, VALUE enums) +{ + struct enum_product *ptr; + + rb_check_frozen(obj); + TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr); + + if (!ptr) rb_raise(rb_eArgError, "unallocated product"); + + ptr->enums = rb_obj_freeze(enums); + + return obj; +} + +/* :nodoc: */ +static VALUE +enum_product_init_copy(VALUE obj, VALUE orig) +{ + struct enum_product *ptr0, *ptr1; + + if (!OBJ_INIT_COPY(obj, orig)) return obj; + ptr0 = enum_product_ptr(orig); + + TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr1); + + if (!ptr1) rb_raise(rb_eArgError, "unallocated product"); + + ptr1->enums = ptr0->enums; + + return obj; +} + +static VALUE +enum_product_total_size(VALUE enums) +{ + VALUE total = INT2FIX(1); + long i; + + for (i = 0; i < RARRAY_LEN(enums); i++) { + VALUE size = enum_size(RARRAY_AREF(enums, i)); + + if (NIL_P(size) || (RB_TYPE_P(size, T_FLOAT) && isinf(NUM2DBL(size)))) { + return size; + } + if (!RB_INTEGER_TYPE_P(size)) { + return Qnil; + } + + total = rb_funcall(total, '*', 1, size); + } + + return total; +} + +/* + * call-seq: + * obj.size -> int, Float::INFINITY or nil + * + * Returns the total size of the enumerator product calculated by + * multiplying the sizes of enumerables in the product. If any of the + * enumerables reports its size as nil or Float::INFINITY, that value + * is returned as the size. + */ +static VALUE +enum_product_size(VALUE obj) +{ + return enum_product_total_size(enum_product_ptr(obj)->enums); +} + +static VALUE +enum_product_enum_size(VALUE obj, VALUE args, VALUE eobj) +{ + return enum_product_size(obj); +} + +struct product_state { + VALUE obj; + VALUE block; + int argc; + VALUE *argv; + int index; +}; + +static VALUE product_each(VALUE, struct product_state *); + +static VALUE +product_each_i(RB_BLOCK_CALL_FUNC_ARGLIST(value, state)) +{ + struct product_state *pstate = (struct product_state *)state; + pstate->argv[pstate->index++] = value; + + VALUE val = product_each(pstate->obj, pstate); + pstate->index--; + return val; +} + +static VALUE +product_each(VALUE obj, struct product_state *pstate) +{ + struct enum_product *ptr = enum_product_ptr(obj); + VALUE enums = ptr->enums; + + if (pstate->index < pstate->argc) { + VALUE eobj = RARRAY_AREF(enums, pstate->index); + + rb_block_call(eobj, id_each_entry, 0, NULL, product_each_i, (VALUE)pstate); + } else { + rb_funcallv(pstate->block, id_call, pstate->argc, pstate->argv); + } + + return obj; +} + +static VALUE +enum_product_run(VALUE obj, VALUE block) +{ + struct enum_product *ptr = enum_product_ptr(obj); + int argc = RARRAY_LENINT(ptr->enums); + struct product_state state = { + .obj = obj, + .block = block, + .index = 0, + .argc = argc, + .argv = ALLOCA_N(VALUE, argc), + }; + + return product_each(obj, &state); +} + +/* + * call-seq: + * obj.each { |...| ... } -> obj + * obj.each -> enumerator + * + * Iterates over the elements of the first enumerable by calling the + * "each_entry" method on it with the given arguments, then proceeds + * to the following enumerables in sequence until all of the + * enumerables are exhausted. + * + * If no block is given, returns an enumerator. Otherwise, returns self. + */ +static VALUE +enum_product_each(VALUE obj) +{ + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_product_enum_size); + + return enum_product_run(obj, rb_block_proc()); +} + +/* + * call-seq: + * obj.rewind -> obj + * + * Rewinds the product enumerator by calling the "rewind" method on + * each enumerable in reverse order. Each call is performed only if + * the enumerable responds to the method. + */ +static VALUE +enum_product_rewind(VALUE obj) +{ + struct enum_product *ptr = enum_product_ptr(obj); + VALUE enums = ptr->enums; + long i; + + for (i = 0; i < RARRAY_LEN(enums); i++) { + rb_check_funcall(RARRAY_AREF(enums, i), id_rewind, 0, 0); + } + + return obj; +} + +static VALUE +inspect_enum_product(VALUE obj, VALUE dummy, int recur) +{ + VALUE klass = rb_obj_class(obj); + struct enum_product *ptr; + + TypedData_Get_Struct(obj, struct enum_product, &enum_product_data_type, ptr); + + if (!ptr || ptr->enums == Qundef) { + return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(klass)); + } + + if (recur) { + return rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(klass)); + } + + return rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(klass), ptr->enums); +} + +/* + * call-seq: + * obj.inspect -> string + * + * Returns a printable version of the product enumerator. + */ +static VALUE +enum_product_inspect(VALUE obj) +{ + return rb_exec_recursive(inspect_enum_product, obj, 0); +} + +/* + * call-seq: + * Enumerator.product(*enums) -> enumerator + * + * Generates a new enumerator object that generates a Cartesian + * product of given enumerable objects. This is equivalent to + * Enumerator::Product.new. + * + * e = Enumerator.product(1..3, [4, 5]) + * e.to_a #=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] + * e.size #=> 6 + */ +static VALUE +enumerator_s_product(VALUE klass, VALUE enums) +{ + VALUE obj = enum_product_initialize(enum_product_allocate(rb_cEnumProduct), enums); + + if (rb_block_given_p()) { + return enum_product_run(obj, rb_block_proc()); + } else { + return obj; + } +} + /* * Document-class: Enumerator::ArithmeticSequence * @@ -4214,6 +4549,22 @@ InitVM_Enumerator(void) rb_undef_method(rb_cEnumChain, "peek"); rb_undef_method(rb_cEnumChain, "peek_values"); + /* Product */ + rb_cEnumProduct = rb_define_class_under(rb_cEnumerator, "Product", rb_cEnumerator); + rb_define_alloc_func(rb_cEnumProduct, enum_product_allocate); + rb_define_method(rb_cEnumProduct, "initialize", enum_product_initialize, -2); + rb_define_method(rb_cEnumProduct, "initialize_copy", enum_product_init_copy, 1); + rb_define_method(rb_cEnumProduct, "each", enum_product_each, 0); + rb_define_method(rb_cEnumProduct, "size", enum_product_size, 0); + rb_define_method(rb_cEnumProduct, "rewind", enum_product_rewind, 0); + rb_define_method(rb_cEnumProduct, "inspect", enum_product_inspect, 0); + rb_undef_method(rb_cEnumProduct, "feed"); + rb_undef_method(rb_cEnumProduct, "next"); + rb_undef_method(rb_cEnumProduct, "next_values"); + rb_undef_method(rb_cEnumProduct, "peek"); + rb_undef_method(rb_cEnumProduct, "peek_values"); + rb_define_singleton_method(rb_cEnumerator, "product", enumerator_s_product, -2); + /* ArithmeticSequence */ rb_cArithSeq = rb_define_class_under(rb_cEnumerator, "ArithmeticSequence", rb_cEnumerator); rb_undef_alloc_func(rb_cArithSeq); @@ -4249,6 +4600,7 @@ Init_Enumerator(void) id_method = rb_intern_const("method"); id_force = rb_intern_const("force"); id_to_enum = rb_intern_const("to_enum"); + id_each_entry = rb_intern_const("each_entry"); id_begin = rb_intern_const("begin"); id_end = rb_intern_const("end"); id_step = rb_intern_const("step"); diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb index c823b79c6d1126..3ca33126d580dd 100644 --- a/test/ruby/test_enumerator.rb +++ b/test/ruby/test_enumerator.rb @@ -906,4 +906,42 @@ def each(&block) e.chain.each(&->{}) assert_equal(true, e.is_lambda) end + + def test_product + e = Enumerator::Product.new + assert_instance_of(Enumerator::Product, e) + assert_kind_of(Enumerator, e) + assert_equal(1, e.size) + elts = [] + e.each { |*x| elts << x } + assert_equal [[]], elts + + e = Enumerator::Product.new(1..3, %w[a b]) + assert_instance_of(Enumerator::Product, e) + assert_kind_of(Enumerator, e) + assert_equal(3 * 2, e.size) + elts = [] + e.each { |*x| elts << x } + assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"], [3, "a"], [3, "b"]], elts + + e = Enumerator.product(1..3, %w[a b]) + assert_instance_of(Enumerator::Product, e) + + elts = [] + ret = Enumerator.product(1..3, %w[a b]) { |*x| elts << x } + assert_instance_of(Enumerator::Product, ret) + assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"], [3, "a"], [3, "b"]], elts + + e = Enumerator.product(1.., 'a'..'c') + assert_equal(Float::INFINITY, e.size) + assert_equal [[1, "a"], [1, "b"], [1, "c"], [2, "a"]], e.take(4) + + e = Enumerator.product(1.., Enumerator.new { |y| y << 'a' << 'b' }) + assert_equal(Float::INFINITY, e.size) + assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"]], e.take(4) + + e = Enumerator.product(1..3, Enumerator.new { |y| y << 'a' << 'b' }) + assert_equal(nil, e.size) + assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"]], e.take(4) + end end From d050f162a7fa04ccb699fa25ef22cd18be4d7c42 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Fri, 29 Jul 2022 14:00:29 +0900 Subject: [PATCH 086/142] Mention Enumerator.product/Enumerator::Product in the NEWS.md --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index fdb58e4bb7fb45..f2aa9d736c43b9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -96,6 +96,9 @@ Note that each entry is kept to a minimum, see links for details. Note: We're only listing outstanding class updates. +* Enumerator + * Enumerator.product has been added. Enumerator::Product is the implementation. [[Feature #18685]] + * Hash * Hash#shift now always returns nil if the hash is empty, instead of returning the default value or From 4efbeb11905534289a6b4a4bc4779859a9c6c6a6 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Sat, 30 Jul 2022 13:18:29 -0500 Subject: [PATCH 087/142] [ruby/date] Enhanced RDoc (https://github.com/ruby/date/pull/67) Treats: ::httpdate #to_date #to_time #to_datetime In behalf of ::httpdate, I've introduced section "Argument limit" that can be pointed to by various Date methods (similar to existing section "Argument start"). This will involve 8 already-enhanced methods plus 8 more not yet done. https://github.com/ruby/date/commit/00326ff99c --- ext/date/date_core.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index d8048194ce8516..762fb7281cd90e 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -4833,11 +4833,14 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._httpdate(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + * Date._httpdate(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__httpdate(int argc, VALUE *argv, VALUE klass) @@ -8760,10 +8763,15 @@ time_to_datetime(VALUE self) /* * call-seq: - * d.to_time -> time + * to_time -> time + * + * Returns a new Time object with the same value as +self+; + * if +self+ is a Julian date, derives its Gregorian date + * for conversion to the \Time object: + * + * Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600 + * Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600 * - * Returns a Time object which denotes self. If self is a julian date, - * convert it to a gregorian date before converting it to Time. */ static VALUE date_to_time(VALUE self) @@ -8784,9 +8792,9 @@ date_to_time(VALUE self) /* * call-seq: - * d.to_date -> self + * to_date -> self * - * Returns self. + * Returns +self+. */ static VALUE date_to_date(VALUE self) @@ -8798,7 +8806,10 @@ date_to_date(VALUE self) * call-seq: * d.to_datetime -> datetime * - * Returns a DateTime object which denotes self. + * Returns a DateTime whose value is the same as +self+: + * + * Date.new(2001, 2, 3).to_datetime # => # + * */ static VALUE date_to_datetime(VALUE self) @@ -9498,6 +9509,19 @@ Init_date_core(void) * - Date::JULIAN - no changeover date; all dates are Julian. * - Date::GREGORIAN - no changeover date; all dates are Gregorian. * + * === Argument +limit+ + * + * Certain singleton methods in \Date that parse string arguments + * also take optional keyword argument +limit+, + * which can limit the length of the string argument. + * + * When +limit+ is: + * + * - Non-negative: + * raises ArgumentError if the string length is greater than _limit_. + * - Other numeric or +nil+: ignores +limit+. + * - Other non-numeric: raises TypeError. + * */ cDate = rb_define_class("Date", rb_cObject); From 118368c1dd9304c0c21a4437016af235bd9b8438 Mon Sep 17 00:00:00 2001 From: git Date: Sun, 31 Jul 2022 03:18:59 +0900 Subject: [PATCH 088/142] * 2022-07-31 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index da18c1d27d0ac5..a82f0a2183ab99 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 30 +#define RUBY_RELEASE_DAY 31 #include "ruby/version.h" #include "ruby/internal/abi.h" From b0e6d07ce49da4ffc84f3a1f1717b2e096e8b513 Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Sun, 31 Jul 2022 11:11:46 +0000 Subject: [PATCH 089/142] [rubygems/rubygems] Update bundle-platform(1) man Signed-off-by: Takuya Noguchi https://github.com/rubygems/rubygems/commit/1c3736f5af --- lib/bundler/man/bundle-platform.1 | 20 +++++++++++++++----- lib/bundler/man/bundle-platform.1.ronn | 21 ++++++++++++++------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1 index 344ad930831460..f5a90c59e91ef2 100644 --- a/lib/bundler/man/bundle-platform.1 +++ b/lib/bundler/man/bundle-platform.1 @@ -10,7 +10,7 @@ \fBbundle platform\fR [\-\-ruby] . .SH "DESCRIPTION" -\fBplatform\fR will display information from your Gemfile, Gemfile\.lock, and Ruby VM about your platform\. +\fBplatform\fR displays information from your Gemfile, Gemfile\.lock, and Ruby VM about your platform\. . .P For instance, using this Gemfile(5): @@ -21,7 +21,7 @@ For instance, using this Gemfile(5): source "https://rubygems\.org" -ruby "1\.9\.3" +ruby "3\.1\.2" gem "rack" . @@ -30,7 +30,7 @@ gem "rack" .IP "" 0 . .P -If you run \fBbundle platform\fR on Ruby 1\.9\.3, it will display the following output: +If you run \fBbundle platform\fR on Ruby 3\.1\.2, it displays the following output: . .IP "" 4 . @@ -39,10 +39,13 @@ If you run \fBbundle platform\fR on Ruby 1\.9\.3, it will display the following Your platform is: x86_64\-linux Your app has gems that work on these platforms: +* arm64\-darwin\-21 * ruby +* x64\-mingw\-ucrt +* x86_64\-linux Your Gemfile specifies a Ruby version requirement: -* ruby 1\.9\.3 +* ruby 3\.1\.2 Your current platform satisfies the Ruby version requirement\. . @@ -51,11 +54,18 @@ Your current platform satisfies the Ruby version requirement\. .IP "" 0 . .P -\fBplatform\fR will list all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It will also let you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn\'t match the running Ruby VM, it will tell you what part does not\. +\fBplatform\fR lists all the platforms in your \fBGemfile\.lock\fR as well as the \fBruby\fR directive if applicable from your Gemfile(5)\. It also lets you know if the \fBruby\fR directive requirement has been met\. If \fBruby\fR directive doesn\'t match the running Ruby VM, it tells you what part does not\. . .SH "OPTIONS" . .TP \fB\-\-ruby\fR It will display the ruby directive information, so you don\'t have to parse it from the Gemfile(5)\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +bundle\-lock(1) \fIbundle\-lock\.1\.ronn\fR +. +.IP "" 0 diff --git a/lib/bundler/man/bundle-platform.1.ronn b/lib/bundler/man/bundle-platform.1.ronn index b5d3283fb6e3cb..eb9baa1c62fca9 100644 --- a/lib/bundler/man/bundle-platform.1.ronn +++ b/lib/bundler/man/bundle-platform.1.ronn @@ -7,36 +7,43 @@ bundle-platform(1) -- Displays platform compatibility information ## DESCRIPTION -`platform` will display information from your Gemfile, Gemfile.lock, and Ruby +`platform` displays information from your Gemfile, Gemfile.lock, and Ruby VM about your platform. For instance, using this Gemfile(5): source "https://rubygems.org" - ruby "1.9.3" + ruby "3.1.2" gem "rack" -If you run `bundle platform` on Ruby 1.9.3, it will display the following output: +If you run `bundle platform` on Ruby 3.1.2, it displays the following output: Your platform is: x86_64-linux Your app has gems that work on these platforms: + * arm64-darwin-21 * ruby + * x64-mingw-ucrt + * x86_64-linux Your Gemfile specifies a Ruby version requirement: - * ruby 1.9.3 + * ruby 3.1.2 Your current platform satisfies the Ruby version requirement. -`platform` will list all the platforms in your `Gemfile.lock` as well as the -`ruby` directive if applicable from your Gemfile(5). It will also let you know +`platform` lists all the platforms in your `Gemfile.lock` as well as the +`ruby` directive if applicable from your Gemfile(5). It also lets you know if the `ruby` directive requirement has been met. If `ruby` directive doesn't -match the running Ruby VM, it will tell you what part does not. +match the running Ruby VM, it tells you what part does not. ## OPTIONS * `--ruby`: It will display the ruby directive information, so you don't have to parse it from the Gemfile(5). + +## SEE ALSO + +* [bundle-lock(1)](bundle-lock.1.ronn) From 3b8279e91fd55b66534e7828cd1ed5cea70b3005 Mon Sep 17 00:00:00 2001 From: git Date: Mon, 1 Aug 2022 01:31:40 +0900 Subject: [PATCH 090/142] * 2022-08-01 [ci skip] --- version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.h b/version.h index a82f0a2183ab99..c53d02157830ac 100644 --- a/version.h +++ b/version.h @@ -14,8 +14,8 @@ #define RUBY_PATCHLEVEL -1 #define RUBY_RELEASE_YEAR 2022 -#define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 31 +#define RUBY_RELEASE_MONTH 8 +#define RUBY_RELEASE_DAY 1 #include "ruby/version.h" #include "ruby/internal/abi.h" From c69ad738dc7c713df547a51607917ca78df6b793 Mon Sep 17 00:00:00 2001 From: Wolf Date: Fri, 29 Jul 2022 20:12:39 +0200 Subject: [PATCH 091/142] Initialize node_id In some causes node_id might have been left uninitialized leading to undefined behavior on access. So always set it to -1, so we have *some* valid value in there. --- node.c | 1 + 1 file changed, 1 insertion(+) diff --git a/node.c b/node.c index a10d5122c37147..483e7fa8fbd0ed 100644 --- a/node.c +++ b/node.c @@ -1138,6 +1138,7 @@ rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2) n->nd_loc.beg_pos.column = 0; n->nd_loc.end_pos.lineno = 0; n->nd_loc.end_pos.column = 0; + n->node_id = -1; } typedef struct node_buffer_elem_struct { From 1520936aa760e6b2747d31c37854f22a63591667 Mon Sep 17 00:00:00 2001 From: Kazuhiro NISHIYAMA Date: Mon, 1 Aug 2022 12:34:03 +0900 Subject: [PATCH 092/142] Fix a link [ci skip] --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index f2aa9d736c43b9..d3fee75302d250 100644 --- a/NEWS.md +++ b/NEWS.md @@ -271,5 +271,6 @@ The following deprecated APIs are removed. [Feature #18598]: https://bugs.ruby-lang.org/issues/18598 [Bug #18625]: https://bugs.ruby-lang.org/issues/18625 [Bug #18633]: https://bugs.ruby-lang.org/issues/18633 +[Feature #18685]: https://bugs.ruby-lang.org/issues/18685 [Bug #18782]: https://bugs.ruby-lang.org/issues/18782 [Feature #18788]: https://bugs.ruby-lang.org/issues/18788 From 5bbba76489628f4509495ebf4ba0a7aad4c0b560 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 29 Jul 2022 16:02:10 +0900 Subject: [PATCH 093/142] respect current frame of `rb_eval_string` `self` is nearest Ruby method's `self`. If there is no ruby frame, use toplevel `self` (`main`). https://bugs.ruby-lang.org/issues/18780 --- ext/-test-/eval/eval.c | 13 +++++++++++++ ext/-test-/eval/extconf.rb | 2 ++ test/-ext-/eval/test_eval.rb | 12 ++++++++++++ vm_eval.c | 5 ++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 ext/-test-/eval/eval.c create mode 100644 ext/-test-/eval/extconf.rb create mode 100644 test/-ext-/eval/test_eval.rb diff --git a/ext/-test-/eval/eval.c b/ext/-test-/eval/eval.c new file mode 100644 index 00000000000000..983468fc347c7d --- /dev/null +++ b/ext/-test-/eval/eval.c @@ -0,0 +1,13 @@ +#include "ruby/ruby.h" + +static VALUE +eval_string(VALUE self, VALUE str) +{ + return rb_eval_string(StringValueCStr(str)); +} + +void +Init_eval(void) +{ + rb_define_global_function("rb_eval_string", eval_string, 1); +} diff --git a/ext/-test-/eval/extconf.rb b/ext/-test-/eval/extconf.rb new file mode 100644 index 00000000000000..cdbf6a8597fccf --- /dev/null +++ b/ext/-test-/eval/extconf.rb @@ -0,0 +1,2 @@ +require 'mkmf' +create_makefile('-test-/eval') diff --git a/test/-ext-/eval/test_eval.rb b/test/-ext-/eval/test_eval.rb new file mode 100644 index 00000000000000..27952996e29c90 --- /dev/null +++ b/test/-ext-/eval/test_eval.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: false +require 'test/unit' +require "-test-/eval" + +class EvalTest < Test::Unit::TestCase + def test_rb_eval_string + a = 1 + assert_equal [self, 1, __method__], rb_eval_string(%q{ + [self, a, __method__] + }) + end +end diff --git a/vm_eval.c b/vm_eval.c index e490e4e32dcf62..c7669cbb858e2a 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1828,7 +1828,10 @@ VALUE ruby_eval_string_from_file(const char *str, const char *filename) { VALUE file = filename ? rb_str_new_cstr(filename) : 0; - return eval_string_with_cref(rb_vm_top_self(), rb_str_new2(str), NULL, file, 1); + rb_execution_context_t *ec = GET_EC(); + rb_control_frame_t *cfp = ec ? rb_vm_get_ruby_level_next_cfp(ec, ec->cfp) : NULL; + VALUE self = cfp ? cfp->self : rb_vm_top_self(); + return eval_string_with_cref(self, rb_str_new2(str), NULL, file, 1); } VALUE From 5c13adb746ad7d0f829809ee833e4fdde1238e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 1 Aug 2022 11:46:49 +0200 Subject: [PATCH 094/142] [rubygems/rubygems] Fix comment incorrectly copied from another spec https://github.com/rubygems/rubygems/commit/9be5eae9cf --- spec/bundler/commands/outdated_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index d0209022a254fd..3b09d6f177b4ec 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -1114,8 +1114,7 @@ def test_group_option(group) gem 'major', '1.0.0' G - # remove 1.4.3 requirement and bar altogether - # to setup update specs below + # remove all version requirements gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'patch' From 13305bf0c9a03f24b5ab667784ff1dc1f10b3d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 1 Aug 2022 11:47:15 +0200 Subject: [PATCH 095/142] [rubygems/rubygems] Fix crash when running `bundle outdated` in debug mode Previously it would crash like this: ```` $ /Users/deivid/.asdf/installs/ruby/3.1.2/bin/ruby -I/Users/deivid/Code/rubygems/rubygems/bundler/spec -r/Users/deivid/Code/rubygems/rubygems/bundler/spec/support/artifice/fail.rb -r/Users/deivid/Code/rubygems/rubygems/bundler/spec/support/hax.rb /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle outdated --patch --strict --filter-patch Running `bundle outdated --filter-patch --patch --strict` with bundler 2.4.0.dev Found changes from the lockfile, re-resolving dependencies because bundler is unlocking Using a local server, bundler won't use the CompactIndex API Fetching source index from file:///Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/remote4/ Resolving dependencies... --- ERROR REPORT TEMPLATE ------------------------------------------------------- ``` RuntimeError: LazySpecification has not been materialized yet (calling :loaded_from []) /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/lazy_specification.rb:147:in `method_missing' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/outdated.rb:214:in `gem_column_for' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/outdated.rb:174:in `block in print_gems_table' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/outdated.rb:173:in `map' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/outdated.rb:173:in `print_gems_table' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli/outdated.rb:123:in `run' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:420:in `outdated' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:31:in `dispatch' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/cli.rb:25:in `start' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/exe/bundle:48:in `block in ' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/gems/bundler-2.4.0.dev/exe/bundle:36:in `' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle:25:in `load' /Users/deivid/Code/rubygems/rubygems/bundler/tmp/1/gems/system/bin/bundle:25:in `
' ``` ```` https://github.com/rubygems/rubygems/commit/23c46f3b57 --- lib/bundler/cli/outdated.rb | 13 +++++++++++-- spec/bundler/commands/outdated_spec.rb | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb index d5183b060bbd8e..9ce583886e81eb 100644 --- a/lib/bundler/cli/outdated.rb +++ b/lib/bundler/cli/outdated.rb @@ -129,6 +129,12 @@ def run private + def loaded_from_for(spec) + return unless spec.respond_to?(:loaded_from) + + spec.loaded_from + end + def groups_text(group_text, groups) "#{group_text}#{groups.split(",").size > 1 ? "s" : ""} \"#{groups}\"" end @@ -184,7 +190,10 @@ def print_gems_table(gems_list) def print_gem(current_spec, active_spec, dependency, groups) spec_version = "#{active_spec.version}#{active_spec.git_version}" - spec_version += " (from #{active_spec.loaded_from})" if Bundler.ui.debug? && active_spec.loaded_from + if Bundler.ui.debug? + loaded_from = loaded_from_for(active_spec) + spec_version += " (from #{loaded_from})" if loaded_from + end current_version = "#{current_spec.version}#{current_spec.git_version}" if dependency && dependency.specific? @@ -211,7 +220,7 @@ def gem_column_for(current_spec, active_spec, dependency, groups) dependency = dependency.requirement if dependency ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s] - ret_val << active_spec.loaded_from.to_s if Bundler.ui.debug? + ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug? ret_val end diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index 3b09d6f177b4ec..a05a1ad4bb8fa2 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -1207,6 +1207,18 @@ def test_group_option(group) expect(out).to end_with(expected_output) end + + it "shows gems with --strict updating to patch and filtering to patch, in debug mode" do + bundle "outdated --patch --strict --filter-patch", :raise_on_error => false, :env => { "DEBUG" => "1" } + + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups Path + bar 2.0.3 2.0.5 + foo 1.4.3 1.4.4 >= 0 default + TABLE + + expect(out).to end_with(expected_output) + end end end From 25022bad85c87b52f59de22db41fe35c9f57d1df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 15:28:32 +0000 Subject: [PATCH 096/142] [rubygems/rubygems] Bump rb-sys Bumps [rb-sys](https://github.com/oxidize-rb/rb-sys) from 0.9.26 to 0.9.28. - [Release notes](https://github.com/oxidize-rb/rb-sys/releases) - [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.26...v0.9.28) --- updated-dependencies: - dependency-name: rb-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] https://github.com/rubygems/rubygems/commit/831a001697 --- .../rust_ruby_example/Cargo.lock | 8 ++++---- .../rust_ruby_example/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock index 376d11cf3e4861..0a95dceca232fc 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.26" +version = "0.9.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723f7560e878bec9d1d49538a17fb6a4e3a04688c1dc6f14eef17918634a54e4" +checksum = "8d7df1d7911fef801edda0b789cca202f3486dff5073eb13dbb85b4715e6f94a" dependencies = [ "bindgen", "linkify", @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "rb-sys-build" -version = "0.9.26" +version = "0.9.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccd93f0d9767385cd7a23076c47e3dca4c86144e510ea4c61d04dbce0cbac7e" +checksum = "c6fa9b908035cb531820f8f3977c538c318308cfaa77da1c6b436577c06db230" dependencies = [ "regex", "shell-words", diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml index 7d3cd133a81b67..7cced882e98132 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = { version = "0.9.26", features = ["gem"] } +rb-sys = { version = "0.9.28", features = ["gem"] } From 00777a9b35bf9ae750c231f06d79e58d07069562 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 2 Aug 2022 02:38:08 +0900 Subject: [PATCH 097/142] * 2022-08-02 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index c53d02157830ac..f364a1a8d0a04a 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 1 +#define RUBY_RELEASE_DAY 2 #include "ruby/version.h" #include "ruby/internal/abi.h" From 24204d54ab730791bfbd0cd66b8e12f0bd62ca5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 17:39:14 +0000 Subject: [PATCH 098/142] [rubygems/rubygems] Bump rb-sys in /test/rubygems/test_gem_ext_cargo_builder/custom_name Bumps [rb-sys](https://github.com/oxidize-rb/rb-sys) from 0.9.26 to 0.9.28. - [Release notes](https://github.com/oxidize-rb/rb-sys/releases) - [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.26...v0.9.28) --- updated-dependencies: - dependency-name: rb-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] https://github.com/rubygems/rubygems/commit/edea8fbfa0 --- .../test_gem_ext_cargo_builder/custom_name/Cargo.lock | 8 ++++---- .../test_gem_ext_cargo_builder/custom_name/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock index 498ee26c7e7139..86221bf249e295 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.26" +version = "0.9.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723f7560e878bec9d1d49538a17fb6a4e3a04688c1dc6f14eef17918634a54e4" +checksum = "8d7df1d7911fef801edda0b789cca202f3486dff5073eb13dbb85b4715e6f94a" dependencies = [ "bindgen", "linkify", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "rb-sys-build" -version = "0.9.26" +version = "0.9.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccd93f0d9767385cd7a23076c47e3dca4c86144e510ea4c61d04dbce0cbac7e" +checksum = "c6fa9b908035cb531820f8f3977c538c318308cfaa77da1c6b436577c06db230" dependencies = [ "regex", "shell-words", diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml index b144f930e58c2b..ae32c194b2959f 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = { version = "0.9.26", features = ["gem"] } +rb-sys = { version = "0.9.28", features = ["gem"] } From 6ec8f684aa1ff6182b4be3fc67b2fa5bad3f0bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 14 Jul 2022 22:22:54 +0200 Subject: [PATCH 099/142] [rubygems/rubygems] Move some logic to `LazySpecification#__materialize__` https://github.com/rubygems/rubygems/commit/5e100df7c9 --- lib/bundler/lazy_specification.rb | 2 ++ lib/bundler/spec_set.rb | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 21e75d2126aab0..ff9444e0091c98 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -76,6 +76,8 @@ def to_lock end def materialize_for_installation + source.local! + __materialize__(ruby_platform_materializes_to_ruby_platform? ? platform : Bundler.local_platform) end diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index a7a95e49bc80b2..4e339ffe914215 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -70,7 +70,6 @@ def materialize(deps) materialized.map! do |s| next s unless s.is_a?(LazySpecification) - s.source.local! s.materialize_for_installation || s end SpecSet.new(materialized) @@ -82,7 +81,6 @@ def materialize(deps) def materialized_for_all_platforms @specs.map do |s| next s unless s.is_a?(LazySpecification) - s.source.local! s.source.remote! spec = s.materialize_for_installation raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec From 7cc5a657eed1a537b33b7b2ec71fdb5ad9323950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 09:19:34 +0200 Subject: [PATCH 100/142] [rubygems/rubygems] Remove unnecessary special case for Bundler https://github.com/rubygems/rubygems/commit/2777e79b8e --- lib/bundler/definition.rb | 6 ++---- lib/bundler/spec_set.rb | 4 ---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 3e93b451710029..34c23796e8fb78 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -524,10 +524,8 @@ def materialize(dependencies) end end - unless specs["bundler"].any? - bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last - specs["bundler"] = bundler - end + bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last + specs["bundler"] = bundler specs end diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 4e339ffe914215..de2ad973302731 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -35,10 +35,6 @@ def for(dependencies, check = false, platforms = [nil]) end end - if spec = lookup["bundler"].first - specs << spec - end - specs end From ed9bbfd7594f655702461067e3dc8106eec52385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 11:58:53 +0200 Subject: [PATCH 101/142] [rubygems/rubygems] Fix incorrect force_ruby_platform propagation It was just working by chance. (cherry picked from commit https://github.com/rubygems/rubygems/commit/16b2d6bfe893) https://github.com/rubygems/rubygems/commit/8f922d980f --- lib/bundler/rubygems_ext.rb | 4 ++++ lib/bundler/spec_set.rb | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index e8e03fcf8f49eb..938c58e64d855d 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -155,6 +155,10 @@ class Dependency alias_method :eql?, :== + def force_ruby_platform + false + end + def encode_with(coder) to_yaml_properties.each do |ivar| coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar) diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index de2ad973302731..6a3813eef8a286 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -13,14 +13,16 @@ def initialize(specs) def for(dependencies, check = false, platforms = [nil]) handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h - deps = dependencies.product(platforms).map {|dep, platform| [dep.name, platform && dep.force_ruby_platform ? Gem::Platform::RUBY : platform] } + deps = dependencies.product(platforms) specs = [] loop do break unless dep = deps.shift - next if handled.key?(dep) - handled[dep] = true + key = [dep[0].name, dep[1]] + next if handled.key?(key) + + handled[key] = true specs_for_dep = specs_for_dependency(*dep) if specs_for_dep.any? @@ -28,10 +30,10 @@ def for(dependencies, check = false, platforms = [nil]) specs_for_dep.first.dependencies.each do |d| next if d.type == :development - deps << [d.name, dep[1]] + deps << [d, dep[1]] end elsif check - specs << IncompleteSpecification.new(*dep) + specs << IncompleteSpecification.new(*key) end end @@ -175,13 +177,12 @@ def tsort_each_node @specs.sort_by(&:name).each {|s| yield s } end - def specs_for_dependency(name, platform) - specs_for_name = lookup[name] + def specs_for_dependency(dep, platform) + specs_for_name = lookup[dep.name] if platform.nil? GemHelpers.select_best_platform_match(specs_for_name.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform) else - specs_for_name_and_platform = GemHelpers.select_best_platform_match(specs_for_name, platform) - specs_for_name_and_platform.any? ? specs_for_name_and_platform : specs_for_name + GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : platform) end end From 35e508d13e6d936af7725ccf9ac15deb69e35257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 20:56:17 +0200 Subject: [PATCH 102/142] [rubygems/rubygems] Refactor materialization conditions https://github.com/rubygems/rubygems/commit/08e1554fb6 --- lib/bundler/lazy_specification.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index ff9444e0091c98..fdf37fd7a4d513 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -91,10 +91,10 @@ def __materialize__(platform) @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name source.gemspec.tap {|s| s.source = source } else - search_object = if source.is_a?(Source::Path) + search_object = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? Dependency.new(name, version) else - ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version) + self end candidates = source.specs.search(search_object) same_platform_candidates = candidates.select do |spec| From 91b9bd62347dbb0971904593a11320d64076a1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 25 Jul 2022 11:14:06 +0200 Subject: [PATCH 103/142] [rubygems/rubygems] This should go through the standard source search logic https://github.com/rubygems/rubygems/commit/087e3e4e3b --- lib/bundler/lazy_specification.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index fdf37fd7a4d513..3d704a7f1256ec 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -88,9 +88,7 @@ def materialize_for_resolution end def __materialize__(platform) - @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name - source.gemspec.tap {|s| s.source = source } - else + @specification = begin search_object = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? Dependency.new(name, version) else From bc0de1e16250ecb4e8278ec64de86fbc049c5e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 13:47:58 +0200 Subject: [PATCH 104/142] [rubygems/rubygems] Only need to filter platforms when materialization is not strict https://github.com/rubygems/rubygems/commit/9d878cbda0 --- lib/bundler/lazy_specification.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 3d704a7f1256ec..4a7f528119d1b3 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -89,21 +89,19 @@ def materialize_for_resolution def __materialize__(platform) @specification = begin - search_object = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? - Dependency.new(name, version) + candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? + source.specs.search(Dependency.new(name, version)).select do |spec| + MatchPlatform.platforms_match?(spec.platform, platform) + end else - self + source.specs.search(self) end - candidates = source.specs.search(search_object) - same_platform_candidates = candidates.select do |spec| - MatchPlatform.platforms_match?(spec.platform, platform) - end - installable_candidates = same_platform_candidates.select do |spec| + installable_candidates = candidates.select do |spec| spec.is_a?(StubSpecification) || (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) end - search = installable_candidates.last || same_platform_candidates.last + search = installable_candidates.last || candidates.last search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) search end From 5487e76374c5ee247b0f5a2867a6dc1319d98e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 29 Jul 2022 21:17:59 +0200 Subject: [PATCH 105/142] [rubygems/rubygems] Prefer reverse+find to select+last https://github.com/rubygems/rubygems/commit/ffb161bb69 --- lib/bundler/lazy_specification.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 4a7f528119d1b3..7245692546b5a3 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -96,12 +96,12 @@ def __materialize__(platform) else source.specs.search(self) end - installable_candidates = candidates.select do |spec| + best_installable_candidate = candidates.reverse.find do |spec| spec.is_a?(StubSpecification) || (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) end - search = installable_candidates.last || candidates.last + search = best_installable_candidate || candidates.last search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) search end From 8c98f7be577389f01a90c7a39d693173d432e9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 29 Jul 2022 22:39:38 +0200 Subject: [PATCH 106/142] [rubygems/rubygems] Remove unnecessary local variable https://github.com/rubygems/rubygems/commit/a997210473 --- lib/bundler/lazy_specification.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 7245692546b5a3..05925e3e79a75f 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -96,12 +96,11 @@ def __materialize__(platform) else source.specs.search(self) end - best_installable_candidate = candidates.reverse.find do |spec| + search = candidates.reverse.find do |spec| spec.is_a?(StubSpecification) || (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) - end - search = best_installable_candidate || candidates.last + end || candidates.last search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) search end From 9189c2d5efa94131050df4994c801fb187d7b43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 29 Jul 2022 22:09:51 +0200 Subject: [PATCH 107/142] [rubygems/rubygems] Materializing for resolution already filters platforms https://github.com/rubygems/rubygems/commit/9f4ba9ebb0 --- lib/bundler/lazy_specification.rb | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 05925e3e79a75f..805afba51fb126 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -78,24 +78,29 @@ def to_lock def materialize_for_installation source.local! - __materialize__(ruby_platform_materializes_to_ruby_platform? ? platform : Bundler.local_platform) + candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? + target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : Bundler.local_platform + + source.specs.search(Dependency.new(name, version)).select do |spec| + MatchPlatform.platforms_match?(spec.platform, target_platform) + end + else + source.specs.search(self) + end + + __materialize__(candidates) end def materialize_for_resolution return self unless Gem::Platform.match_spec?(self) - __materialize__(platform) + candidates = source.specs.search(self) + + __materialize__(candidates) end - def __materialize__(platform) + def __materialize__(candidates) @specification = begin - candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? - source.specs.search(Dependency.new(name, version)).select do |spec| - MatchPlatform.platforms_match?(spec.platform, platform) - end - else - source.specs.search(self) - end search = candidates.reverse.find do |spec| spec.is_a?(StubSpecification) || (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && From f4f681463f71c2fc63e1a07f36f2665f2b9db002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 23 Jul 2022 08:44:47 +0200 Subject: [PATCH 108/142] [rubygems/rubygems] Don't discard candidates matching ruby metadata Do dependency filtering and materialization in one step. Before, dependency filtering would not consider ruby metadata so it would discard variants that end up not being materializable in the end. https://github.com/rubygems/rubygems/commit/0c0d40d417 Co-authored-by: Ian Ker-Seymer --- lib/bundler/gem_helpers.rb | 8 +++- lib/bundler/lazy_specification.rb | 6 ++- lib/bundler/spec_set.rb | 7 +-- .../install/gemfile/specific_platform_spec.rb | 47 +++++++++++++++++++ spec/bundler/install/gems/resolving_spec.rb | 22 +++++++-- 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb index 6bc4fb4991fb50..0d50d8687b90b5 100644 --- a/lib/bundler/gem_helpers.rb +++ b/lib/bundler/gem_helpers.rb @@ -44,6 +44,12 @@ def platform_specificity_match(spec_platform, user_platform) def select_best_platform_match(specs, platform) matching = specs.select {|spec| spec.match_platform(platform) } + + sort_best_platform_match(matching, platform) + end + module_function :select_best_platform_match + + def sort_best_platform_match(matching, platform) exact = matching.select {|spec| spec.platform == platform } return exact if exact.any? @@ -52,7 +58,7 @@ def select_best_platform_match(specs, platform) sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) } end - module_function :select_best_platform_match + module_function :sort_best_platform_match class PlatformMatch def self.specificity_score(spec_platform, user_platform) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 805afba51fb126..a88172d96b852e 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -88,6 +88,8 @@ def materialize_for_installation source.specs.search(self) end + return self if candidates.empty? + __materialize__(candidates) end @@ -105,8 +107,8 @@ def __materialize__(candidates) spec.is_a?(StubSpecification) || (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) - end || candidates.last - search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + end + search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) search end end diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 6a3813eef8a286..e21a3ea6f5b0d1 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -66,10 +66,6 @@ def to_hash def materialize(deps) materialized = self.for(deps, true).uniq - materialized.map! do |s| - next s unless s.is_a?(LazySpecification) - s.materialize_for_installation || s - end SpecSet.new(materialized) end @@ -180,7 +176,8 @@ def tsort_each_node def specs_for_dependency(dep, platform) specs_for_name = lookup[dep.name] if platform.nil? - GemHelpers.select_best_platform_match(specs_for_name.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform) + matching_specs = specs_for_name.map {|s| s.materialize_for_installation if Gem::Platform.match_spec?(s) }.compact + GemHelpers.sort_best_platform_match(matching_specs, Bundler.local_platform) else GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : platform) end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 6994cb2af15863..48349aaef4353a 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -374,6 +374,41 @@ ERROR end + it "can fallback to a source gem when platform gems are incompatible with current ruby version" do + setup_multiplatform_gem_with_source_gem + + source = file_uri_for(gem_repo2) + + gemfile <<~G + source "#{source}" + + gem "my-precompiled-gem" + G + + # simulate lockfile which includes both a precompiled gem with: + # - Gem the current platform (with imcompatible ruby version) + # - A source gem with compatible ruby version + lockfile <<-L + GEM + remote: #{source}/ + specs: + my-precompiled-gem (3.0.0) + my-precompiled-gem (3.0.0-#{Bundler.local_platform}) + + PLATFORMS + ruby + #{Bundler.local_platform} + + DEPENDENCIES + my-precompiled-gem + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle :install + end + private def setup_multiplatform_gem @@ -404,4 +439,16 @@ def setup_multiplatform_gem_with_different_dependencies_per_platform build_gem("CFPropertyList") end end + + def setup_multiplatform_gem_with_source_gem + build_repo2 do + build_gem("my-precompiled-gem", "3.0.0") + build_gem("my-precompiled-gem", "3.0.0") do |s| + s.platform = Bundler.local_platform + + # purposely unresolvable + s.required_ruby_version = ">= 1000.0.0" + end + end + end end diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index 1679ad4460499d..a55db83dc47f27 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -241,7 +241,7 @@ expect(the_bundle).to include_gems("rack 1.2") end - it "gives a meaningful error if there's a lockfile using the newer incompatible version" do + it "automatically updates lockfile to use the older version" do build_repo2 do build_gem "parallel_tests", "3.7.0" do |s| s.required_ruby_version = ">= #{current_ruby_minor}" @@ -273,9 +273,23 @@ #{Bundler::VERSION} L - bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false - expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}") - expect(err).not_to include("That means the author of parallel_tests (3.8.0) has removed it.") + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + + expect(lockfile).to eq <<~L + GEM + remote: http://localgemserver.test/ + specs: + parallel_tests (3.7.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + parallel_tests + + BUNDLED WITH + #{Bundler::VERSION} + L end it "gives a meaningful error on ruby version mismatches between dependencies" do From bc90090672450a4ba3ba1025fbbad8991ee84b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 30 Jul 2022 21:41:49 +0200 Subject: [PATCH 109/142] [rubygems/rubygems] Check for errors in error stream https://github.com/rubygems/rubygems/commit/7b0f7804f2 --- spec/bundler/install/gems/resolving_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index a55db83dc47f27..069fa273b43a4f 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -216,7 +216,7 @@ gem 'rack' G - expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") expect(the_bundle).to include_gems("rack 1.2") end @@ -237,7 +237,7 @@ gem 'rack' G - expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") expect(the_bundle).to include_gems("rack 1.2") end @@ -329,7 +329,7 @@ gem 'foo1' G - expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") expect(the_bundle).to include_gems("rack 1.2") end @@ -353,8 +353,8 @@ G end - expect(out).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(out).to_not include("rack-1.2-#{Bundler.local_platform} requires ruby version > 9000") + expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("rack-1.2-#{Bundler.local_platform} requires ruby version > 9000") expect(the_bundle).to include_gems("rack 1.2") end end From 3e4fedca4e0b068908137d44bcf5a567cb8445d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 30 Jul 2022 10:07:45 +0200 Subject: [PATCH 110/142] [rubygems/rubygems] Preserve the previous behavior of raising an error when in frozen mode https://github.com/rubygems/rubygems/commit/6e35a6edfe --- lib/bundler/lazy_specification.rb | 6 +- spec/bundler/install/gems/resolving_spec.rb | 87 ++++++++++++--------- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index a88172d96b852e..9f75c7bab263a5 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -108,7 +108,11 @@ def __materialize__(candidates) (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) end - search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + if search.nil? && Bundler.frozen_bundle? + search = candidates.last + else + search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + end search end end diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index 069fa273b43a4f..9c0d6bfe56cba7 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -241,55 +241,68 @@ expect(the_bundle).to include_gems("rack 1.2") end - it "automatically updates lockfile to use the older version" do - build_repo2 do - build_gem "parallel_tests", "3.7.0" do |s| - s.required_ruby_version = ">= #{current_ruby_minor}" - end + context "when there is a lockfile using the newer incompatible version" do + before do + build_repo2 do + build_gem "parallel_tests", "3.7.0" do |s| + s.required_ruby_version = ">= #{current_ruby_minor}" + end - build_gem "parallel_tests", "3.8.0" do |s| - s.required_ruby_version = ">= #{next_ruby_minor}" + build_gem "parallel_tests", "3.8.0" do |s| + s.required_ruby_version = ">= #{next_ruby_minor}" + end end - end - gemfile <<-G - source "http://localgemserver.test/" - gem 'parallel_tests' - G + gemfile <<-G + source "http://localgemserver.test/" + gem 'parallel_tests' + G - lockfile <<~L - GEM - remote: http://localgemserver.test/ - specs: - parallel_tests (3.8.0) + lockfile <<~L + GEM + remote: http://localgemserver.test/ + specs: + parallel_tests (3.8.0) - PLATFORMS - #{lockfile_platforms} + PLATFORMS + #{lockfile_platforms} - DEPENDENCIES - parallel_tests + DEPENDENCIES + parallel_tests - BUNDLED WITH - #{Bundler::VERSION} - L + BUNDLED WITH + #{Bundler::VERSION} + L + end - bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + it "automatically updates lockfile to use the older version" do + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } - expect(lockfile).to eq <<~L - GEM - remote: http://localgemserver.test/ - specs: - parallel_tests (3.7.0) + expect(lockfile).to eq <<~L + GEM + remote: http://localgemserver.test/ + specs: + parallel_tests (3.7.0) - PLATFORMS - #{lockfile_platforms} + PLATFORMS + #{lockfile_platforms} - DEPENDENCIES - parallel_tests + DEPENDENCIES + parallel_tests - BUNDLED WITH - #{Bundler::VERSION} - L + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "gives a meaningful error if we're in frozen mode" do + expect do + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s, "BUNDLE_FROZEN" => "true" }, :raise_on_error => false + end.not_to change { lockfile } + + expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}") + expect(err).not_to include("That means the author of parallel_tests (3.8.0) has removed it.") + end end it "gives a meaningful error on ruby version mismatches between dependencies" do From ec3f59309e3f08339c4c76a6881901580801d6cd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 20 Jul 2022 19:19:23 +0900 Subject: [PATCH 111/142] [Bug #17767] Now `ENV.clone` raises `TypeError` as well as `ENV.dup` One year ago, the former method has been deprecated while the latter has become an error. Then the 3.1 released, it is enough time to make also the former an error. --- hash.c | 21 ++++++++----------- test/ruby/test_env.rb | 48 ++++++------------------------------------- 2 files changed, 14 insertions(+), 55 deletions(-) diff --git a/hash.c b/hash.c index 69a768d4ce1cce..8c20791ede41fd 100644 --- a/hash.c +++ b/hash.c @@ -6639,31 +6639,26 @@ env_update(int argc, VALUE *argv, VALUE env) return env; } +NORETURN(static VALUE env_clone(int, VALUE *, VALUE)); /* * call-seq: - * ENV.clone(freeze: nil) -> ENV + * ENV.clone(freeze: nil) # raises TypeError * - * Returns ENV itself, and warns because ENV is a wrapper for the - * process-wide environment variables and a clone is useless. - * If +freeze+ keyword is given and not +nil+ or +false+, raises ArgumentError. - * If +freeze+ keyword is given and +true+, raises TypeError, as ENV storage - * cannot be frozen. + * Raises TypeError, because ENV is a wrapper for the process-wide + * environment variables and a clone is useless. + * Use #to_h to get a copy of ENV data as a hash. */ static VALUE env_clone(int argc, VALUE *argv, VALUE obj) { if (argc) { - VALUE opt, kwfreeze; + VALUE opt; if (rb_scan_args(argc, argv, "0:", &opt) < argc) { - kwfreeze = rb_get_freeze_opt(1, &opt); - if (RTEST(kwfreeze)) { - rb_raise(rb_eTypeError, "cannot freeze ENV"); - } + rb_get_freeze_opt(1, &opt); } } - rb_warn_deprecated("ENV.clone", "ENV.to_h"); - return envtbl; + rb_raise(rb_eTypeError, "Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash"); } NORETURN(static VALUE env_dup(VALUE)); diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb index e9eaf144a1eeb2..cdadeac14886e8 100644 --- a/test/ruby/test_env.rb +++ b/test/ruby/test_env.rb @@ -69,25 +69,20 @@ def test_dup end def test_clone - warning = /ENV\.clone is deprecated; use ENV\.to_h instead/ - clone = assert_deprecated_warning(warning) { + message = /Cannot clone ENV/ + assert_raise_with_message(TypeError, message) { ENV.clone } - assert_same(ENV, clone) - - clone = assert_deprecated_warning(warning) { + assert_raise_with_message(TypeError, message) { ENV.clone(freeze: false) } - assert_same(ENV, clone) - - clone = assert_deprecated_warning(warning) { + assert_raise_with_message(TypeError, message) { ENV.clone(freeze: nil) } - assert_same(ENV, clone) - - assert_raise(TypeError) { + assert_raise_with_message(TypeError, message) { ENV.clone(freeze: true) } + assert_raise(ArgumentError) { ENV.clone(freeze: 1) } @@ -688,37 +683,6 @@ def test_dup_in_ractor end; end - def test_clone_in_ractor - assert_ractor(<<-"end;") - r = Ractor.new do - original_warning_state = Warning[:deprecated] - Warning[:deprecated] = false - - begin - Ractor.yield ENV.clone.object_id - Ractor.yield ENV.clone(freeze: false).object_id - Ractor.yield ENV.clone(freeze: nil).object_id - - #{str_for_yielding_exception_class("ENV.clone(freeze: true)")} - #{str_for_yielding_exception_class("ENV.clone(freeze: 1)")} - #{str_for_yielding_exception_class("ENV.clone(foo: false)")} - #{str_for_yielding_exception_class("ENV.clone(1)")} - #{str_for_yielding_exception_class("ENV.clone(1, foo: false)")} - - ensure - Warning[:deprecated] = original_warning_state - end - end - assert_equal(ENV.object_id, r.take) - assert_equal(ENV.object_id, r.take) - assert_equal(ENV.object_id, r.take) - #{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")} - 4.times do - #{str_for_assert_raise_on_yielded_exception_class(ArgumentError, "r")} - end - end; - end - def test_has_value_in_ractor assert_ractor(<<-"end;") r = Ractor.new do From e3aabe93aae87a60ba7b8f1a0fd590534647e352 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 26 Jul 2022 17:40:00 +0200 Subject: [PATCH 112/142] Implement Queue#pop(timeout: sec) [Feature #18774] As well as `SizedQueue#pop(timeout: sec)` If both `non_block=true` and `timeout:` are supplied, ArgumentError is raised. --- .document | 1 + common.mk | 5 ++ hrtime.h | 10 +++ inits.c | 1 + spec/ruby/shared/queue/deque.rb | 55 +++++++++++++++++ test/ruby/test_settracefunc.rb | 21 +++---- test/ruby/test_thread_queue.rb | 35 +++++++++++ thread.c | 35 +++++++++-- thread_sync.c | 105 ++++++++++++++------------------ thread_sync.rb | 45 ++++++++++++++ 10 files changed, 238 insertions(+), 75 deletions(-) create mode 100644 thread_sync.rb diff --git a/.document b/.document index 5494bcc7feea95..ec2fa093261427 100644 --- a/.document +++ b/.document @@ -24,6 +24,7 @@ pack.rb ractor.rb string.rb timev.rb +thread_sync.rb trace_point.rb warning.rb diff --git a/common.mk b/common.mk index aeb87dfb553c71..4c49690e4abcdf 100644 --- a/common.mk +++ b/common.mk @@ -1062,6 +1062,7 @@ BUILTIN_RB_SRCS = \ $(srcdir)/kernel.rb \ $(srcdir)/ractor.rb \ $(srcdir)/timev.rb \ + $(srcdir)/thread_sync.rb \ $(srcdir)/nilclass.rb \ $(srcdir)/prelude.rb \ $(srcdir)/gem_prelude.rb \ @@ -9447,6 +9448,7 @@ miniinit.$(OBJEXT): {$(VPATH)}st.h miniinit.$(OBJEXT): {$(VPATH)}subst.h miniinit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h miniinit.$(OBJEXT): {$(VPATH)}thread_native.h +miniinit.$(OBJEXT): {$(VPATH)}thread_sync.rb miniinit.$(OBJEXT): {$(VPATH)}timev.rb miniinit.$(OBJEXT): {$(VPATH)}trace_point.rb miniinit.$(OBJEXT): {$(VPATH)}vm_core.h @@ -15230,6 +15232,7 @@ thread.$(OBJEXT): {$(VPATH)}backward/2/limits.h thread.$(OBJEXT): {$(VPATH)}backward/2/long_long.h thread.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h thread.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +thread.$(OBJEXT): {$(VPATH)}builtin.h thread.$(OBJEXT): {$(VPATH)}config.h thread.$(OBJEXT): {$(VPATH)}debug.h thread.$(OBJEXT): {$(VPATH)}debug_counter.h @@ -15412,6 +15415,8 @@ thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).c thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h thread.$(OBJEXT): {$(VPATH)}thread_native.h thread.$(OBJEXT): {$(VPATH)}thread_sync.c +thread.$(OBJEXT): {$(VPATH)}thread_sync.rb +thread.$(OBJEXT): {$(VPATH)}thread_sync.rbinc thread.$(OBJEXT): {$(VPATH)}timev.h thread.$(OBJEXT): {$(VPATH)}vm_core.h thread.$(OBJEXT): {$(VPATH)}vm_debug.h diff --git a/hrtime.h b/hrtime.h index 4ac3d5472361a8..80aff5deb36b4d 100644 --- a/hrtime.h +++ b/hrtime.h @@ -36,6 +36,7 @@ #define RB_HRTIME_PER_MSEC (RB_HRTIME_PER_USEC * (rb_hrtime_t)1000) #define RB_HRTIME_PER_SEC (RB_HRTIME_PER_MSEC * (rb_hrtime_t)1000) #define RB_HRTIME_MAX UINT64_MAX +#define RB_HRTIME_MIN ((rb_hrtime_t)0) /* * Lets try to support time travelers. Lets assume anybody with a time machine @@ -91,6 +92,15 @@ rb_hrtime_add(rb_hrtime_t a, rb_hrtime_t b) return c; } +static inline rb_hrtime_t +rb_hrtime_sub(rb_hrtime_t a, rb_hrtime_t b) +{ + if (a < b) { + return RB_HRTIME_MIN; + } + return a - b; +} + /* * convert a timeval struct to rb_hrtime_t, clamping at RB_HRTIME_MAX */ diff --git a/inits.c b/inits.c index f41e88d8387bc5..22ba6d5a8c33c0 100644 --- a/inits.c +++ b/inits.c @@ -98,6 +98,7 @@ rb_call_builtin_inits(void) BUILTIN(array); BUILTIN(kernel); BUILTIN(timev); + BUILTIN(thread_sync); BUILTIN(yjit); BUILTIN(nilclass); BUILTIN(marshal); diff --git a/spec/ruby/shared/queue/deque.rb b/spec/ruby/shared/queue/deque.rb index 8b755dd9b7a1ee..ed32bd29c88b61 100644 --- a/spec/ruby/shared/queue/deque.rb +++ b/spec/ruby/shared/queue/deque.rb @@ -55,6 +55,61 @@ t.join end + describe "with a timeout" do + ruby_version_is "3.2" do + it "returns an item if one is available in time" do + q = @object.call + + t = Thread.new { + q.send(@method, timeout: 1).should == 1 + } + Thread.pass until t.status == "sleep" && q.num_waiting == 1 + q << 1 + t.join + end + + it "returns nil if no item is available in time" do + q = @object.call + + t = Thread.new { + q.send(@method, timeout: 0.1).should == nil + } + t.join + end + + it "does nothing if the timeout is nil" do + q = @object.call + t = Thread.new { + q.send(@method, timeout: nil).should == 1 + } + t.join(0.2).should == nil + q << 1 + t.join + end + + it "raise TypeError if timeout is not a valid numeric" do + q = @object.call + -> { q.send(@method, timeout: "1") }.should raise_error( + TypeError, + "no implicit conversion to float from string", + ) + + -> { q.send(@method, timeout: false) }.should raise_error( + TypeError, + "no implicit conversion to float from false", + ) + end + + it "raise ArgumentError if non_block = true is passed too" do + q = @object.call + -> { q.send(@method, true, timeout: 1) }.should raise_error( + ArgumentError, + "can't set a timeout if non_block is enabled", + ) + end + end + end + describe "in non-blocking mode" do it "removes an item from the queue" do q = @object.call diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 56d457c7d7f4b8..31946c8b719cdb 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -2140,17 +2140,16 @@ def test_thread_add_trace_func m2t_q.push 1 t.join - assert_equal ["c-return", base_line + 31], events[0] - assert_equal ["line", base_line + 32], events[1] - assert_equal ["line", base_line + 33], events[2] - assert_equal ["call", base_line + -6], events[3] - assert_equal ["return", base_line + -4], events[4] - assert_equal ["line", base_line + 34], events[5] - assert_equal ["line", base_line + 35], events[6] - assert_equal ["c-call", base_line + 35], events[7] # Thread.current - assert_equal ["c-return", base_line + 35], events[8] # Thread.current - assert_equal ["c-call", base_line + 35], events[9] # Thread#set_trace_func - assert_equal nil, events[10] + assert_equal ["line", base_line + 32], events[0] + assert_equal ["line", base_line + 33], events[1] + assert_equal ["call", base_line + -6], events[2] + assert_equal ["return", base_line + -4], events[3] + assert_equal ["line", base_line + 34], events[4] + assert_equal ["line", base_line + 35], events[5] + assert_equal ["c-call", base_line + 35], events[6] # Thread.current + assert_equal ["c-return", base_line + 35], events[7] # Thread.current + assert_equal ["c-call", base_line + 35], events[8] # Thread#set_trace_func + assert_equal nil, events[9] end def test_lineno_in_optimized_insn diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb index ebf7ded3b9beb0..aa4ea0a4009d86 100644 --- a/test/ruby/test_thread_queue.rb +++ b/test/ruby/test_thread_queue.rb @@ -111,6 +111,23 @@ def test_queue_pop_interrupt assert_equal(0, q.num_waiting) end + def test_queue_pop_timeout + q = Thread::Queue.new + q << 1 + assert_equal 1, q.pop(timeout: 1) + + t1 = Thread.new { q.pop(timeout: 1) } + assert_equal t1, t1.join(2) + assert_nil t1.value + + t2 = Thread.new { q.pop(timeout: 0.1) } + assert_equal t2, t2.join(0.2) + assert_nil t2.value + ensure + t1&.kill + t2&.kill + end + def test_queue_pop_non_block q = Thread::Queue.new assert_raise_with_message(ThreadError, /empty/) do @@ -126,6 +143,24 @@ def test_sized_queue_pop_interrupt assert_equal(0, q.num_waiting) end + def test_sized_queue_pop_timeout + q = Thread::SizedQueue.new(1) + + q << 1 + assert_equal 1, q.pop(timeout: 1) + + t1 = Thread.new { q.pop(timeout: 1) } + assert_equal t1, t1.join(2) + assert_nil t1.value + + t2 = Thread.new { q.pop(timeout: 0.1) } + assert_equal t2, t2.join(0.2) + assert_nil t2.value + ensure + t1&.kill + t2&.kill + end + def test_sized_queue_pop_non_block q = Thread::SizedQueue.new(1) assert_raise_with_message(ThreadError, /empty/) do diff --git a/thread.c b/thread.c index 411b6d70841f8b..feb89d435271ae 100644 --- a/thread.c +++ b/thread.c @@ -132,7 +132,7 @@ rb_thread_local_storage(VALUE thread) static int sleep_hrtime(rb_thread_t *, rb_hrtime_t, unsigned int fl); static void sleep_forever(rb_thread_t *th, unsigned int fl); -static void rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker); +static void rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker, VALUE timeout, rb_hrtime_t end); static int rb_threadptr_dead(rb_thread_t *th); static void rb_check_deadlock(rb_ractor_t *r); static int rb_threadptr_pending_interrupt_empty_p(const rb_thread_t *th); @@ -1328,6 +1328,28 @@ sleep_hrtime(rb_thread_t *th, rb_hrtime_t rel, unsigned int fl) return woke; } +static int +sleep_hrtime_until(rb_thread_t *th, rb_hrtime_t end, unsigned int fl) +{ + enum rb_thread_status prev_status = th->status; + int woke; + rb_hrtime_t rel = rb_hrtime_sub(end, rb_hrtime_now()); + + th->status = THREAD_STOPPED; + RUBY_VM_CHECK_INTS_BLOCKING(th->ec); + while (th->status == THREAD_STOPPED) { + native_sleep(th, &rel); + woke = vm_check_ints_blocking(th->ec); + if (woke && !(fl & SLEEP_SPURIOUS_CHECK)) + break; + if (hrtime_update_expire(&rel, end)) + break; + woke = 1; + } + th->status = prev_status; + return woke; +} + void rb_thread_sleep_forever(void) { @@ -1355,15 +1377,20 @@ rb_thread_sleep_interruptible(void) } static void -rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker) +rb_thread_sleep_deadly_allow_spurious_wakeup(VALUE blocker, VALUE timeout, rb_hrtime_t end) { VALUE scheduler = rb_fiber_scheduler_current(); if (scheduler != Qnil) { - rb_fiber_scheduler_block(scheduler, blocker, Qnil); + rb_fiber_scheduler_block(scheduler, blocker, timeout); } else { RUBY_DEBUG_LOG("%s", ""); - sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE); + if (end) { + sleep_hrtime_until(GET_THREAD(), end, SLEEP_SPURIOUS_CHECK); + } + else { + sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE); + } } } diff --git a/thread_sync.c b/thread_sync.c index 5ff36dd01de7fe..1a0f3ee8555c1f 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -1,5 +1,6 @@ /* included by thread.c */ #include "ccan/list/list.h" +#include "builtin.h" static VALUE rb_cMutex, rb_cQueue, rb_cSizedQueue, rb_cConditionVariable; static VALUE rb_eClosedQueueError; @@ -19,6 +20,12 @@ struct sync_waiter { struct ccan_list_node node; }; +struct queue_sleep_arg { + VALUE self; + VALUE timeout; + rb_hrtime_t end; +}; + #define MUTEX_ALLOW_TRAP FL_USER1 static void @@ -514,7 +521,7 @@ rb_mutex_abandon_all(rb_mutex_t *mutexes) static VALUE rb_mutex_sleep_forever(VALUE self) { - rb_thread_sleep_deadly_allow_spurious_wakeup(self); + rb_thread_sleep_deadly_allow_spurious_wakeup(self, Qnil, 0); return Qnil; } @@ -706,6 +713,21 @@ queue_ptr(VALUE obj) #define QUEUE_CLOSED FL_USER5 +static rb_hrtime_t +queue_timeout2hrtime(VALUE timeout) { + if (NIL_P(timeout)) { + return (rb_hrtime_t)0; + } + rb_hrtime_t rel = 0; + if (FIXNUM_P(timeout)) { + rel = rb_sec2hrtime(NUM2TIMET(timeout)); + } + else { + double2hrtime(&rel, rb_num2dbl(timeout)); + } + return rb_hrtime_add(rel, rb_hrtime_now()); +} + static void szqueue_mark(void *ptr) { @@ -964,9 +986,10 @@ rb_queue_push(VALUE self, VALUE obj) } static VALUE -queue_sleep(VALUE self) +queue_sleep(VALUE _args) { - rb_thread_sleep_deadly_allow_spurious_wakeup(self); + struct queue_sleep_arg *args = (struct queue_sleep_arg *)_args; + rb_thread_sleep_deadly_allow_spurious_wakeup(args->self, args->timeout, args->end); return Qnil; } @@ -1001,9 +1024,10 @@ szqueue_sleep_done(VALUE p) } static VALUE -queue_do_pop(VALUE self, struct rb_queue *q, int should_block) +queue_do_pop(VALUE self, struct rb_queue *q, int should_block, VALUE timeout) { check_array(self, q->que); + rb_hrtime_t end = queue_timeout2hrtime(timeout); while (RARRAY_LEN(q->que) == 0) { if (!should_block) { @@ -1028,43 +1052,25 @@ queue_do_pop(VALUE self, struct rb_queue *q, int should_block) ccan_list_add_tail(waitq, &queue_waiter.w.node); queue_waiter.as.q->num_waiting++; - rb_ensure(queue_sleep, self, queue_sleep_done, (VALUE)&queue_waiter); + struct queue_sleep_arg queue_sleep_arg = { + .self = self, + .timeout = timeout, + .end = end + }; + + rb_ensure(queue_sleep, (VALUE)&queue_sleep_arg, queue_sleep_done, (VALUE)&queue_waiter); + if (!NIL_P(timeout) && (rb_hrtime_now() >= end)) + break; } } return rb_ary_shift(q->que); } -static int -queue_pop_should_block(int argc, const VALUE *argv) -{ - int should_block = 1; - rb_check_arity(argc, 0, 1); - if (argc > 0) { - should_block = !RTEST(argv[0]); - } - return should_block; -} - -/* - * Document-method: Thread::Queue#pop - * call-seq: - * pop(non_block=false) - * deq(non_block=false) - * shift(non_block=false) - * - * Retrieves data from the queue. - * - * If the queue is empty, the calling thread is suspended until data is pushed - * onto the queue. If +non_block+ is true, the thread isn't suspended, and - * +ThreadError+ is raised. - */ - static VALUE -rb_queue_pop(int argc, VALUE *argv, VALUE self) +rb_queue_pop(rb_execution_context_t *ec, VALUE self, VALUE non_block, VALUE timeout) { - int should_block = queue_pop_should_block(argc, argv); - return queue_do_pop(self, queue_ptr(self), should_block); + return queue_do_pop(self, queue_ptr(self), !RTEST(non_block), timeout); } /* @@ -1283,10 +1289,10 @@ rb_szqueue_push(int argc, VALUE *argv, VALUE self) } static VALUE -szqueue_do_pop(VALUE self, int should_block) +szqueue_do_pop(VALUE self, int should_block, VALUE timeout) { struct rb_szqueue *sq = szqueue_ptr(self); - VALUE retval = queue_do_pop(self, &sq->q, should_block); + VALUE retval = queue_do_pop(self, &sq->q, should_block, timeout); if (queue_length(self, &sq->q) < sq->max) { wakeup_one(szqueue_pushq(sq)); @@ -1294,26 +1300,10 @@ szqueue_do_pop(VALUE self, int should_block) return retval; } - -/* - * Document-method: Thread::SizedQueue#pop - * call-seq: - * pop(non_block=false) - * deq(non_block=false) - * shift(non_block=false) - * - * Retrieves data from the queue. - * - * If the queue is empty, the calling thread is suspended until data is pushed - * onto the queue. If +non_block+ is true, the thread isn't suspended, and - * +ThreadError+ is raised. - */ - static VALUE -rb_szqueue_pop(int argc, VALUE *argv, VALUE self) +rb_szqueue_pop(rb_execution_context_t *ec, VALUE self, VALUE non_block, VALUE timeout) { - int should_block = queue_pop_should_block(argc, argv); - return szqueue_do_pop(self, should_block); + return szqueue_do_pop(self, !RTEST(non_block), timeout); } /* @@ -1597,7 +1587,6 @@ Init_thread_sync(void) rb_define_method(rb_cQueue, "close", rb_queue_close, 0); rb_define_method(rb_cQueue, "closed?", rb_queue_closed_p, 0); rb_define_method(rb_cQueue, "push", rb_queue_push, 1); - rb_define_method(rb_cQueue, "pop", rb_queue_pop, -1); rb_define_method(rb_cQueue, "empty?", rb_queue_empty_p, 0); rb_define_method(rb_cQueue, "clear", rb_queue_clear, 0); rb_define_method(rb_cQueue, "length", rb_queue_length, 0); @@ -1605,8 +1594,6 @@ Init_thread_sync(void) rb_define_alias(rb_cQueue, "enq", "push"); rb_define_alias(rb_cQueue, "<<", "push"); - rb_define_alias(rb_cQueue, "deq", "pop"); - rb_define_alias(rb_cQueue, "shift", "pop"); rb_define_alias(rb_cQueue, "size", "length"); DEFINE_CLASS(SizedQueue, Queue); @@ -1617,16 +1604,12 @@ Init_thread_sync(void) rb_define_method(rb_cSizedQueue, "max", rb_szqueue_max_get, 0); rb_define_method(rb_cSizedQueue, "max=", rb_szqueue_max_set, 1); rb_define_method(rb_cSizedQueue, "push", rb_szqueue_push, -1); - rb_define_method(rb_cSizedQueue, "pop", rb_szqueue_pop, -1); rb_define_method(rb_cSizedQueue, "empty?", rb_szqueue_empty_p, 0); rb_define_method(rb_cSizedQueue, "clear", rb_szqueue_clear, 0); rb_define_method(rb_cSizedQueue, "length", rb_szqueue_length, 0); rb_define_method(rb_cSizedQueue, "num_waiting", rb_szqueue_num_waiting, 0); - rb_define_alias(rb_cSizedQueue, "enq", "push"); rb_define_alias(rb_cSizedQueue, "<<", "push"); - rb_define_alias(rb_cSizedQueue, "deq", "pop"); - rb_define_alias(rb_cSizedQueue, "shift", "pop"); rb_define_alias(rb_cSizedQueue, "size", "length"); /* CVar */ @@ -1644,3 +1627,5 @@ Init_thread_sync(void) rb_provide("thread.rb"); } + +#include "thread_sync.rbinc" diff --git a/thread_sync.rb b/thread_sync.rb new file mode 100644 index 00000000000000..d567ca51af1047 --- /dev/null +++ b/thread_sync.rb @@ -0,0 +1,45 @@ +class Thread + class Queue + # call-seq: + # pop(non_block=false, timeout: nil) + # + # Retrieves data from the queue. + # + # If the queue is empty, the calling thread is suspended until data is pushed + # onto the queue. If +non_block+ is true, the thread isn't suspended, and + # +ThreadError+ is raised. + # + # If +timeout+ seconds have passed and no data is available +nil+ is + # returned. + def pop(non_block = false, timeout: nil) + if non_block && timeout + raise ArgumentError, "can't set a timeout if non_block is enabled" + end + Primitive.rb_queue_pop(non_block, timeout) + end + alias_method :deq, :pop + alias_method :shift, :pop + end + + class SizedQueue + # call-seq: + # pop(non_block=false, timeout: nil) + # + # Retrieves data from the queue. + # + # If the queue is empty, the calling thread is suspended until data is + # pushed onto the queue. If +non_block+ is true, the thread isn't + # suspended, and +ThreadError+ is raised. + # + # If +timeout+ seconds have passed and no data is available +nil+ is + # returned. + def pop(non_block = false, timeout: nil) + if non_block && timeout + raise ArgumentError, "can't set a timeout if non_block is enabled" + end + Primitive.rb_szqueue_pop(non_block, timeout) + end + alias_method :deq, :pop + alias_method :shift, :pop + end +end From b81858cf6f22b1a3c9a56e8e867c3a9efc189408 Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Tue, 2 Aug 2022 05:24:22 +0000 Subject: [PATCH 113/142] [rubygems/rubygems] Fix arguments for bundle-config(1) docs Signed-off-by: Takuya Noguchi https://github.com/rubygems/rubygems/commit/3e62ca776d --- lib/bundler/man/bundle-config.1 | 2 +- lib/bundler/man/bundle-config.1.ronn | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 9ab1f81c83369d..9f7887ca91418b 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -51,7 +51,7 @@ Executing \fBbundle config unset \fR will delete the configuration in both Executing \fBbundle config unset \-\-global \fR will delete the configuration only from the user configuration\. . .P -Executing \fBbundle config unset \-\-local \fR will delete the configuration only from the local application\. +Executing \fBbundle config unset \-\-local \fR will delete the configuration only from the local application\. . .P Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\. diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 62afe77af8ea16..905c85fcd99867 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -43,8 +43,8 @@ local and global sources. Executing `bundle config unset --global ` will delete the configuration only from the user configuration. -Executing `bundle config unset --local ` will delete the -configuration only from the local application. +Executing `bundle config unset --local ` will delete the configuration +only from the local application. Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will cause it to ignore all configuration. From f70b26af47f4f4e851e1a16d2c13951485272325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 2 Aug 2022 13:23:24 +0200 Subject: [PATCH 114/142] [rubygems/rubygems] Array is already uniq, no need to deduplicate it https://github.com/rubygems/rubygems/commit/3212ae14b7 --- lib/bundler/spec_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index e21a3ea6f5b0d1..735cdac126c916 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -64,7 +64,7 @@ def to_hash end def materialize(deps) - materialized = self.for(deps, true).uniq + materialized = self.for(deps, true) SpecSet.new(materialized) end From da00243dfe745cba3b176112fe8245c23e6f1635 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Sun, 31 Jul 2022 17:03:19 -0400 Subject: [PATCH 115/142] [DOC] Specify ways to run bootstrap tests --- doc/contributing/testing_ruby.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/contributing/testing_ruby.md b/doc/contributing/testing_ruby.md index ecdb1529260f6a..6247686efcf443 100644 --- a/doc/contributing/testing_ruby.md +++ b/doc/contributing/testing_ruby.md @@ -20,10 +20,11 @@ We can run any of the make scripts [in parallel](building_ruby.md#label-Running+ make btest OPTS=-v ``` - To run an individual bootstrap test, we can set the filename in the environment variable `BTESTS`: + To run individual bootstrap tests, we can either specify a list of filenames or use the `--sets` flag in the variable `BTESTS`: ``` - make btest BTESTS=bootstraptest/test_gc.rb + make btest BTESTS="bootstraptest/test_fork.rb bootstraptest/tes_gc.rb" + make btest BTESTS="--sets=fork,gc" ``` If we want to run the bootstrap test suite on Ruby (not Miniruby), we can use: From e4e054e3ce409f1c1d04bf7cd75aa9238e205d52 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 1 Aug 2022 14:24:12 -0700 Subject: [PATCH 116/142] Speed up setting the backref match object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch speeds up setting the backref match object by avoiding some memcopies. Take the following code for example: ```ruby "hello world" =~ /hello/ p $~ ``` When the RE matches the string, we have to set the Match object in the backref global. So we would allocate a match object[^1] and use `rb_reg_region_copy`[^2] to make a deep copy of the stack allocated `re_registers` struct[^3] in to the newly created Ruby object. This could possibly trigger GC[^4], and would allocate new memory. This patch makes a shallow copy of the `re_registers` struct on to the Match object allowing the match object to manage the `re_registers` pointer and also avoiding some calls to `xmalloc` and some manual memcopy. Benchmark looks like this: ```ruby require "benchmark/ips" def test_re thing thing =~ /hello/ end Benchmark.ips do |x| x.report("re hit") do test_re "hello world" end x.report("re miss") do test_re "world" end end ``` Before this patch: ``` $ ruby -v test.rb ruby 3.2.0dev (2022-07-27T22:29:00Z master 4ad69899b7) [arm64-darwin21] Ignoring bcrypt-3.1.16 because its extensions are not built. Try: gem pristine bcrypt --version 3.1.16 Warming up -------------------------------------- re hit 345.401k i/100ms re miss 673.584k i/100ms Calculating ------------------------------------- re hit 3.452M (± 0.5%) i/s - 17.270M in 5.002535s re miss 6.736M (± 0.4%) i/s - 34.353M in 5.099593s ``` After this patch: ``` $ ./ruby -v test.rb ruby 3.2.0dev (2022-08-01T21:24:12Z less-memcpy 0ff2a56606) [arm64-darwin21] Warming up -------------------------------------- re hit 419.578k i/100ms re miss 673.251k i/100ms Calculating ------------------------------------- re hit 4.201M (± 0.7%) i/s - 21.398M in 5.093593s re miss 6.716M (± 0.4%) i/s - 33.663M in 5.012756s ``` Matches get faster and misses maintain the same speed [^1]: https://github.com/ruby/ruby/blob/24204d54ab730791bfbd0cd66b8e12f0bd62ca5d/re.c#L1737 [^2]: https://github.com/ruby/ruby/blob/24204d54ab730791bfbd0cd66b8e12f0bd62ca5d/re.c#L1738 [^3]: https://github.com/ruby/ruby/blob/24204d54ab730791bfbd0cd66b8e12f0bd62ca5d/re.c#L1686 [^4]: https://github.com/ruby/ruby/blob/24204d54ab730791bfbd0cd66b8e12f0bd62ca5d/re.c#L981 --- re.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/re.c b/re.c index 7642dc36510fde..a633d1bb7b312d 100644 --- a/re.c +++ b/re.c @@ -1735,9 +1735,7 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back } match = match_alloc(rb_cMatch); - int copy_err = rb_reg_region_copy(RMATCH_REGS(match), regs); - onig_region_free(regs, 0); - if (copy_err) rb_memerror(); + memcpy(RMATCH_REGS(match), regs, sizeof(struct re_registers)); if (set_backref_str) { RMATCH(match)->str = rb_str_new4(str); From 4ba611ab29a11f1b99575fd1b313c69ff4a5362a Mon Sep 17 00:00:00 2001 From: git Date: Wed, 3 Aug 2022 01:04:26 +0900 Subject: [PATCH 117/142] * 2022-08-03 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index f364a1a8d0a04a..0839bef786ef53 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 2 +#define RUBY_RELEASE_DAY 3 #include "ruby/version.h" #include "ruby/internal/abi.h" From d8ea3a20fa7db0a670cde9c90d62fc5187217a23 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 2 Aug 2022 12:28:03 -0500 Subject: [PATCH 118/142] [ruby/date] [DOC] Enhanced RDoc for parser methods (https://github.com/ruby/date/pull/68) Treats: ::_httpdate ::_iso8601 ::_jisx0301 ::_parse ::_rfc2822 ::_rfc3339 ::_xmlschema ::httpdate ::iso8601 ::jisx0301 ::parse ::rfc2822 ::rfc3339 ::xmlschema https://github.com/ruby/date/commit/24bdab600a --- ext/date/date_core.c | 228 ++++++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 98 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 762fb7281cd90e..9fd0f52b4836e8 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -4493,23 +4493,26 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._parse(string, comp = true, limit: 128) -> hash * - * Parses the given representation of date and time, and returns a - * hash of parsed elements. + * Note: + * This method recognizes many forms in +string+, + * but it is not a validator. + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. * - * This method *does* *not* function as a validator. If the input - * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use Date._strptime or DateTime._strptime - * instead of this method as possible. + * Returns a hash of values parsed from +string+: * - * If the optional second argument is true and the detected year is in - * the range "00" to "99", considers the year a 2-digit form and makes - * it full. + * Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3} * - * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3} + * If +comp+ is +true+ and the given year is in the range (0..99), + * the current century is supplied; + * otherwise, the year is taken as given: + * + * Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3} + * Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. */ static VALUE date_s__parse(int argc, VALUE *argv, VALUE klass) @@ -4521,27 +4524,31 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.parse(string = '-4712-01-01', comp = true, start = Date::ITALY, limit: 128) -> date * - * Parses the given representation of date and time, and creates a - * date object. + * Note: + * This method recognizes many forms in +string+, + * but it is not a validator. + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. * - * This method *does* *not* function as a validator. If the input - * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use Date.strptime instead of this method - * as possible. + * Returns a new \Date object with values parsed from +string+: * - * If the optional second argument is true and the detected year is in - * the range "00" to "99", considers the year a 2-digit form and makes - * it full. + * Date.parse('2001-02-03') # => # + * Date.parse('20010203') # => # + * Date.parse('3rd Feb 2001') # => # * - * Date.parse('2001-02-03') #=> # - * Date.parse('20010203') #=> # - * Date.parse('3rd Feb 2001') #=> # + * If +comp+ is +true+ and the given year is in the range (0..99), + * the current century is supplied; + * otherwise, the year is taken as given: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * Date.parse('01-02-03', true) # => # + * Date.parse('01-02-03', false) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * - * See argument {start}[rdoc-ref:Date@Argument+start]. */ static VALUE date_s_parse(int argc, VALUE *argv, VALUE klass) @@ -4582,11 +4589,14 @@ VALUE date__jisx0301(VALUE); * call-seq: * Date._iso8601(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should contain + * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__iso8601(int argc, VALUE *argv, VALUE klass) @@ -4603,18 +4613,19 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.iso8601(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical ISO 8601 formats. + * Returns a new \Date object with values parsed from +string+, + * which should contain + * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]: * - * Date.iso8601('2001-02-03') #=> # - * Date.iso8601('20010203') #=> # - * Date.iso8601('2001-W05-6') #=> # + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date.iso8601(s) # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: + * + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * - * See argument {start}[rdoc-ref:Date@Argument+start]. */ static VALUE date_s_iso8601(int argc, VALUE *argv, VALUE klass) @@ -4645,11 +4656,15 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._rfc3339(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 3339 format}[https://datatracker.ietf.org/doc/html/rfc3339]: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date._rfc3339(s) + * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__rfc3339(int argc, VALUE *argv, VALUE klass) @@ -4666,16 +4681,19 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.rfc3339(string = '-4712-01-01T00:00:00+00:00', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical RFC 3339 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 3339 format}[https://datatracker.ietf.org/doc/html/rfc3339]: * - * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> # + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date.rfc3339(s) # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: + * + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * - * See argument {start}[rdoc-ref:Date@Argument+start]. */ static VALUE date_s_rfc3339(int argc, VALUE *argv, VALUE klass) @@ -4706,11 +4724,14 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._xmlschema(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should be a valid + * XML date format: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__xmlschema(int argc, VALUE *argv, VALUE klass) @@ -4727,16 +4748,17 @@ date_s__xmlschema(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.xmlschema(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical XML Schema formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid XML date format: * - * Date.xmlschema('2001-02-03') #=> # + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date.xmlschema(s) # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: * - * See argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * */ static VALUE @@ -4768,11 +4790,15 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._rfc2822(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 2822 date format}[https://datatracker.ietf.org/doc/html/rfc2822]: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date._rfc2822(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. * * Date._rfc822 is an alias for Date._rfc2822. */ @@ -4791,17 +4817,18 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.rfc2822(string = 'Mon, 1 Jan -4712 00:00:00 +0000', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical RFC 2822 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 2822 date format}[https://datatracker.ietf.org/doc/html/rfc2822]: * - * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000') - * #=> # + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date.rfc2822(s) # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: * - * See argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * * Date.rfc822 is an alias for Date.rfc2822. */ @@ -4833,14 +4860,14 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._httpdate(string, limit: 128) -> hash * - * Returns a hash of values parsed from +string+: + * Returns a hash of values parsed from +string+, which should be a valid + * HTTP date format: * * d = Date.new(2001, 2, 3) * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" * Date._httpdate(s) * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0} * - * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__httpdate(int argc, VALUE *argv, VALUE klass) @@ -4857,17 +4884,18 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.httpdate(string = 'Mon, 01 Jan -4712 00:00:00 GMT', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some RFC 2616 format. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 2616 date format}[https://datatracker.ietf.org/doc/html/rfc2616]: * - * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT') - * #=> # + * d = Date.new(2001, 2, 3) + s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + Date.httpdate(s) # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: * - * See argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * */ static VALUE @@ -4898,11 +4926,14 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass) * call-seq: * Date._jisx0301(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should be a valid + * JIS X 0301 date format: * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. */ static VALUE date_s__jisx0301(int argc, VALUE *argv, VALUE klass) @@ -4919,20 +4950,21 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical JIS X 0301 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid JIS X 0301 format: * - * Date.jisx0301('H13.02.03') #=> # + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date.jisx0301(s) # => # * * For no-era year, legacy format, Heisei is assumed. * - * Date.jisx0301('13.02.03') #=> # + * Date.jisx0301('13.02.03') # => # * - * Raise an ArgumentError when the string length is longer than _limit_. - * You can stop this check by passing limit: nil, but note - * that it may take a long time to parse. + * See: * - * See argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {start}[rdoc-ref:Date@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * */ static VALUE From eaf6189fe59ac4839d3a04bf7f9552fc22f09471 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 2 Aug 2022 15:17:50 -0500 Subject: [PATCH 119/142] [ruby/date] Enhanced RDoc (https://github.com/ruby/date/pull/69) Treats: ::_strptime ::strptime Adds 'Related' entry to some methods' doc. https://github.com/ruby/date/commit/a6c2129273 --- ext/date/date_core.c | 63 ++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 9fd0f52b4836e8..cee7b27faf6d08 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -4371,14 +4371,18 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass, * call-seq: * Date._strptime(string, format = '%F') -> hash * - * Parses the given representation of date and time with the given - * template, and returns a hash of parsed elements. _strptime does - * not support specification of flags and width unlike strftime. + * Returns a hash of values parsed from +string+ + * according to the given +format+: * - * Date._strptime('2001-02-03', '%Y-%m-%d') - * #=> {:year=>2001, :mon=>2, :mday=>3} + * Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3} * - * See also strptime(3) and #strftime. + * For other formats, see + * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. + * (Unlike Date.strftime, does not support flags and width.) + * + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date.strptime (returns a \Date object). */ static VALUE date_s__strptime(int argc, VALUE *argv, VALUE klass) @@ -4390,21 +4394,26 @@ date_s__strptime(int argc, VALUE *argv, VALUE klass) * call-seq: * Date.strptime(string = '-4712-01-01', format = '%F', start = Date::ITALY) -> date * - * Parses the given representation of date and time with the given - * template, and creates a date object. strptime does not support - * specification of flags and width unlike strftime. + * Returns a new \Date object with values parsed from +string+, + * according to the given +format+: * - * Date.strptime('2001-02-03', '%Y-%m-%d') #=> # - * Date.strptime('03-02-2001', '%d-%m-%Y') #=> # - * Date.strptime('2001-034', '%Y-%j') #=> # - * Date.strptime('2001-W05-6', '%G-W%V-%u') #=> # - * Date.strptime('2001 04 6', '%Y %U %w') #=> # - * Date.strptime('2001 05 6', '%Y %W %u') #=> # - * Date.strptime('sat3feb01', '%a%d%b%y') #=> # + * Date.strptime('2001-02-03', '%Y-%m-%d') # => # + * Date.strptime('03-02-2001', '%d-%m-%Y') # => # + * Date.strptime('2001-034', '%Y-%j') # => # + * Date.strptime('2001-W05-6', '%G-W%V-%u') # => # + * Date.strptime('2001 04 6', '%Y %U %w') # => # + * Date.strptime('2001 05 6', '%Y %W %u') # => # + * Date.strptime('sat3feb01', '%a%d%b%y') # => # + * + * For other formats, see + * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. + * (Unlike Date.strftime, does not support flags and width.) * * See argument {start}[rdoc-ref:Date@Argument+start]. * - * See also strptime(3) and #strftime. + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date._strptime (returns a hash). */ static VALUE date_s_strptime(int argc, VALUE *argv, VALUE klass) @@ -4513,6 +4522,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * * See argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date.parse(returns a \Date object). */ static VALUE date_s__parse(int argc, VALUE *argv, VALUE klass) @@ -4549,6 +4559,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._parse (returns a hash). */ static VALUE date_s_parse(int argc, VALUE *argv, VALUE klass) @@ -4597,6 +4608,8 @@ VALUE date__jisx0301(VALUE); * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2} * * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.iso8601 (returns a \Date object). */ static VALUE date_s__iso8601(int argc, VALUE *argv, VALUE klass) @@ -4626,6 +4639,7 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._iso8601 (returns a hash). */ static VALUE date_s_iso8601(int argc, VALUE *argv, VALUE klass) @@ -4665,6 +4679,8 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass) * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0} * * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.rfc3339 (returns a \Date object). */ static VALUE date_s__rfc3339(int argc, VALUE *argv, VALUE klass) @@ -4694,6 +4710,7 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._rfc3339 (returns a hash). */ static VALUE date_s_rfc3339(int argc, VALUE *argv, VALUE klass) @@ -4732,6 +4749,8 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass) * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3} * * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.xmlschema (returns a \Date object). */ static VALUE date_s__xmlschema(int argc, VALUE *argv, VALUE klass) @@ -4760,6 +4779,7 @@ date_s__xmlschema(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._xmlschema (returns a hash). */ static VALUE date_s_xmlschema(int argc, VALUE *argv, VALUE klass) @@ -4801,6 +4821,8 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass) * See argument {limit}[rdoc-ref:Date@Argument+limit]. * * Date._rfc822 is an alias for Date._rfc2822. + * + * Related: Date.rfc2822 (returns a \Date object). */ static VALUE date_s__rfc2822(int argc, VALUE *argv, VALUE klass) @@ -4831,6 +4853,8 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass) * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * * Date.rfc822 is an alias for Date.rfc2822. + * + * Related: Date._rfc2822 (returns a hash). */ static VALUE date_s_rfc2822(int argc, VALUE *argv, VALUE klass) @@ -4868,6 +4892,7 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) * Date._httpdate(s) * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0} * + * Related: Date.httpdate (returns a \Date object). */ static VALUE date_s__httpdate(int argc, VALUE *argv, VALUE klass) @@ -4897,6 +4922,7 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._httpdate (returns a hash). */ static VALUE date_s_httpdate(int argc, VALUE *argv, VALUE klass) @@ -4934,6 +4960,8 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass) * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3} * * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.jisx0301 (returns a \Date object). */ static VALUE date_s__jisx0301(int argc, VALUE *argv, VALUE klass) @@ -4966,6 +4994,7 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass) * - Argument {start}[rdoc-ref:Date@Argument+start]. * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * + * Related: Date._jisx0301 (returns a hash). */ static VALUE date_s_jisx0301(int argc, VALUE *argv, VALUE klass) From 20936eb3a95f3564e565f59228a35453ae94eee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 1 Aug 2022 09:56:39 +0200 Subject: [PATCH 120/142] [rubygems/rubygems] Warn (rather than crash) when setting `nil` specification versions https://github.com/rubygems/rubygems/commit/a4ba1a4d97 --- lib/rubygems/specification.rb | 2 ++ lib/rubygems/version.rb | 14 +++++++++++--- test/rubygems/test_gem_requirement.rb | 12 +++++++++--- test/rubygems/test_gem_specification.rb | 9 +++++++++ test/rubygems/test_gem_version.rb | 11 +++++++++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index f2e274002641e5..28ad176b535578 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -2653,6 +2653,8 @@ def validate_permissions def version=(version) @version = Gem::Version.create(version) + return if @version.nil? + # skip to set required_ruby_version when pre-released rubygems. # It caused to raise CircularDependencyError if @version.prerelease? && (@name.nil? || @name.strip != "rubygems") diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index 03ae5ca17eb13b..bb41374ffc3d02 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -171,9 +171,7 @@ def version # True if the +version+ string matches RubyGems' requirements. def self.correct?(version) - unless Gem::Deprecate.skip - warn "nil versions are discouraged and will be deprecated in Rubygems 4" if version.nil? - end + nil_versions_are_discouraged! if version.nil? !!(version.to_s =~ ANCHORED_VERSION_PATTERN) end @@ -190,6 +188,8 @@ def self.create(input) if self === input # check yourself before you wreck yourself input elsif input.nil? + nil_versions_are_discouraged! + nil else new input @@ -206,6 +206,14 @@ def self.new(version) # :nodoc: @@all[version] ||= super end + def self.nil_versions_are_discouraged! + unless Gem::Deprecate.skip + warn "nil versions are discouraged and will be deprecated in Rubygems 4" + end + end + + private_class_method :nil_versions_are_discouraged! + ## # Constructs a Version from the +version+ string. A version string is a # series of digits or ASCII letters separated by dots. diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index 37137dbdad80d3..5ecdbeddaeba79 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -129,7 +129,9 @@ def test_satisfied_by_eh_bang_equal assert_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end @@ -141,7 +143,9 @@ def test_satisfied_by_eh_blank refute_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end @@ -153,7 +157,9 @@ def test_satisfied_by_eh_equal refute_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 6117e81a81a42f..cf0dba4331fc3c 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -1220,6 +1220,15 @@ def test_initialize_prerelease_version_before_name assert_equal "1.0.0.dev", spec.version.to_s end + def test_initialize_nil_version + expected = "nil versions are discouraged and will be deprecated in Rubygems 4\n" + actual_stdout, actual_stderr = capture_output do + Gem::Specification.new.version = nil + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + end + def test__dump @a2.platform = Gem::Platform.local @a2.instance_variable_set :@original_platform, "old_platform" diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index e907eabb34d801..9237608d4a8ca9 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -32,8 +32,15 @@ def test_bump_one_level def test_class_create real = Gem::Version.new(1.0) - assert_same real, Gem::Version.create(real) - assert_nil Gem::Version.create(nil) + assert_same real, Gem::Version.create(real) + + expected = "nil versions are discouraged and will be deprecated in Rubygems 4\n" + actual_stdout, actual_stderr = capture_output do + assert_nil Gem::Version.create(nil) + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + assert_equal v("5.1"), Gem::Version.create("5.1") ver = "1.1".freeze From 4f00ee8d470f4ad5040c0df4cac2cf802b3cbdaf Mon Sep 17 00:00:00 2001 From: Ilya Dyakonov Date: Mon, 1 Aug 2022 09:54:21 +0100 Subject: [PATCH 121/142] [rubygems/rubygems] fix platform matching for index specs https://github.com/rubygems/rubygems/commit/f087f1b590 --- lib/rubygems/resolver/index_specification.rb | 5 +++-- .../test_gem_resolver_index_specification.rb | 2 +- test/rubygems/test_gem_resolver_installer_set.rb | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/rubygems/resolver/index_specification.rb b/lib/rubygems/resolver/index_specification.rb index e8c3b35f7e6314..0fc758dfd3ac5c 100644 --- a/lib/rubygems/resolver/index_specification.rb +++ b/lib/rubygems/resolver/index_specification.rb @@ -21,7 +21,8 @@ def initialize(set, name, version, source, platform) @name = name @version = version @source = source - @platform = platform.to_s + @platform = Gem::Platform.new(platform.to_s) + @original_platform = platform.to_s @spec = nil end @@ -91,7 +92,7 @@ def pretty_print(q) # :nodoc: def spec # :nodoc: @spec ||= begin - tuple = Gem::NameTuple.new @name, @version, @platform + tuple = Gem::NameTuple.new @name, @version, @original_platform @source.fetch_spec tuple end diff --git a/test/rubygems/test_gem_resolver_index_specification.rb b/test/rubygems/test_gem_resolver_index_specification.rb index 339445cb44583f..b479757bd557fe 100644 --- a/test/rubygems/test_gem_resolver_index_specification.rb +++ b/test/rubygems/test_gem_resolver_index_specification.rb @@ -26,7 +26,7 @@ def test_initialize_platform spec = Gem::Resolver::IndexSpecification.new( set, "rails", version, source, Gem::Platform.local) - assert_equal Gem::Platform.local.to_s, spec.platform + assert_equal Gem::Platform.local, spec.platform end def test_install diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb index 8d84c28172a7fe..32e1faa28d4368 100644 --- a/test/rubygems/test_gem_resolver_installer_set.rb +++ b/test/rubygems/test_gem_resolver_installer_set.rb @@ -51,6 +51,19 @@ def test_add_always_install_platform assert_equal %w[a-1], set.always_install.map {|s| s.full_name } end + def test_add_always_install_index_spec_platform + a_1_local, a_1_local_gem = util_gem "a", 1 do |s| + s.platform = Gem::Platform.local + end + + FileUtils.mv a_1_local_gem, @tempdir + + set = Gem::Resolver::InstallerSet.new :both + set.add_always_install dep("a") + + assert_equal [Gem::Platform.local], set.always_install.map {|s| s.platform } + end + def test_add_always_install_prerelease spec_fetcher do |fetcher| fetcher.gem "a", 1 From f33b2ae918aff36518540244ac57e7f9c4de4af9 Mon Sep 17 00:00:00 2001 From: Thomas Winsnes Date: Tue, 2 Aug 2022 02:22:22 +0200 Subject: [PATCH 122/142] Updated to use multiple licenses Co-authored-by: Hiroshi SHIBATA --- ext/bigdecimal/bigdecimal.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec index 2ed7d09373b03c..96e1aa83f1b078 100644 --- a/ext/bigdecimal/bigdecimal.gemspec +++ b/ext/bigdecimal/bigdecimal.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "Arbitrary-precision decimal floating-point number library." s.description = "This library provides arbitrary-precision decimal floating-point number class." s.homepage = "https://github.com/ruby/bigdecimal" - s.license = "Ruby" + s.license = ["Ruby", "bsd-2-clause"] s.require_paths = %w[lib] s.extensions = %w[ext/bigdecimal/extconf.rb] From 8a1be433e8cac6ca5ded095f6fefbdc1009102b9 Mon Sep 17 00:00:00 2001 From: Thomas Winsnes Date: Tue, 2 Aug 2022 02:23:34 +0200 Subject: [PATCH 123/142] [ruby/bigdecimal] Updated to use the correct spec for muilti license https://github.com/ruby/bigdecimal/commit/13165b29b8 --- ext/bigdecimal/bigdecimal.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec index 96e1aa83f1b078..1feed332f66f6e 100644 --- a/ext/bigdecimal/bigdecimal.gemspec +++ b/ext/bigdecimal/bigdecimal.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "Arbitrary-precision decimal floating-point number library." s.description = "This library provides arbitrary-precision decimal floating-point number class." s.homepage = "https://github.com/ruby/bigdecimal" - s.license = ["Ruby", "bsd-2-clause"] + s.licenses = ["Ruby", "bsd-2-clause"] s.require_paths = %w[lib] s.extensions = %w[ext/bigdecimal/extconf.rb] From 71794a75db5d3da810146da106baf7eb5e86f745 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Wed, 3 Aug 2022 12:24:38 +0900 Subject: [PATCH 124/142] Merge rubygems/bundler HEAD Pick from https://github.com/rubygems/rubygems/commit/8331e63263081a6aa690d8025d2957f30c4e814a --- lib/bundler/cli/platform.rb | 2 +- lib/bundler/cli/viz.rb | 2 +- lib/bundler/constants.rb | 2 +- lib/bundler/fetcher/downloader.rb | 2 +- lib/bundler/templates/Executable | 2 +- lib/bundler/templates/Executable.bundler | 5 +++-- lib/bundler/templates/Executable.standalone | 2 ++ lib/rubygems.rb | 2 +- lib/rubygems/commands/rdoc_command.rb | 5 +++-- lib/rubygems/defaults.rb | 2 +- lib/rubygems/ext/builder.rb | 2 +- lib/rubygems/installer.rb | 4 ++-- lib/rubygems/validator.rb | 2 +- .../bundler/{other => commands}/platform_spec.rb | 2 +- spec/bundler/quality_spec.rb | 2 +- spec/bundler/realworld/edgecases_spec.rb | 6 +++--- spec/bundler/runtime/setup_spec.rb | 4 ++-- test/rubygems/helper.rb | 2 +- test/rubygems/test_bundled_ca.rb | 2 +- test/rubygems/test_gem_bundler_version_finder.rb | 2 +- test/rubygems/test_gem_ext_builder.rb | 6 +++--- test/rubygems/test_gem_ext_cargo_builder.rb | 2 +- test/rubygems/test_gem_installer.rb | 2 +- test/rubygems/test_gem_requirement.rb | 2 +- .../test_gem_resolver_git_specification.rb | 2 +- test/rubygems/test_gem_security_trust_dir.rb | 4 ++-- test/rubygems/test_kernel.rb | 16 ++++++++-------- 27 files changed, 46 insertions(+), 42 deletions(-) rename spec/bundler/{other => commands}/platform_spec.rb (99%) diff --git a/lib/bundler/cli/platform.rb b/lib/bundler/cli/platform.rb index 068c765aad4e8c..16d4e0145add4c 100644 --- a/lib/bundler/cli/platform.rb +++ b/lib/bundler/cli/platform.rb @@ -9,7 +9,7 @@ def initialize(options) def run platforms, ruby_version = Bundler.ui.silence do - locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version + locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version.gsub(/p\d+\Z/, "") gemfile_ruby_version = Bundler.definition.ruby_version && Bundler.definition.ruby_version.single_version_string [Bundler.definition.platforms.map {|p| "* #{p}" }, locked_ruby_version || gemfile_ruby_version] diff --git a/lib/bundler/cli/viz.rb b/lib/bundler/cli/viz.rb index 644f9b25cf704b..5c09e009959e49 100644 --- a/lib/bundler/cli/viz.rb +++ b/lib/bundler/cli/viz.rb @@ -23,7 +23,7 @@ def run Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:" Bundler.ui.warn "`gem install ruby-graphviz`" rescue StandardError => e - raise unless e.message =~ /GraphViz not installed or dot not in PATH/ + raise unless e.message.to_s.include?("GraphViz not installed or dot not in PATH") Bundler.ui.error e.message Bundler.ui.warn "Please install GraphViz. On a Mac with Homebrew, you can run `brew install graphviz`." end diff --git a/lib/bundler/constants.rb b/lib/bundler/constants.rb index 2e4ebb37ee606d..8dd8a5381535c7 100644 --- a/lib/bundler/constants.rb +++ b/lib/bundler/constants.rb @@ -2,6 +2,6 @@ module Bundler WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/ - FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/ + FREEBSD = RbConfig::CONFIG["host_os"].to_s.include?("bsd") NULL = WINDOWS ? "NUL" : "/dev/null" end diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb index f2aad3a5007a66..0a668eb17c73a2 100644 --- a/lib/bundler/fetcher/downloader.rb +++ b/lib/bundler/fetcher/downloader.rb @@ -68,7 +68,7 @@ def request(uri, headers) raise CertificateFailureError.new(uri) rescue *HTTP_ERRORS => e Bundler.ui.trace e - if e.is_a?(SocketError) || e.message =~ /host down:/ + if e.is_a?(SocketError) || e.message.to_s.include?("host down:") raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \ "connection and try again." else diff --git a/lib/bundler/templates/Executable b/lib/bundler/templates/Executable index f6487e3c89d0c9..9ff6f00898815b 100644 --- a/lib/bundler/templates/Executable +++ b/lib/bundler/templates/Executable @@ -13,7 +13,7 @@ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir bundle_binstub = File.expand_path("bundle", __dir__) if File.file?(bundle_binstub) - if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") load(bundle_binstub) else abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler index 51650c7664a21e..77f90e735c3adf 100644 --- a/lib/bundler/templates/Executable.bundler +++ b/lib/bundler/templates/Executable.bundler @@ -62,8 +62,9 @@ m = Module.new do def bundler_requirement @bundler_requirement ||= - env_var_version || cli_arg_version || - bundler_requirement_for(lockfile_version) + env_var_version || + cli_arg_version || + bundler_requirement_for(lockfile_version) end def bundler_requirement_for(version) diff --git a/lib/bundler/templates/Executable.standalone b/lib/bundler/templates/Executable.standalone index d591e3fc045948..3117a27e86ff2d 100644 --- a/lib/bundler/templates/Executable.standalone +++ b/lib/bundler/templates/Executable.standalone @@ -1,4 +1,6 @@ #!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %> +# frozen_string_literal: true + # # This file was generated by Bundler. # diff --git a/lib/rubygems.rb b/lib/rubygems.rb index e59cd26870b3ea..b21f00acc74b90 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -1010,7 +1010,7 @@ def self.java_platform? # Is this platform Solaris? def self.solaris_platform? - RUBY_PLATFORM =~ /solaris/ + RUBY_PLATFORM.include?("solaris") end ## diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb index 17ad6f836bea94..a998a9704cb3ed 100644 --- a/lib/rubygems/commands/rdoc_command.rb +++ b/lib/rubygems/commands/rdoc_command.rb @@ -86,8 +86,9 @@ def execute begin doc.generate rescue Errno::ENOENT => e - e.message =~ / - / - alert_error "Unable to document #{spec.full_name}, #{$'} is missing, skipping" + match = / - /.match(e.message) + alert_error "Unable to document #{spec.full_name}, " \ + " #{match.post_match} is missing, skipping" terminate_interaction 1 if specs.length == 1 end end diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index d27f286265c8ff..b805ef91740803 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -171,7 +171,7 @@ def self.default_path def self.default_exec_format exec_format = RbConfig::CONFIG["ruby_install_name"].sub("ruby", "%s") rescue "%s" - unless exec_format =~ /%s/ + unless exec_format.include?("%s") raise Gem::Exception, "[BUG] invalid exec_format #{exec_format.inspect}, no %s" end diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index c5a03806b9607b..b46f9b5cd5fa8f 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -26,7 +26,7 @@ def self.make(dest_path, results, make_dir = Dir.pwd, sitedir = nil) RbConfig::CONFIG["configure_args"] =~ /with-make-prog\=(\w+)/ make_program_name = ENV["MAKE"] || ENV["make"] || $1 unless make_program_name - make_program_name = (/mswin/ =~ RUBY_PLATFORM) ? "nmake" : "make" + make_program_name = (RUBY_PLATFORM.include?("mswin")) ? "nmake" : "make" end make_program = Shellwords.split(make_program_name) diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 52307f6d930d80..8ec75d1ff7405d 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -234,8 +234,8 @@ def check_executable_overwrite(filename) # :nodoc: io.gets # blankline # TODO detect a specially formatted comment instead of trying - # to run a regexp against Ruby code. - next unless io.gets =~ /This file was generated by RubyGems/ + # to find a string inside Ruby code. + next unless io.gets.to_s.include?("This file was generated by RubyGems") ruby_executable = true existing = io.read.slice(%r{ diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb index 60104a34d5352c..1609924607d7b8 100644 --- a/lib/rubygems/validator.rb +++ b/lib/rubygems/validator.rb @@ -26,7 +26,7 @@ def find_files_for_gem(gem_directory) Find.find gem_directory do |file_name| fn = file_name[gem_directory.size..file_name.size - 1].sub(/^\//, "") installed_files << fn unless - fn =~ /CVS/ || fn.empty? || File.directory?(file_name) + fn.empty? || fn.include?("CVS") || File.directory?(file_name) end installed_files diff --git a/spec/bundler/other/platform_spec.rb b/spec/bundler/commands/platform_spec.rb similarity index 99% rename from spec/bundler/other/platform_spec.rb rename to spec/bundler/commands/platform_spec.rb index 691a219e62d9d9..0b964eac8cd255 100644 --- a/spec/bundler/other/platform_spec.rb +++ b/spec/bundler/commands/platform_spec.rb @@ -231,7 +231,7 @@ L bundle "platform --ruby" - expect(out).to eq("ruby 1.0.0p127") + expect(out).to eq("ruby 1.0.0") end it "handles when there is a requirement in the gemfile" do diff --git a/spec/bundler/quality_spec.rb b/spec/bundler/quality_spec.rb index 62f3722a392967..ee98bcd4d7c82e 100644 --- a/spec/bundler/quality_spec.rb +++ b/spec/bundler/quality_spec.rb @@ -22,7 +22,7 @@ def check_for_git_merge_conflicts(filename) def check_for_tab_characters(filename) failing_lines = [] each_line(filename) do |line, number| - failing_lines << number + 1 if line =~ /\t/ + failing_lines << number + 1 if line.include?("\t") end return if failing_lines.empty? diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index 30c922efb0771d..2a667011a10fec 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -218,7 +218,7 @@ def rubygems_version(name, requirement) end it "doesn't hang on big gemfile" do - skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/ + skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") gemfile <<~G # frozen_string_literal: true @@ -330,7 +330,7 @@ def rubygems_version(name, requirement) end it "doesn't hang on tricky gemfile" do - skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/ + skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") gemfile <<~G source 'https://rubygems.org' @@ -356,7 +356,7 @@ def rubygems_version(name, requirement) end it "doesn't hang on nix gemfile" do - skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM =~ /darwin/ + skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM.include?("darwin") gemfile <<~G source "https://rubygems.org" do diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 4390f0fb174e63..29445b420ce11d 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -370,7 +370,7 @@ def clean_load_path(lp) context "when the ruby stdlib is a substring of Gem.path" do it "does not reject the stdlib from $LOAD_PATH" do - substring = "/" + $LOAD_PATH.find {|p| p =~ /vendor_ruby/ }.split("/")[2] + substring = "/" + $LOAD_PATH.find {|p| p.include?("vendor_ruby") }.split("/")[2] run "puts 'worked!'", :env => { "GEM_PATH" => substring } expect(out).to eq("worked!") end @@ -865,7 +865,7 @@ def clean_load_path(lp) gemspec_content = File.binread(gemspec). sub("Bundler::VERSION", %("#{Bundler::VERSION}")). - lines.reject {|line| line =~ %r{lib/bundler/version} }.join + lines.reject {|line| line.include?("lib/bundler/version") }.join File.open(File.join(specifications_dir, "#{full_name}.gemspec"), "wb") do |f| f.write(gemspec_content) diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index dab3cd4d4c4c0d..46eefbb48e4ce0 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -270,7 +270,7 @@ def parse_make_command_line_targets(line) end def assert_contains_make_command(target, output, msg = nil) - if output.match(/\n/) + if output.include?("\n") msg = build_message(msg, "Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT" % [ ("%s %s" % [make_command, target]).rstrip, diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb index b061666c76981f..3d7f616519f23e 100644 --- a/test/rubygems/test_bundled_ca.rb +++ b/test/rubygems/test_bundled_ca.rb @@ -36,7 +36,7 @@ def assert_https(host) pend "#{host} seems offline, I can't tell whether ssl would work." rescue OpenSSL::SSL::SSLError => e # Only fail for certificate verification errors - if e.message =~ /certificate verify failed/ + if e.message.include?("certificate verify failed") flunk "#{host} is not verifiable using the included certificates. Error was: #{e.message}" end raise diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb index 0e21e460f69b88..60e2b65047cacb 100644 --- a/test/rubygems/test_gem_bundler_version_finder.rb +++ b/test/rubygems/test_gem_bundler_version_finder.rb @@ -78,7 +78,7 @@ def test_bundler_version def test_deleted_directory pend "Cannot perform this test on windows" if win_platform? - pend "Cannot perform this test on Solaris" if /solaris/ =~ RUBY_PLATFORM + pend "Cannot perform this test on Solaris" if RUBY_PLATFORM.include?("solaris") require "tmpdir" orig_dir = Dir.pwd diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb index 6adfd425506d5b..34d89035952ea6 100644 --- a/test/rubygems/test_gem_ext_builder.rb +++ b/test/rubygems/test_gem_ext_builder.rb @@ -106,7 +106,7 @@ def test_custom_make_with_options end def test_build_extensions - pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") # not working from the beginning + pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning @spec.extensions << "ext/extconf.rb" ext_dir = File.join @spec.gem_dir, "ext" @@ -142,7 +142,7 @@ def test_build_extensions end def test_build_extensions_with_gemhome_with_space - pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") # not working from the beginning + pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning new_gemhome = File.join @tempdir, "gem home" File.rename(@gemhome, new_gemhome) @gemhome = new_gemhome @@ -163,7 +163,7 @@ def Gem.install_extension_in_lib false end end - pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") # not working from the beginning + pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning @spec.extensions << "ext/extconf.rb" diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb index 5a940b07a82bcb..c6bbab2cb313f6 100644 --- a/test/rubygems/test_gem_ext_cargo_builder.rb +++ b/test/rubygems/test_gem_ext_cargo_builder.rb @@ -164,7 +164,7 @@ def test_custom_name def skip_unsupported_platforms! pend "jruby not supported" if java_platform? pend "truffleruby not supported (yet)" if RUBY_ENGINE == "truffleruby" - pend "mswin not supported (yet)" if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") + pend "mswin not supported (yet)" if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out]) pend "cargo not present" unless $?.success? pend "ruby.h is not provided by ruby repo" if ruby_repo? diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 46003175784c16..d269644ade541d 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -1490,7 +1490,7 @@ def test_find_lib_file_after_install def test_install_extension_and_script pend "Makefile creation crashes on jruby" if Gem.java_platform? - pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") # not working from the beginning + pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning @spec = setup_base_spec @spec.extensions << "extconf.rb" diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index 5ecdbeddaeba79..29bb264454f64f 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -83,7 +83,7 @@ def test_parse Gem::Requirement.parse(Gem::Version.new("2")) end - if RUBY_VERSION >= "2.5" && !(Gem.java_platform? && ENV["JRUBY_OPTS"] =~ /--debug/) + if RUBY_VERSION >= "2.5" && !(Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug")) def test_parse_deduplication assert_same "~>", Gem::Requirement.parse("~> 1").first end diff --git a/test/rubygems/test_gem_resolver_git_specification.rb b/test/rubygems/test_gem_resolver_git_specification.rb index fef071aa7632f5..454fd9c6e49535 100644 --- a/test/rubygems/test_gem_resolver_git_specification.rb +++ b/test/rubygems/test_gem_resolver_git_specification.rb @@ -63,7 +63,7 @@ def test_install def test_install_extension pend if Gem.java_platform? - pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?("GITHUB_ACTIONS") # not working from the beginning + pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning name, _, repository, = git_gem "a", 1 do |s| s.extensions << "ext/extconf.rb" end diff --git a/test/rubygems/test_gem_security_trust_dir.rb b/test/rubygems/test_gem_security_trust_dir.rb index 8c59286679e45c..b74e21fb5cfc53 100644 --- a/test/rubygems/test_gem_security_trust_dir.rb +++ b/test/rubygems/test_gem_security_trust_dir.rb @@ -70,7 +70,7 @@ def test_verify assert_path_exist @dest_dir mask = 040700 & (~File.umask) - mask |= 0200000 if /aix/ =~ RUBY_PLATFORM + mask |= 0200000 if RUBY_PLATFORM.include?("aix") assert_equal mask, File.stat(@dest_dir).mode unless win_platform? end @@ -91,7 +91,7 @@ def test_verify_wrong_permissions @trust_dir.verify mask = 040700 & (~File.umask) - mask |= 0200000 if /aix/ =~ RUBY_PLATFORM + mask |= 0200000 if RUBY_PLATFORM.include?("aix") assert_equal mask, File.stat(@dest_dir).mode unless win_platform? end diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb index cced65fa50d89a..091a5419fbb41f 100644 --- a/test/rubygems/test_kernel.rb +++ b/test/rubygems/test_kernel.rb @@ -20,7 +20,7 @@ def teardown def test_gem assert gem("a", "= 1"), "Should load" - assert $:.any? {|p| %r{a-1/lib} =~ p } + assert $:.any? {|p| p.include?("a-1/lib") } end def test_gem_default @@ -50,13 +50,13 @@ def test_gem_re_gem_mismatch def test_gem_redundant assert gem("a", "= 1"), "Should load" refute gem("a", "= 1"), "Should not load" - assert_equal 1, $:.select {|p| %r{a-1/lib} =~ p }.size + assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size end def test_gem_overlapping assert gem("a", "= 1"), "Should load" refute gem("a", ">= 1"), "Should not load" - assert_equal 1, $:.select {|p| %r{a-1/lib} =~ p }.size + assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size end def test_gem_prerelease @@ -83,13 +83,13 @@ def test_gem_conflicting assert_match(/activated a-1/, ex.message) assert_equal "a", ex.name - assert $:.any? {|p| %r{a-1/lib} =~ p } - refute $:.any? {|p| %r{a-2/lib} =~ p } + assert $:.any? {|p| p.include?("a-1/lib") } + refute $:.any? {|p| p.include?("a-2/lib") } end def test_gem_not_adding_bin assert gem("a", "= 1"), "Should load" - refute $:.any? {|p| %r{a-1/bin} =~ p } + refute $:.any? {|p| p.include?("a-1/bin") } end def test_gem_failing_inside_require_doesnt_cause_double_exceptions @@ -114,7 +114,7 @@ def test_gem_bundler quick_gem "bundler", "2.a" assert gem("bundler") - assert $:.any? {|p| %r{bundler-1/lib} =~ p } + assert $:.any? {|p| p.include?("bundler-1/lib") } end def test_gem_bundler_inferred_bundler_version @@ -123,7 +123,7 @@ def test_gem_bundler_inferred_bundler_version quick_gem "bundler", "2.a" assert gem("bundler", ">= 0.a") - assert $:.any? {|p| %r{bundler-1/lib} =~ p } + assert $:.any? {|p| p.include?("bundler-1/lib") } end end end From 35c65e7ba6b4aa8bc80aaca8429a48c4eb923b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 1 Aug 2022 16:41:31 +0200 Subject: [PATCH 125/142] [rubygems/rubygems] Fix conservative updates regardless of `--strict` https://github.com/rubygems/rubygems/commit/c9a1d69a8d --- lib/bundler/cli/outdated.rb | 2 +- spec/bundler/commands/outdated_spec.rb | 194 ++++++++++++------------- 2 files changed, 97 insertions(+), 99 deletions(-) diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb index 9ce583886e81eb..e9f93fec396d06 100644 --- a/lib/bundler/cli/outdated.rb +++ b/lib/bundler/cli/outdated.rb @@ -46,7 +46,7 @@ def run Bundler::CLI::Common.configure_gem_version_promoter( Bundler.definition, - options + options.merge(:strict => @strict) ) definition_resolution = proc do diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index a05a1ad4bb8fa2..6b7c95f01baada 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -1098,127 +1098,125 @@ def test_group_option(group) end context "conservative updates" do - context "without --strict" do - before do - build_repo4 do - build_gem "patch", %w[1.0.0 1.0.1] - build_gem "minor", %w[1.0.0 1.0.1 1.1.0] - build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0] - end + before do + build_repo4 do + build_gem "patch", %w[1.0.0 1.0.1] + build_gem "minor", %w[1.0.0 1.0.1 1.1.0] + build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0] + end - # establish a lockfile set to 1.0.0 - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem 'patch', '1.0.0' - gem 'minor', '1.0.0' - gem 'major', '1.0.0' - G + # establish a lockfile set to 1.0.0 + install_gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem 'patch', '1.0.0' + gem 'minor', '1.0.0' + gem 'major', '1.0.0' + G - # remove all version requirements - gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem 'patch' - gem 'minor' - gem 'major' - G - end + # remove all version requirements + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem 'patch' + gem 'minor' + gem 'major' + G + end - it "shows nothing when patching and filtering to minor" do - bundle "outdated --patch --filter-minor" + it "shows nothing when patching and filtering to minor" do + bundle "outdated --patch --filter-minor" - expect(out).to end_with("No minor updates to display.") - end + expect(out).to end_with("No minor updates to display.") + end - it "shows all gems when patching and filtering to patch" do - bundle "outdated --patch --filter-patch", :raise_on_error => false + it "shows all gems when patching and filtering to patch" do + bundle "outdated --patch --filter-patch", :raise_on_error => false - expected_output = <<~TABLE.strip - Gem Current Latest Requested Groups - major 1.0.0 1.0.1 >= 0 default - minor 1.0.0 1.0.1 >= 0 default - patch 1.0.0 1.0.1 >= 0 default - TABLE + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups + major 1.0.0 1.0.1 >= 0 default + minor 1.0.0 1.0.1 >= 0 default + patch 1.0.0 1.0.1 >= 0 default + TABLE - expect(out).to end_with(expected_output) - end + expect(out).to end_with(expected_output) + end - it "shows minor and major when updating to minor and filtering to patch and minor" do - bundle "outdated --minor --filter-minor", :raise_on_error => false + it "shows minor and major when updating to minor and filtering to patch and minor" do + bundle "outdated --minor --filter-minor", :raise_on_error => false - expected_output = <<~TABLE.strip - Gem Current Latest Requested Groups - major 1.0.0 1.1.0 >= 0 default - minor 1.0.0 1.1.0 >= 0 default - TABLE + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups + major 1.0.0 1.1.0 >= 0 default + minor 1.0.0 1.1.0 >= 0 default + TABLE - expect(out).to end_with(expected_output) - end + expect(out).to end_with(expected_output) + end - it "shows minor when updating to major and filtering to minor with parseable" do - bundle "outdated --major --filter-minor --parseable", :raise_on_error => false + it "shows minor when updating to major and filtering to minor with parseable" do + bundle "outdated --major --filter-minor --parseable", :raise_on_error => false - expect(out).not_to include("patch (newest") - expect(out).to include("minor (newest") - expect(out).not_to include("major (newest") - end + expect(out).not_to include("patch (newest") + expect(out).to include("minor (newest") + expect(out).not_to include("major (newest") end + end - context "with --strict" do - before do - build_repo4 do - build_gem "foo", %w[1.4.3 1.4.4] do |s| - s.add_dependency "bar", "~> 2.0" - end - build_gem "foo", %w[1.4.5 1.5.0] do |s| - s.add_dependency "bar", "~> 2.1" - end - build_gem "foo", %w[1.5.1] do |s| - s.add_dependency "bar", "~> 3.0" - end - build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0] - build_gem "qux", %w[1.0.0 1.1.0 2.0.0] + context "tricky conservative updates" do + before do + build_repo4 do + build_gem "foo", %w[1.4.3 1.4.4] do |s| + s.add_dependency "bar", "~> 2.0" end + build_gem "foo", %w[1.4.5 1.5.0] do |s| + s.add_dependency "bar", "~> 2.1" + end + build_gem "foo", %w[1.5.1] do |s| + s.add_dependency "bar", "~> 3.0" + end + build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0] + build_gem "qux", %w[1.0.0 1.1.0 2.0.0] + end - # establish a lockfile set to 1.4.3 - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem 'foo', '1.4.3' - gem 'bar', '2.0.3' - gem 'qux', '1.0.0' - G + # establish a lockfile set to 1.4.3 + install_gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem 'foo', '1.4.3' + gem 'bar', '2.0.3' + gem 'qux', '1.0.0' + G - # remove 1.4.3 requirement and bar altogether - # to setup update specs below - gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem 'foo' - gem 'qux' - G - end + # remove 1.4.3 requirement and bar altogether + # to setup update specs below + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem 'foo' + gem 'qux' + G + end - it "shows gems with --strict updating to patch and filtering to patch" do - bundle "outdated --patch --strict --filter-patch", :raise_on_error => false + it "shows gems updating to patch and filtering to patch" do + bundle "outdated --patch --filter-patch", :raise_on_error => false, :env => { "DEBUG_RESOLVER" => "1" } - expected_output = <<~TABLE.strip - Gem Current Latest Requested Groups - bar 2.0.3 2.0.5 - foo 1.4.3 1.4.4 >= 0 default - TABLE + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups + bar 2.0.3 2.0.5 + foo 1.4.3 1.4.4 >= 0 default + TABLE - expect(out).to end_with(expected_output) - end + expect(out).to end_with(expected_output) + end - it "shows gems with --strict updating to patch and filtering to patch, in debug mode" do - bundle "outdated --patch --strict --filter-patch", :raise_on_error => false, :env => { "DEBUG" => "1" } + it "shows gems updating to patch and filtering to patch, in debug mode" do + bundle "outdated --patch --filter-patch", :raise_on_error => false, :env => { "DEBUG" => "1" } - expected_output = <<~TABLE.strip - Gem Current Latest Requested Groups Path - bar 2.0.3 2.0.5 - foo 1.4.3 1.4.4 >= 0 default - TABLE + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups Path + bar 2.0.3 2.0.5 + foo 1.4.3 1.4.4 >= 0 default + TABLE - expect(out).to end_with(expected_output) - end + expect(out).to end_with(expected_output) end end From 851b3aa7dde489502f517cc1ad9d31d9a3056197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 1 Aug 2022 17:11:20 +0200 Subject: [PATCH 126/142] [rubygems/rubygems] Fix `bundle outdated --strict` It should be an alias of `--filter-strict`. `--update-strict` is essentially a dummy option with no special behavior associated and should be deprecated. https://github.com/rubygems/rubygems/commit/ec1e5d83c8 --- lib/bundler/cli.rb | 4 ++-- spec/bundler/commands/outdated_spec.rb | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index e9ef47f9ba7af1..0fa646c8ea823c 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -401,9 +401,9 @@ def add(*gems) "Do not attempt to fetch gems remotely and use the gem cache instead" method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems" method_option "source", :type => :array, :banner => "Check against a specific source" - method_option "filter-strict", :type => :boolean, :banner => + method_option "filter-strict", :type => :boolean, :aliases => "--strict", :banner => "Only list newer versions allowed by your Gemfile requirements" - method_option "strict", :type => :boolean, :aliases => "--update-strict", :banner => + method_option "update-strict", :type => :boolean, :banner => "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major" method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version" method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)" diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index 6b7c95f01baada..e084af85d791bb 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -604,6 +604,22 @@ def test_group_option(group) expect(out).to end_with(expected_output) end + it "only reports gems that have a newer version that matches the specified dependency version requirements, using --strict alias" do + update_repo2 do + build_gem "activesupport", "3.0" + build_gem "weakling", "0.0.5" + end + + bundle :outdated, :strict => true, :raise_on_error => false + + expected_output = <<~TABLE.strip + Gem Current Latest Requested Groups + weakling 0.0.3 0.0.5 ~> 0.0.1 default + TABLE + + expect(out).to end_with(expected_output) + end + it "doesn't crash when some deps unused on the current platform" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" From 4406cb1bf10e34757d9877b3b12d4b0c294c22fb Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 3 Aug 2022 09:46:21 +0200 Subject: [PATCH 127/142] Harden Queue#pop timeout tests They occasionaly fail with; ``` FLeaked thread: TestThreadQueue#test_queue_pop_timeout: # .Finished thread: TestThreadQueue#test_deny_pushers: # ... Retrying... 1) Failure: TestThreadQueue#test_sized_queue_pop_timeout [/Users/runner/work/ruby/ruby/src/test/ruby/test_thread_queue.rb:157]: <#> expected but was . 2) Failure: TestThreadQueue#test_queue_pop_timeout [/Users/runner/work/ruby/ruby/src/test/ruby/test_thread_queue.rb:124]: <#> expected but was . ``` I'm hoping joining for longer should help avoid this. --- test/ruby/test_thread_queue.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb index aa4ea0a4009d86..1c852474b4277f 100644 --- a/test/ruby/test_thread_queue.rb +++ b/test/ruby/test_thread_queue.rb @@ -121,11 +121,11 @@ def test_queue_pop_timeout assert_nil t1.value t2 = Thread.new { q.pop(timeout: 0.1) } - assert_equal t2, t2.join(0.2) + assert_equal t2, t2.join(1) assert_nil t2.value ensure - t1&.kill - t2&.kill + t1&.kill&.join + t2&.kill&.join end def test_queue_pop_non_block @@ -154,11 +154,11 @@ def test_sized_queue_pop_timeout assert_nil t1.value t2 = Thread.new { q.pop(timeout: 0.1) } - assert_equal t2, t2.join(0.2) + assert_equal t2, t2.join(1) assert_nil t2.value ensure - t1&.kill - t2&.kill + t1&.kill&.join + t2&.kill&.join end def test_sized_queue_pop_non_block From b54f26b7048fc8dd103e7da5cf8f8dd73feb10d0 Mon Sep 17 00:00:00 2001 From: tompng Date: Tue, 2 Aug 2022 04:10:45 +0900 Subject: [PATCH 128/142] [ruby/irb] shortcut colorize_code to speedup pretty_print https://github.com/ruby/irb/commit/8a074a6904 --- lib/irb/color_printer.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/irb/color_printer.rb b/lib/irb/color_printer.rb index 78f0b51520324f..1127bcecb4932c 100644 --- a/lib/irb/color_printer.rb +++ b/lib/irb/color_printer.rb @@ -37,6 +37,9 @@ def text(str, width = nil) width ||= str.length case str + when '' + when ',', '=>', '[', ']', '{', '}', '..', '...', /\A@\w+\z/ + super(str, width) when /\A#' super(Color.colorize(str, [:GREEN]), width) else From 394486206603f701ac756cd0cc0c0f642152e035 Mon Sep 17 00:00:00 2001 From: git Date: Thu, 4 Aug 2022 08:37:19 +0900 Subject: [PATCH 129/142] * 2022-08-04 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 0839bef786ef53..313c1feaf9e490 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 3 +#define RUBY_RELEASE_DAY 4 #include "ruby/version.h" #include "ruby/internal/abi.h" From 0591780a74f9893038d5d794a958621189953e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 2 Aug 2022 11:25:51 +0200 Subject: [PATCH 130/142] [rubygems/rubygems] Extract entry.full_name to a variable https://github.com/rubygems/rubygems/commit/3973773005 --- lib/rubygems/package.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 1e87837b0e9009..8d7aa01f6ee410 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -411,15 +411,16 @@ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: directories = [] open_tar_gz io do |tar| tar.each do |entry| - next unless File.fnmatch pattern, entry.full_name, File::FNM_DOTMATCH + full_name = entry.full_name + next unless File.fnmatch pattern, full_name, File::FNM_DOTMATCH - destination = install_location entry.full_name, destination_dir + destination = install_location full_name, destination_dir if entry.symlink? link_target = entry.header.linkname real_destination = link_target.start_with?("/") ? link_target : File.expand_path(link_target, File.dirname(destination)) - raise Gem::Package::SymlinkError.new(entry.full_name, real_destination, destination_dir) unless + raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless normalize_path(real_destination).start_with? normalize_path(destination_dir + "/") end From 542040fb8375ffd74096ae0615a33bbc90524cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 2 Aug 2022 10:27:42 +0200 Subject: [PATCH 131/142] [rubygems/rubygems] Warn dangling symlinks https://github.com/rubygems/rubygems/commit/425b78637f --- lib/rubygems/installer.rb | 10 +--------- lib/rubygems/package.rb | 14 ++++++++++++-- test/rubygems/test_gem_installer.rb | 5 ++++- test/rubygems/test_gem_package.rb | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 8ec75d1ff7405d..b764f21a4f9537 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -490,15 +490,7 @@ def generate_bin # :nodoc: spec.executables.each do |filename| filename.tap(&Gem::UNTAINT) bin_path = File.join gem_dir, spec.bindir, filename - - unless File.exist? bin_path - if File.symlink? bin_path - alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`" - else - alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" - end - next - end + next unless File.exist? bin_path mode = File.stat(bin_path).mode dir_mode = options[:prog_mode] || (mode | 0111) diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 8d7aa01f6ee410..77f9f282d8fb79 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -409,6 +409,8 @@ def extract_files(destination_dir, pattern = "*") def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: directories = [] + symlinks = [] + open_tar_gz io do |tar| tar.each do |entry| full_name = entry.full_name @@ -422,6 +424,8 @@ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless normalize_path(real_destination).start_with? normalize_path(destination_dir + "/") + + symlinks << [full_name, link_target, destination, real_destination] end FileUtils.rm_rf destination @@ -445,12 +449,18 @@ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: FileUtils.chmod file_mode(entry.header.mode), destination end if entry.file? - File.symlink(entry.header.linkname, destination) if entry.symlink? - verbose destination end end + symlinks.each do |name, target, destination, real_destination| + if File.exist?(real_destination) + File.symlink(target, destination) + else + alert_warning "#{@spec.full_name} ships with a dangling symlink named #{name} pointing to missing #{target} file. Ignoring" + end + end + if dir_mode File.chmod(dir_mode, *directories) end diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index d269644ade541d..55f0a074b8776b 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -756,7 +756,10 @@ def test_generate_bin_with_dangling_symlink end end - assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error + errors = @ui.error.split("\n") + assert_equal "WARNING: ascii_binder-0.1.10.1 ships with a dangling symlink named bin/ascii_binder pointing to missing bin/asciibinder file. Ignoring", errors.shift + assert_empty errors + assert_empty @ui.output end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 9e18dacba1a324..9295f42dba0140 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -529,6 +529,7 @@ def test_extract_tar_gz_absolute def test_extract_tar_gz_symlink_relative_path package = Gem::Package.new @gem + package.verify tgz_io = util_tar_gz do |tar| tar.add_file "relative.rb", 0644 do |io| @@ -557,6 +558,27 @@ def test_extract_tar_gz_symlink_relative_path File.read(extracted) end + def test_extract_tar_gz_symlink_broken_relative_path + package = Gem::Package.new @gem + package.verify + + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0755 + tar.add_symlink "lib/foo.rb", "../broken.rb", 0644 + end + + ui = Gem::MockGemUi.new + + use_ui ui do + package.extract_tar_gz tgz_io, @destination + end + + assert_equal "WARNING: a-2 ships with a dangling symlink named lib/foo.rb pointing to missing ../broken.rb file. Ignoring\n", ui.error + + extracted = File.join @destination, "lib/foo.rb" + assert_path_not_exist extracted + end + def test_extract_symlink_parent package = Gem::Package.new @gem From 50d81bfbc19d9b2e3d4be511c26c3dff317e2f8e Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 28 Jul 2022 17:19:28 +0900 Subject: [PATCH 132/142] Link ext bundles with bundle loader option for newer ld64 ld64 shipped with Xcode 14 emits a warning when using `-undefined dynamic_lookup`. ``` ld: warning: -undefined dynamic_lookup may not work with chained fixups ``` Actually, `-undefined dynamic_lookup` doesn't work when: 1. Link a *shared library* with the option 2. Link it with a program that uses the chained-fixup introduced from macOS 12 and iOS 15 because `-undefined dynamic_lookup` uses lazy-bindings and they won't be bound while dyld fixes-up by traversing chained-fixup info. However, we build exts as *bundles* and they are loaded only through `dlopen`, so it's safe to use `-undefined dynamic_lookup` in theory. So the warning produced by ld64 is false-positive, and it results failure of option checking in configuration. Therefore, it would be an option to ignore the warning during our configuration. On the other hand, `-undefined dynamic_lookup` is already deprecated on all darwin platforms except for macOS, so it's good time to get rid of the option. ld64 also provides `-bundle_loader ` option, which allows to resolve symbols defined in the executable symtab while linking. It behaves almost the same with `-undefined dynamic_lookup`, but it makes the following changes: 1. Require that unresolved symbols among input objects must be defined in the executable. 2. Lazy symbol binding will lookup only the symtab of the bundle loader executable. (`-undefined dynamic_lookup` lookups all symtab as flat namespace) This patch adds `-bundle_loader $(RUBY)` when non-EXTSTATIC configuration by assuming ruby executable can be linked before building exts. See "New Features" subsection under "Linking" section for chained fixup https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes --- configure.ac | 10 ++++++++-- enc/Makefile.in | 2 ++ ext/extmk.rb | 5 ++++- lib/mkmf.rb | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 864a9a4e8b0499..4da115ce4ca836 100644 --- a/configure.ac +++ b/configure.ac @@ -3011,6 +3011,12 @@ STATIC= : ${LDFLAGS=""} : ${LIBPATHENV=DYLD_FALLBACK_LIBRARY_PATH} : ${PRELOADENV=DYLD_INSERT_LIBRARIES} + AS_IF([test "x$EXTSTATIC" = x], [ + # When building ext bundles, a mach-o bundle needs to know its loader + # program to bind symbols from the ruby executable + EXTDLDFLAGS='-bundle_loader $(BUILTRUBY)' + PREP="$PREP"' $(PROGRAM)' + ]) rb_cv_dlopen=yes], [aix*], [ : ${LDSHARED='$(CC)'} AS_IF([test "$GCC" = yes], [ @@ -3334,7 +3340,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ AC_SUBST(XRUBY_LIBDIR) AC_SUBST(XRUBY_RUBYLIBDIR) AC_SUBST(XRUBY_RUBYHDRDIR) - PREP='$(arch)-fake.rb' + PREP="$PREP "'$(arch)-fake.rb' RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`' RUNRUBY='$(RUNRUBY_COMMAND)' XRUBY='$(MINIRUBY)' @@ -3344,7 +3350,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ ], [ MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.' MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common' - PREP='miniruby$(EXEEXT)' + PREP="$PREP "'miniruby$(EXEEXT)' RUNRUBY_COMMAND='$(MINIRUBY) $(tooldir)/runruby.rb --extout=$(EXTOUT) $(RUNRUBYOPT)' RUNRUBY='$(RUNRUBY_COMMAND) --' XRUBY='$(RUNRUBY)' diff --git a/enc/Makefile.in b/enc/Makefile.in index 5e5d39cd76498d..0e1a27a6675b5b 100644 --- a/enc/Makefile.in +++ b/enc/Makefile.in @@ -22,6 +22,7 @@ TRANSSODIR = $(ENCSODIR)/trans DLEXT = @DLEXT@ OBJEXT = @OBJEXT@ LIBEXT = @LIBEXT@ +EXEEXT = @EXEEXT@ TIMESTAMPDIR = $(EXTOUT)/.timestamp ENC_TRANS_D = $(TIMESTAMPDIR)/.enc-trans.time ENC_TRANS_SO_D = $(TIMESTAMPDIR)/.enc-trans.so.time @@ -35,6 +36,7 @@ RUBY_SO_NAME = @RUBY_SO_NAME@ LIBRUBY = @LIBRUBY@ LIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@ LIBRUBYARG_STATIC = $(LIBRUBYARG_SHARED) +BUILTRUBY = $(topdir)/ruby$(EXEEXT) empty = AR = @AR@ diff --git a/ext/extmk.rb b/ext/extmk.rb index b5ff735cc45f88..70067d28b8feab 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -412,9 +412,12 @@ def $mflags.defined?(var) $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY'] elsif sep = config_string('BUILD_FILE_SEPARATOR') $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT -else +elsif CONFIG['EXTSTATIC'] $ruby = '$(topdir)/miniruby' + EXEEXT +else + $ruby = '$(topdir)/ruby' + EXEEXT end +$mflags << "BUILTRUBY=#$ruby" $ruby = [$ruby] $ruby << "-I'$(topdir)'" unless CROSS_COMPILING diff --git a/lib/mkmf.rb b/lib/mkmf.rb index a6ec9bae5d3ebc..79bb96ba75330a 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -2076,6 +2076,7 @@ def configuration(srcdir) ruby_version = #{RbConfig::CONFIG['ruby_version']} ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}} RUBY = $(ruby#{sep}) +BUILTRUBY = $(RUBY) ruby_headers = #{headers.join(' ')} RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'} From c69582a5401ac7b6e59b87a8bcc8636c27eb923e Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 29 Jul 2022 14:18:26 -0400 Subject: [PATCH 133/142] Quote $(BUILTRUBY) so paths with spaces work --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4da115ce4ca836..1808a643f376a0 100644 --- a/configure.ac +++ b/configure.ac @@ -3014,7 +3014,7 @@ STATIC= AS_IF([test "x$EXTSTATIC" = x], [ # When building ext bundles, a mach-o bundle needs to know its loader # program to bind symbols from the ruby executable - EXTDLDFLAGS='-bundle_loader $(BUILTRUBY)' + EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'" PREP="$PREP"' $(PROGRAM)' ]) rb_cv_dlopen=yes], From e5a3f232563139fdf15660d54aeaec112ffc2349 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 29 Jul 2022 13:54:27 -0400 Subject: [PATCH 134/142] Use $(bindir) for path to executable in mkmf For the macOS -bundle_loader linker option, we need a path to the Ruby exectuable. $(RUBY) is not necessarily a path since it could be a command line invocation. That happens during build with runruby.rb and can happen post installation if the user passes the --ruby option to a extconf.rb. Use $(bindir) to locate the executable instead. Before installation, $(bindir) doesn't exist, so we need to be able to override $(BUILTRUBY) in such situations so test-spec and bundled extensions could build. Use a new mkmf global, $builtruby, to do this; set it in fake.rb and in extmk.rb. Our build system is quite complex... --- ext/extmk.rb | 2 +- lib/mkmf.rb | 6 +++++- tool/fake.rb | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ext/extmk.rb b/ext/extmk.rb index 70067d28b8feab..b0d84ef00fd611 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -417,7 +417,6 @@ def $mflags.defined?(var) else $ruby = '$(topdir)/ruby' + EXEEXT end -$mflags << "BUILTRUBY=#$ruby" $ruby = [$ruby] $ruby << "-I'$(topdir)'" unless CROSS_COMPILING @@ -428,6 +427,7 @@ def $mflags.defined?(var) topruby = $ruby $ruby = topruby.join(' ') $mflags << "ruby=#$ruby" +$builtruby = '$(topdir)/ruby' + EXEEXT # Must be an executable path MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)} diff --git a/lib/mkmf.rb b/lib/mkmf.rb index 79bb96ba75330a..efe3419fd700fb 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -2076,7 +2076,11 @@ def configuration(srcdir) ruby_version = #{RbConfig::CONFIG['ruby_version']} ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}} RUBY = $(ruby#{sep}) -BUILTRUBY = $(RUBY) +BUILTRUBY = #{if defined?($builtruby) && $builtruby + $builtruby + else + File.join('$(bindir)', CONFIG["RUBY_INSTALL_NAME"] + CONFIG['EXEEXT']) + end} ruby_headers = #{headers.join(' ')} RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'} diff --git a/tool/fake.rb b/tool/fake.rb index 88709b2f23ee61..91dfb041c4e30d 100644 --- a/tool/fake.rb +++ b/tool/fake.rb @@ -45,6 +45,7 @@ class File $extout_prefix = '$(extout)$(target_prefix)/' config = RbConfig::CONFIG mkconfig = RbConfig::MAKEFILE_CONFIG + $builtruby ||= File.join(builddir, config['RUBY_INSTALL_NAME'] + config['EXEEXT']) RbConfig.fire_update!("builddir", builddir) RbConfig.fire_update!("buildlibdir", builddir) RbConfig.fire_update!("libdir", builddir) From 6d8b9a9d619821b722273d93cdc4645ae2e23ede Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 30 Jul 2022 17:25:12 +0900 Subject: [PATCH 135/142] Resolve abi symbol references from miniruby to avoid circular deps Adding `ruby` to `PREP` causes the following circular dependencies because `PREP` is used as a prerequisite by some targets required to build `ruby` target itself. ``` make: Circular .rbconfig.time <- ruby dependency dropped. make: Circular builtin_binary.inc <- ruby dependency dropped. make: Circular ext/extinit.c <- ruby dependency dropped. make: Circular ruby <- ruby dependency dropped. ``` Adding a new Make variable like `EXTPREP` only for exts may be also reasonable, but it would introduce another complexity into our build system. `-bundle_loader` doesn't care that link-time and run-time loader executables are different as long as bound symbols are provided, so it's ok to resolve from miniruby to simplify our build. --- configure.ac | 5 ++--- enc/Makefile.in | 2 +- ext/extmk.rb | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 1808a643f376a0..c68b7632e680b7 100644 --- a/configure.ac +++ b/configure.ac @@ -3015,7 +3015,6 @@ STATIC= # When building ext bundles, a mach-o bundle needs to know its loader # program to bind symbols from the ruby executable EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'" - PREP="$PREP"' $(PROGRAM)' ]) rb_cv_dlopen=yes], [aix*], [ : ${LDSHARED='$(CC)'} @@ -3340,7 +3339,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ AC_SUBST(XRUBY_LIBDIR) AC_SUBST(XRUBY_RUBYLIBDIR) AC_SUBST(XRUBY_RUBYHDRDIR) - PREP="$PREP "'$(arch)-fake.rb' + PREP='$(arch)-fake.rb' RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`' RUNRUBY='$(RUNRUBY_COMMAND)' XRUBY='$(MINIRUBY)' @@ -3350,7 +3349,7 @@ AS_IF([test x"$cross_compiling" = xyes], [ ], [ MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib -I.' MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common' - PREP="$PREP "'miniruby$(EXEEXT)' + PREP='miniruby$(EXEEXT)' RUNRUBY_COMMAND='$(MINIRUBY) $(tooldir)/runruby.rb --extout=$(EXTOUT) $(RUNRUBYOPT)' RUNRUBY='$(RUNRUBY_COMMAND) --' XRUBY='$(RUNRUBY)' diff --git a/enc/Makefile.in b/enc/Makefile.in index 0e1a27a6675b5b..dd8ca1b5281aad 100644 --- a/enc/Makefile.in +++ b/enc/Makefile.in @@ -36,7 +36,7 @@ RUBY_SO_NAME = @RUBY_SO_NAME@ LIBRUBY = @LIBRUBY@ LIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@ LIBRUBYARG_STATIC = $(LIBRUBYARG_SHARED) -BUILTRUBY = $(topdir)/ruby$(EXEEXT) +BUILTRUBY = $(topdir)/miniruby$(EXEEXT) empty = AR = @AR@ diff --git a/ext/extmk.rb b/ext/extmk.rb index b0d84ef00fd611..1624ec9099eb40 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -427,7 +427,7 @@ def $mflags.defined?(var) topruby = $ruby $ruby = topruby.join(' ') $mflags << "ruby=#$ruby" -$builtruby = '$(topdir)/ruby' + EXEEXT # Must be an executable path +$builtruby = '$(topdir)/miniruby' + EXEEXT # Must be an executable path MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)} From 184fd94d7e8023d7720be985089bae00c4bdfa2b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 30 Jul 2022 18:32:38 +0900 Subject: [PATCH 136/142] Resolve abi symbols from libruby.dylib when available --- configure.ac | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index c68b7632e680b7..9ed0c1ef9e2ca9 100644 --- a/configure.ac +++ b/configure.ac @@ -3011,10 +3011,13 @@ STATIC= : ${LDFLAGS=""} : ${LIBPATHENV=DYLD_FALLBACK_LIBRARY_PATH} : ${PRELOADENV=DYLD_INSERT_LIBRARIES} - AS_IF([test "x$EXTSTATIC" = x], [ - # When building ext bundles, a mach-o bundle needs to know its loader - # program to bind symbols from the ruby executable - EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'" + AS_IF([test x"$enable_shared" = xyes], [ + # Resolve symbols from libruby.dylib when --enable-shared + EXTDLDFLAGS='$(LIBRUBYARG_SHARED)' + ], [test "x$EXTSTATIC" = x], [ + # When building exts as bundles, a mach-o bundle needs to know its loader + # program to bind symbols from the ruby executable + EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'" ]) rb_cv_dlopen=yes], [aix*], [ : ${LDSHARED='$(CC)'} From 00f411c58ac6105f135ff4501ea5bd1d691fcc32 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 30 Jul 2022 20:26:57 +0900 Subject: [PATCH 137/142] Add `-bundle_loader` to mjit compilation args on macOS --- mjit.c | 12 ++++++++++-- ruby.c | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/mjit.c b/mjit.c index 01ad7339f0ebfc..98f4af3d18fa71 100644 --- a/mjit.c +++ b/mjit.c @@ -811,8 +811,16 @@ start_compiling_c_to_so(const char *c_file, const char *so_file) # endif c_file, NULL }; - char **args = form_args(7, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, cc_added_args, - so_args, CC_LIBS, CC_DLDFLAGS_ARGS, CC_LINKER_ARGS); + +# if defined(__MACH__) + extern VALUE rb_libruby_selfpath; + const char *loader_args[] = {"-bundle_loader", StringValuePtr(rb_libruby_selfpath), NULL}; +# else + const char *loader_args[] = {NULL}; +# endif + + char **args = form_args(8, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, cc_added_args, + so_args, loader_args, CC_LIBS, CC_DLDFLAGS_ARGS, CC_LINKER_ARGS); if (args == NULL) return -1; rb_vm_t *vm = GET_VM(); diff --git a/ruby.c b/ruby.c index 46fb019701e138..9b9bfb54c7795b 100644 --- a/ruby.c +++ b/ruby.c @@ -22,7 +22,7 @@ # include #endif -#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR) +#if (defined(LOAD_RELATIVE) || defined(__MACH__)) && defined(HAVE_DLADDR) # include #endif @@ -534,7 +534,7 @@ str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to) void ruby_init_loadpath(void); -#if defined(LOAD_RELATIVE) +#if defined(LOAD_RELATIVE) || defined(__MACH__) static VALUE runtime_libruby_path(void) { @@ -615,6 +615,10 @@ runtime_libruby_path(void) #define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index") VALUE ruby_archlibdir_path, ruby_prefix_path; +#if defined(__MACH__) +// A path to libruby.dylib itself or where it's statically linked to. +VALUE rb_libruby_selfpath; +#endif void ruby_init_loadpath(void) @@ -622,6 +626,14 @@ ruby_init_loadpath(void) VALUE load_path, archlibdir = 0; ID id_initial_load_path_mark; const char *paths = ruby_initial_load_paths; +#if defined(LOAD_RELATIVE) || defined(__MACH__) + VALUE libruby_path = runtime_libruby_path(); +# if defined(__MACH__) + rb_libruby_selfpath = libruby_path; + rb_gc_register_address(&rb_libruby_selfpath); +# endif +#endif + #if defined LOAD_RELATIVE #if !defined ENABLE_MULTIARCH # define RUBY_ARCH_PATH "" @@ -635,7 +647,7 @@ ruby_init_loadpath(void) size_t baselen; const char *p; - sopath = runtime_libruby_path(); + sopath = libruby_path; libpath = RSTRING_PTR(sopath); p = strrchr(libpath, '/'); From 6b2fc33ae231594eb69f93c493e2c314931b0990 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 4 Aug 2022 10:37:46 +0200 Subject: [PATCH 138/142] thread_sync.c: pass proper argument to queue_sleep in rb_szqueue_push When I removed the SizeQueue#push timeout from my PR, I forgot to update the `queue_sleep` parameters to be a `queue_sleep_arg`. Somehow this worked on most archs, but on Solaris/Sparc it would legitimately crash when trying to access the `timeout` and `end` members of the struct. --- thread_sync.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/thread_sync.c b/thread_sync.c index 1a0f3ee8555c1f..0359ac2214d808 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -1277,7 +1277,13 @@ rb_szqueue_push(int argc, VALUE *argv, VALUE self) ccan_list_add_tail(pushq, &queue_waiter.w.node); sq->num_waiting_push++; - rb_ensure(queue_sleep, self, szqueue_sleep_done, (VALUE)&queue_waiter); + struct queue_sleep_arg queue_sleep_arg = { + .self = self, + .timeout = Qnil, + .end = 0 + }; + + rb_ensure(queue_sleep, (VALUE)&queue_sleep_arg, szqueue_sleep_done, (VALUE)&queue_waiter); } } From c84d0538be3b5f6739c6968f3bb1b8e4abe8eadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 4 Aug 2022 10:57:15 +0200 Subject: [PATCH 139/142] [rubygems/rubygems] Fix unused variable warning ``` /Users/deivid/Code/rubygems/rubygems/test/rubygems/test_gem_resolver_installer_set.rb:55: warning: assigned but unused variable - a_1_local ``` https://github.com/rubygems/rubygems/commit/9ea4534800 --- test/rubygems/test_gem_resolver_installer_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb index 32e1faa28d4368..ffa6b13ea4d599 100644 --- a/test/rubygems/test_gem_resolver_installer_set.rb +++ b/test/rubygems/test_gem_resolver_installer_set.rb @@ -52,7 +52,7 @@ def test_add_always_install_platform end def test_add_always_install_index_spec_platform - a_1_local, a_1_local_gem = util_gem "a", 1 do |s| + _, a_1_local_gem = util_gem "a", 1 do |s| s.platform = Gem::Platform.local end From 8bab09983046351453c7c86c003cfadad3dac01a Mon Sep 17 00:00:00 2001 From: git Date: Fri, 5 Aug 2022 00:09:30 +0900 Subject: [PATCH 140/142] * 2022-08-05 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 313c1feaf9e490..bcd3b29f5095f8 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 4 +#define RUBY_RELEASE_DAY 5 #include "ruby/version.h" #include "ruby/internal/abi.h" From 7f5f9d19c54d3d5e0c2b2947785d8821b752641d Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Thu, 4 Aug 2022 08:18:24 -0700 Subject: [PATCH 141/142] YJIT: Add known_* helpers for Type (#6208) * YJIT: Add known_* helpers for Type This adds a few helpers to Type which all return Options representing what is known, from a Ruby perspective, about the type. This includes: * known_class_of: If known, the class represented by this type * known_value_type: If known, the T_ value type * known_exact_value: If known, the exact VALUE represented by this type (currently this is only available for true/false/nil) * known_truthy: If known, whether or not this value evaluates as true (not false or nil) The goal of this is to abstract away the specifics of the mappings between types wherever possible from the codegen. For example previously by introducing Type::CString as a more specific version of Type::TString, uses of Type::TString in codegen needed to be updated to check either case. Now by using known_value_type, at least in theory we can introduce new types with minimal (if any) codegen changes. I think rust's Option type allows us to represent this uncertainty fairly well, and should help avoid mistakes, and the matching using this turned out pretty cleanly. * YJIT: Use known_value_type for checktype * YJIT: Use known_value_type for T_STRING check * YJIT: Use known_class_of in guard_known_klass * YJIT: Use known truthyness in jit_rb_obj_not * YJIT: Rename known_class_of => known_class --- yjit/src/codegen.rs | 159 ++++++++++++++++++++------------------------ yjit/src/core.rs | 54 +++++++++++++++ 2 files changed, 125 insertions(+), 88 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 0acd1972c39df1..818e3fbb41edee 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2218,22 +2218,16 @@ fn gen_checktype( let val = ctx.stack_pop(1); // Check if we know from type information - match (type_val, val_type) { - (RUBY_T_STRING, Type::TString) - | (RUBY_T_STRING, Type::CString) - | (RUBY_T_ARRAY, Type::Array) - | (RUBY_T_HASH, Type::Hash) => { - // guaranteed type match - let stack_ret = ctx.stack_push(Type::True); - mov(cb, stack_ret, uimm_opnd(Qtrue.as_u64())); - return KeepCompiling; - } - _ if val_type.is_imm() || val_type.is_specific() => { - // guaranteed not to match T_STRING/T_ARRAY/T_HASH - let stack_ret = ctx.stack_push(Type::False); - mov(cb, stack_ret, uimm_opnd(Qfalse.as_u64())); - return KeepCompiling; - } + match val_type.known_value_type() { + Some(value_type) => { + if value_type == type_val { + jit_putobject(jit, ctx, cb, Qtrue); + return KeepCompiling; + } else { + jit_putobject(jit, ctx, cb, Qfalse); + return KeepCompiling; + } + }, _ => (), } @@ -2502,7 +2496,7 @@ fn gen_equality_specialized( // Otherwise guard that b is a T_STRING (from type info) or String (from runtime guard) let btype = ctx.get_opnd_type(StackOpnd(0)); - if btype != Type::TString && btype != Type::CString { + if btype.known_value_type() != Some(RUBY_T_STRING) { mov(cb, REG0, C_ARG_REGS[1]); // Note: any T_STRING is valid here, but we check for a ::String for simplicity // To pass a mutable static variable (rb_cString) requires an unsafe block @@ -3405,78 +3399,70 @@ fn jit_guard_known_klass( ) { let val_type = ctx.get_opnd_type(insn_opnd); + if val_type.known_class() == Some(known_klass) { + // We already know from type information that this is a match + return; + } + if unsafe { known_klass == rb_cNilClass } { assert!(!val_type.is_heap()); - if val_type != Type::Nil { - assert!(val_type.is_unknown()); + assert!(val_type.is_unknown()); - add_comment(cb, "guard object is nil"); - cmp(cb, REG0, imm_opnd(Qnil.into())); - jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); + add_comment(cb, "guard object is nil"); + cmp(cb, REG0, imm_opnd(Qnil.into())); + jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::Nil); - } + ctx.upgrade_opnd_type(insn_opnd, Type::Nil); } else if unsafe { known_klass == rb_cTrueClass } { assert!(!val_type.is_heap()); - if val_type != Type::True { - assert!(val_type.is_unknown()); + assert!(val_type.is_unknown()); - add_comment(cb, "guard object is true"); - cmp(cb, REG0, imm_opnd(Qtrue.into())); - jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); + add_comment(cb, "guard object is true"); + cmp(cb, REG0, imm_opnd(Qtrue.into())); + jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::True); - } + ctx.upgrade_opnd_type(insn_opnd, Type::True); } else if unsafe { known_klass == rb_cFalseClass } { assert!(!val_type.is_heap()); - if val_type != Type::False { - assert!(val_type.is_unknown()); + assert!(val_type.is_unknown()); - add_comment(cb, "guard object is false"); - assert!(Qfalse.as_i32() == 0); - test(cb, REG0, REG0); - jit_chain_guard(JCC_JNZ, jit, ctx, cb, ocb, max_chain_depth, side_exit); + add_comment(cb, "guard object is false"); + assert!(Qfalse.as_i32() == 0); + test(cb, REG0, REG0); + jit_chain_guard(JCC_JNZ, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::False); - } + ctx.upgrade_opnd_type(insn_opnd, Type::False); } else if unsafe { known_klass == rb_cInteger } && sample_instance.fixnum_p() { - assert!(!val_type.is_heap()); // We will guard fixnum and bignum as though they were separate classes // BIGNUM can be handled by the general else case below - if val_type != Type::Fixnum || !val_type.is_imm() { - assert!(val_type.is_unknown()); + assert!(val_type.is_unknown()); - add_comment(cb, "guard object is fixnum"); - test(cb, REG0, imm_opnd(RUBY_FIXNUM_FLAG as i64)); - jit_chain_guard(JCC_JZ, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum); - } + add_comment(cb, "guard object is fixnum"); + test(cb, REG0, imm_opnd(RUBY_FIXNUM_FLAG as i64)); + jit_chain_guard(JCC_JZ, jit, ctx, cb, ocb, max_chain_depth, side_exit); + ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum); } else if unsafe { known_klass == rb_cSymbol } && sample_instance.static_sym_p() { assert!(!val_type.is_heap()); // We will guard STATIC vs DYNAMIC as though they were separate classes // DYNAMIC symbols can be handled by the general else case below - if val_type != Type::ImmSymbol || !val_type.is_imm() { - assert!(val_type.is_unknown()); - - add_comment(cb, "guard object is static symbol"); - assert!(RUBY_SPECIAL_SHIFT == 8); - cmp(cb, REG0_8, uimm_opnd(RUBY_SYMBOL_FLAG as u64)); - jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::ImmSymbol); - } + assert!(val_type.is_unknown()); + + add_comment(cb, "guard object is static symbol"); + assert!(RUBY_SPECIAL_SHIFT == 8); + cmp(cb, REG0_8, uimm_opnd(RUBY_SYMBOL_FLAG as u64)); + jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); + ctx.upgrade_opnd_type(insn_opnd, Type::ImmSymbol); } else if unsafe { known_klass == rb_cFloat } && sample_instance.flonum_p() { assert!(!val_type.is_heap()); - if val_type != Type::Flonum || !val_type.is_imm() { - assert!(val_type.is_unknown()); - - // We will guard flonum vs heap float as though they were separate classes - add_comment(cb, "guard object is flonum"); - mov(cb, REG1, REG0); - and(cb, REG1, uimm_opnd(RUBY_FLONUM_MASK as u64)); - cmp(cb, REG1, uimm_opnd(RUBY_FLONUM_FLAG as u64)); - jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); - ctx.upgrade_opnd_type(insn_opnd, Type::Flonum); - } + assert!(val_type.is_unknown()); + + // We will guard flonum vs heap float as though they were separate classes + add_comment(cb, "guard object is flonum"); + mov(cb, REG1, REG0); + and(cb, REG1, uimm_opnd(RUBY_FLONUM_MASK as u64)); + cmp(cb, REG1, uimm_opnd(RUBY_FLONUM_FLAG as u64)); + jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); + ctx.upgrade_opnd_type(insn_opnd, Type::Flonum); } else if unsafe { FL_TEST(known_klass, VALUE(RUBY_FL_SINGLETON as usize)) != VALUE(0) && sample_instance == rb_attr_get(known_klass, id__attached__ as ID) @@ -3496,11 +3482,6 @@ fn jit_guard_known_klass( jit_mov_gc_ptr(jit, cb, REG1, sample_instance); cmp(cb, REG0, REG1); jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit); - } else if val_type == Type::CString && unsafe { known_klass == rb_cString } { - // guard elided because the context says we've already checked - unsafe { - assert_eq!(sample_instance.class_of(), rb_cString, "context says class is exactly ::String") - }; } else { assert!(!val_type.is_imm()); @@ -3576,23 +3557,25 @@ fn jit_rb_obj_not( ) -> bool { let recv_opnd = ctx.get_opnd_type(StackOpnd(0)); - if recv_opnd == Type::Nil || recv_opnd == Type::False { - add_comment(cb, "rb_obj_not(nil_or_false)"); - ctx.stack_pop(1); - let out_opnd = ctx.stack_push(Type::True); - mov(cb, out_opnd, uimm_opnd(Qtrue.into())); - } else if recv_opnd.is_heap() || recv_opnd.is_specific() { - // Note: recv_opnd != Type::Nil && recv_opnd != Type::False. - add_comment(cb, "rb_obj_not(truthy)"); - ctx.stack_pop(1); - let out_opnd = ctx.stack_push(Type::False); - mov(cb, out_opnd, uimm_opnd(Qfalse.into())); - } else { - // jit_guard_known_klass() already ran on the receiver which should - // have deduced deduced the type of the receiver. This case should be - // rare if not unreachable. - return false; + match recv_opnd.known_truthy() { + Some(false) => { + add_comment(cb, "rb_obj_not(nil_or_false)"); + ctx.stack_pop(1); + let out_opnd = ctx.stack_push(Type::True); + mov(cb, out_opnd, uimm_opnd(Qtrue.into())); + }, + Some(true) => { + // Note: recv_opnd != Type::Nil && recv_opnd != Type::False. + add_comment(cb, "rb_obj_not(truthy)"); + ctx.stack_pop(1); + let out_opnd = ctx.stack_push(Type::False); + mov(cb, out_opnd, uimm_opnd(Qfalse.into())); + }, + _ => { + return false; + }, } + true } diff --git a/yjit/src/core.rs b/yjit/src/core.rs index 8242c9477ea946..64585653d94e47 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -126,6 +126,60 @@ impl Type { } } + /// Returns an Option with the T_ value type if it is known, otherwise None + pub fn known_value_type(&self) -> Option { + match self { + Type::Nil => Some(RUBY_T_NIL), + Type::True => Some(RUBY_T_TRUE), + Type::False => Some(RUBY_T_FALSE), + Type::Fixnum => Some(RUBY_T_FIXNUM), + Type::Flonum => Some(RUBY_T_FLOAT), + Type::Array => Some(RUBY_T_ARRAY), + Type::Hash => Some(RUBY_T_HASH), + Type::ImmSymbol | Type::HeapSymbol => Some(RUBY_T_SYMBOL), + Type::TString | Type::CString => Some(RUBY_T_STRING), + Type::Unknown | Type::UnknownImm | Type::UnknownHeap => None + } + } + + /// Returns an Option with the class if it is known, otherwise None + pub fn known_class(&self) -> Option { + unsafe { + match self { + Type::Nil => Some(rb_cNilClass), + Type::True => Some(rb_cTrueClass), + Type::False => Some(rb_cFalseClass), + Type::Fixnum => Some(rb_cInteger), + Type::Flonum => Some(rb_cFloat), + Type::ImmSymbol | Type::HeapSymbol => Some(rb_cSymbol), + Type::CString => Some(rb_cString), + _ => None, + } + } + } + + /// Returns an Option with the exact value if it is known, otherwise None + #[allow(unused)] // not yet used + pub fn known_exact_value(&self) -> Option { + match self { + Type::Nil => Some(Qnil), + Type::True => Some(Qtrue), + Type::False => Some(Qfalse), + _ => None, + } + } + + /// Returns an Option with the exact value if it is known, otherwise None + pub fn known_truthy(&self) -> Option { + match self { + Type::Nil => Some(false), + Type::False => Some(false), + Type::UnknownHeap => Some(true), + Type::Unknown | Type::UnknownImm => None, + _ => Some(true) + } + } + /// Compute a difference between two value types /// Returns 0 if the two are the same /// Returns > 0 if different but compatible From 1e7a2415a4c69aa64c9c2a561197bf9cfc5a91f8 Mon Sep 17 00:00:00 2001 From: Noah Gibbs Date: Thu, 4 Aug 2022 17:19:14 +0100 Subject: [PATCH 142/142] YJIT: Allow str-concat arg to be any string subtype, not just rb_cString (#6205) Allow str-concat arg to be any string subtype, not just rb_cString --- yjit/src/codegen.rs | 69 ++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 818e3fbb41edee..119477f50516ad 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1338,6 +1338,31 @@ fn guard_object_is_array( jne_ptr(cb, side_exit); } +fn guard_object_is_string( + cb: &mut CodeBlock, + object_reg: X86Opnd, + flags_reg: X86Opnd, + side_exit: CodePtr, +) { + add_comment(cb, "guard object is string"); + + // Pull out the type mask + mov( + cb, + flags_reg, + mem_opnd( + 8 * SIZEOF_VALUE as u8, + object_reg, + RUBY_OFFSET_RBASIC_FLAGS, + ), + ); + and(cb, flags_reg, uimm_opnd(RUBY_T_MASK as u64)); + + // Compare the result with T_STRING + cmp(cb, flags_reg, uimm_opnd(RUBY_T_STRING as u64)); + jne_ptr(cb, side_exit); +} + // push enough nils onto the stack to fill out an array fn gen_expandarray( jit: &mut JITState, @@ -3730,7 +3755,7 @@ fn jit_rb_str_to_s( false } -// Codegen for rb_str_concat() +// Codegen for rb_str_concat() -- *not* String#concat // Frequently strings are concatenated using "out_str << next_str". // This is common in Erb and similar templating languages. fn jit_rb_str_concat( @@ -3744,14 +3769,12 @@ fn jit_rb_str_concat( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { + // The << operator can accept integer codepoints for characters + // as the argument. We only specially optimise string arguments. + // If the peeked-at compile time argument is something other than + // a string, assume it won't be a string later either. let comptime_arg = jit_peek_at_stack(jit, ctx, 0); - let comptime_arg_type = ctx.get_opnd_type(StackOpnd(0)); - - // String#<< can take an integer codepoint as an argument, but we don't optimise that. - // Also, a non-string argument would have to call .to_str on itself before being treated - // as a string, and that would require saving pc/sp, which we don't do here. - // TODO: figure out how we should optimise a string-subtype argument here - if comptime_arg_type != Type::CString && comptime_arg.class_of() != unsafe { rb_cString } { + if ! unsafe { RB_TYPE_P(comptime_arg, RUBY_T_STRING) } { return false; } @@ -3759,19 +3782,25 @@ fn jit_rb_str_concat( let side_exit = get_side_exit(jit, ocb, ctx); // Guard that the argument is of class String at runtime. + let insn_opnd = StackOpnd(0); let arg_opnd = ctx.stack_opnd(0); mov(cb, REG0, arg_opnd); - jit_guard_known_klass( - jit, - ctx, - cb, - ocb, - unsafe { rb_cString }, - StackOpnd(0), - comptime_arg, - SEND_MAX_DEPTH, - side_exit, - ); + let arg_type = ctx.get_opnd_type(insn_opnd); + + if arg_type != Type::CString && arg_type != Type::TString { + if !arg_type.is_heap() { + add_comment(cb, "guard arg not immediate"); + test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK as i64)); + jnz_ptr(cb, side_exit); + cmp(cb, REG0, imm_opnd(Qnil.into())); + jbe_ptr(cb, side_exit); + + ctx.upgrade_opnd_type(insn_opnd, Type::UnknownHeap); + } + guard_object_is_string(cb, REG0, REG1, side_exit); + // We know this has type T_STRING, but not necessarily that it's a ::String + ctx.upgrade_opnd_type(insn_opnd, Type::TString); + } let concat_arg = ctx.stack_pop(1); let recv = ctx.stack_pop(1); @@ -3794,7 +3823,7 @@ fn jit_rb_str_concat( test(cb, REG0, uimm_opnd(RUBY_ENCODING_MASK as u64)); let enc_mismatch = cb.new_label("enc_mismatch".to_string()); - jne_label(cb, enc_mismatch); + jnz_label(cb, enc_mismatch); // If encodings match, call the simple append function and jump to return call_ptr(cb, REG0, rb_yjit_str_simple_append as *const u8);