Commit Graph

3465 Commits

Author SHA1 Message Date
Rafael França
61716e1fde
Merge pull request #39350 from jaynetics/fix_rounding_of_custom_formatted_negative_amounts
Fix rounding of custom-formatted negative amounts
2020-08-26 16:08:55 -04:00
Rafael França
7bd416363a
Merge pull request #38699 from jasonyork/master
Add ActiveSupport::Duration conversion methods
2020-08-26 13:49:21 -04:00
Akshay Birajdar
a12a2707ac Implement #inspect for ActiveSupport::OrderedOptions 2020-08-26 21:50:09 +05:30
Jason York
a2535d9fe9 Rename prefix to in_* and update CHANGELOG 2020-08-26 09:36:03 -05:00
Jason York
7bd9603778 Add ActiveSupport::Duration conversion methods 2020-08-26 09:35:09 -05:00
Daniel Pepper
964e7ad156
deep dup
Is there a reason we're only taking this short cut for frozen strings and not other immutable objects commonly used as hash keys (eg. symbols and integers)?

initial tests suggest a ~30% performance improvement...

```

require 'benchmark'

class Object
  def deep_dup
    dup
  end
  alias deep_dup_all deep_dup
end

class Hash
 def deep_dup
   hash = dup
   each_pair do |key, value|
     if key.frozen? && ::String === key
       hash[key] = value.deep_dup
     else
       hash.delete(key)
       hash[key.deep_dup] = value.deep_dup
     end
   end
   hash
 end

 def deep_dup_all
   hash = dup
   each_pair do |key, value|
     if key.frozen?
       hash[key] = value.deep_dup_all
     else
       hash.delete(key)
       hash[key.deep_dup_all] = value.deep_dup_all
     end
   end
   hash
 end
end

data = Hash[('aaa'..'zzz').map {|k| [k.to_sym, k]}]

control = Benchmark.realtime do
  30.times { data.deep_dup }
end

experiment = Benchmark.realtime do
  30.times { data.deep_dup_all }
end

puts "%.3f  v  %.3f  => %d%% speed up" % [ control, experiment, (control - experiment) / control * 100 ]

```
2020-08-17 15:24:47 -07:00
Rajesh Sharma
4a552c3ab9 Fix option not being passed with fetch_multi
In redis cache store, options to `fetch_multi` are passed correctly to
`write_multi` but not to `read_multi`. This causes cache always to be missed
when passing `namespace` option to it.
2020-07-26 08:34:30 +02:00
maxgurewitz
73ba6faa36 prevents redundant memcached compression
- Disables Dalli compression in MemCacheStore.
- Fixes issue where redundant compression in Dalli can cause values to
either be compressed twice, or compressed when they fall below the
specified compression threshold.
2020-07-25 12:59:39 -07:00
maxgurewitz
f1fb097a74 prevents raw redis and memcached compression
- Fixes issue where reads with raw: true using redis or memcached cache
store, will compress values on reads.
- Should speed up raw cache reads by preventing unnecessary cpu intensive
operation.
2020-07-24 11:56:43 -07:00
Eugene Kenny
19d8578361 Add a regression test for per-fiber tagged logging
Followup to 978421abd83d45b72e299f50a4fb324fcbdb3e00.
2020-07-02 22:37:23 +01:00
Jean Boussier
12f3f11f61 Use URI::DEFAULT_PARSER rather than instantiate a new one 2020-06-29 23:06:34 +02:00
colorbox
3758274b3b Fix an error for FileStore.cleanup when using Sprockets
### Summary

This PR fixes `NoMethodError` for `ActiveSupport::Cache::FileStore.cleanup` when using [Sprockets](https://github.com/rails/sprockets).

`FileStore.cleanup` assumes entry object is a `Cache::Entry`.
An entry obejct is returned from `FileStore.read_entry` method.
If `FileStore.read_entry` returns object that cannot respond to `expired?` method, `FileStore.cleanup` will fail.

Sprockets generates cache file in tmp/cache/assets.
If `FileStore.read_entry` gets these Sprocket's cache file, this method creates entry object which cannot respond to `expired?` method.

In my project, this error occured and failed to execute `ActiveSupport::Cache::FileStore.cleanup`.

This PR adds a `is_a?` checking to entry object in `read_entry` method.
2020-06-25 23:58:30 +09:00
Ryuta Kamizono
37c19f7ebc Fix Active Support failure for redis 4.2.0 with Ruby 2.8.0-dev 2020-06-10 09:25:03 +09:00
Jonathan Hefner
8f8aa857e0 Alias direct_descendants as subclasses
This alias overrides Class#subclasses.  Thus calls to `subclasses` get a
free performance boost when the class extends DescendantsTracker.
2020-06-02 22:57:48 -05:00
Kasper Timm Hansen
3b953da779
Catch Time.zone before TestHelper resets it to UTC
This is most easiest done by switching to before_setup, which fits since
we're also testing the ordering of the reset calls provided by the
TestHelper.
2020-06-02 01:31:14 +02:00
Kasper Timm Hansen
c962409ba6
Reset ActiveSupport::CurrentAttributes even where executor doesn't wrap
Currently there's a problem with ActiveSupport::CurrentAttributes where
they don't reset unless there's a controller or a job executing.

This is because we correctly hook into the controller/job executor to
reset them.

However, we were missing plain tests, so this is that.
2020-05-31 22:26:24 +02:00
Alexander Shemetovskiy
3d1b9389a9
Test that Array#extract_options! extracts ActiveSupport::OrderedOptions 2020-05-24 16:59:42 -04:00
Eugene Kenny
537b071002 Copy options before delegating in with_options
cd31e113c0663dabcdc293d9e7dc3b6e1392db5d switched to passing options as
keyword arguments, which always creates a new hash.

9e4ff29f748b05c3a949f0d75167950039b6cda8 removed a now-unnecessary call
to `dup`, since the options could no longer be accidentally mutated.

a55620f3fa89d957817349e5170f686d505eeee4 switched back to passing
options as a positional argument for Ruby < 2.7, but didn't restore the
call to `dup`, which meant that the same options hash was now passed
with every method call and mutations leaked from one call to another.
2020-05-23 22:47:48 +01:00
Mads Ohm Larsen
e2a2ee008b Decoding JSON dates should respect newlines 2020-05-21 13:04:01 +02:00
Jannosch Müller
31575b39ca Fix rounding of custom-formatted negative amounts
closes #39349
2020-05-20 12:34:20 +02:00
Aaron Patterson
b472feddbc
Merge branch 'master-sec'
* master-sec:
  Check that request is same-origin prior to including CSRF token in XHRs
  HMAC raw CSRF token before masking it, so it cannot be used to reconstruct a per-form token
  activesupport: Avoid Marshal.load on raw cache value in RedisCacheStore
  activesupport: Avoid Marshal.load on raw cache value in MemCacheStore
  Return self when calling #each, #each_pair, and #each_value instead of the raw @parameters hash
  Include Content-Length in signature for ActiveStorage direct upload
2020-05-18 08:48:41 -07:00
Ryan Davis
3116bdceba Fixed BacktraceCleaner to never return an empty backtrace.
Empty backtraces means you didn't run any code, which isn't the case,
and goes against the contract that Minitest.backtrace_cleaner expects.
This fixes a bug I've seen in a number of reports.

It would be nice if this got backported to whatever versions are
active, as this keeps coming back on minitest issues.
2020-05-15 16:42:27 -07:00
Dylan Thacker-Smith
9b4aef4be3
activesupport: Avoid Marshal.load on raw cache value in RedisCacheStore
The same value for the `raw` option should be provided for both reading and
writing to avoid Marshal.load being called on untrusted data.

[CVE-2020-8165]
2020-05-15 15:38:33 -07:00
Dylan Thacker-Smith
0a4cf42311
activesupport: Avoid Marshal.load on raw cache value in MemCacheStore
Dalli is already being used for marshalling, so we should also rely
on it for unmarshalling. Since Dalli tags the cache value as marshalled
it can avoid unmarshalling a raw string which might have come from
an untrusted source.

[CVE-2020-8165]
2020-05-15 15:38:29 -07:00
Ryuta Kamizono
37c7481826 Callbacks tests also uses singleton class eval 2020-05-10 04:25:26 +09:00
akinomaeni
6379f99c97 Add tests for to_s(:inspect) 2020-05-10 00:03:37 +09:00
Jean Boussier
8c0b94b995 Make NameError#missing_name work even for real Ruby NameError
On constant missing Ruby call `#inspect` on the receiver to build
the error message.

For instance, the error message for `Foo::Bar` will be `"#{Foo.inspect}::Bar"`.

And since Active Record override the model classes inspect method, this
breaks `missing_name` assumptions.

Until now it worked because missing_name was only called on errors
raised by the classic autoloader, and the classic autoloader calls
`#name` to build its error message.
2020-05-08 17:08:38 +02:00
Eugene Kenny
343638d7d9 Preserve multiple arguments in Symbol#start_with? and Symbol#end_with?
Followup to 62a20c2a642a2ae6ac7c265af1fe8fdf33114bf4, for consistency
with the upstream implementation.
2020-05-06 03:04:42 +01:00
Ryuta Kamizono
62a20c2a64 Add 3rd person aliases of Symbol#start_with? and Symbol#end_with?
This is the opposite direction of #39152.
2020-05-06 02:18:26 +09:00
Ryuta Kamizono
783a195cb7 Revert "Merge pull request #39152 from kamipo/deprecate_starts_ends_with"
This reverts commit 55e038cf17afcd6712d38d5a43d463bc7f7d098f, reversing
changes made to 8b900a7105eb4ae6957017a99a89e276186c287c.
2020-05-05 23:19:02 +09:00
Ryuta Kamizono
6a4395f466 Deprecate starts_with? and ends_with? for String core extensions
In the past, we sometimes hit missing `Symbol#start_with?` and
`Symbol#end_with?`.

63256bc5d7
a8e812964d

So I proposed `Symbol#start_with?` and `Symbol#end_with?` to allow duck
typing that methods for String and Symbol, then now it is available in
Ruby 2.7.

https://bugs.ruby-lang.org/issues/16348

Using `String#starts_with?` and `String#ends_with?` could not be gained
that conveniency, so it is preferable to not use these in the future.
2020-05-05 15:51:24 +09:00
Jack McCracken
dd870dd029
Add a separator to the cache key for ActiveSupport::CachingKeyGenerator 2020-05-04 13:56:38 -04:00
Roman Kushnir
17e24f92f1 Add override of unary plus for ActiveSupport::Duration
```ruby
(+ 1.second).class
=> ActiveSupport::Duration
```

Fixes #39079.
2020-04-30 01:54:47 +02:00
Godfrey Chan
1064c51609 Fix typos [ci skip]
I wrote this shell script to find words from the Rails repo,
so I can paste them into https://www.horsepaste.com/ for
the [codenames game](https://en.m.wikipedia.org/wiki/Codenames_(board_game)).

```bash
git grep -Il '' | \
  grep -v -E "CHANGELOG|Gemfile|gemspec|package\.json|yarn\.lock" | \
  xargs cat | \
  sed '/[^ ]\{10,\}/d' | \
  sed 's/\([A-Z]\)/ \1/g' | \
  tr 'A-Z' 'a-z' | \
  tr -c -s 'a-z' '\n' | \
  sed '/^.\{0,3\}$/d' | \
  sort | \
  uniq | \
  tr '\n' ',' | \
  pbcopy
```

You can see the result in https://www.horsepaste.com/rails-fixed.
Click "Next game" to cycle the words.

Found some typos in the codebase from this 😂

This is how I generated the list of possible typos:

```bash
git grep -Il '' | \
  grep -v -E "CHANGELOG|Gemfile|gemspec|package\.json|yarn\.lock" | \
  xargs cat | \
  sed '/[^ ]\{10,\}/d' | \
  sed 's/\([A-Z]\)/ \1/g' | \
  tr 'A-Z' 'a-z' | \
  tr -c -s 'a-z' '\n' | \
  sed '/^.\{0,3\}$/d' | \
  sort | \
  uniq | \
  aspell --ignore-case list
```

I manually reviewed the list and made the corrections
in this commit. The rest on the list are either:

* Bugs in my script: it split things like "doesn't" into
  "doesn" and "t", if find things like `#ffffff` and
  extracts "ffffff" as a word, etc
* British spelling: honour, optimised
* Foreign words: bonjour, espanol
* Names: nginx, hanekawa
* Technical words: mutex, xhtml
* Portmanteau words: autosave, nodelist
* Invented words: camelize, coachee
* Shortened words: attrs, repo
* Deliberate typos: hllo, hillo (used in code examples, etc)
* Lorem ipsum words: arcu, euismod

This is the [output](https://gist.github.com/chancancode/eb0b573d667dc31906f33f1fb0b22313)
of the script *after* fixing the typos included in this
commit. In theory, someone can run that command again in
the future and compare the output to catch new typos (i.e.
using my list to filter out known typos).

Limitations: the aspell dictionary could be wrong, I
could have miss things, and my script ignores words that
are less than 3 characters or longer than 10 characters.
2020-04-22 21:43:37 -07:00
akinomaeni
cbc8057bbb Add subsec to ActiveSupport::TimeWithZone#inspect
Time.at(1498099140).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00.000000000 UTC +00:00"
Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00.123456780 UTC +00:00"
Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00.333333333 UTC +00:00"
2020-04-11 10:22:23 +09:00
akinomaeni
1e799f2385 Add subsec to ActiveSupport::TimeWithZone#inspect
Time.at(1498099140).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00.12345678 UTC +00:00"
Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
=> "Thu, 22 Jun 2017 02:39:00 1/3 UTC +00:00"
2020-04-04 22:57:06 +09:00
George Claghorn
8c4d6a04f8 Redis cache store: fix expanding empty keys with no namespace 2020-03-31 17:39:06 -04:00
Eugene Kenny
f84e0d64dd Allow logs to be tagged without a block
Calling `#tagged` without a block now returns a new logger with the tags
applied. This is useful for when you want to tag an individual log line,
rather than an entire request.
2020-03-31 16:02:59 +01:00
Michael Groeneman
e4068f5ff2 Align Range#cover? extension behavior with Ruby behavior for backwards ranges.
`(1..10).cover?(5..3)` now returns `false`, as it does in plain Ruby. Previously this returned `true`.

Also update `#include?` and `#===` behavior to match.
2020-03-30 13:52:47 -07:00
Kasper Timm Hansen
bf34c808f9
Merge branch 'tzinfo2' 2020-03-28 20:53:24 +01:00
Phil Ross
e9425abe33
Update to TZInfo v2.0.0
Co-authored-by: Jared Beck <jared@jaredbeck.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2020-03-28 20:42:43 +01:00
Ryuta Kamizono
c728f8ec97 Restore the lookup_store compatibility to accept config as a single object
fa986ae broke the `lookup_store` compatibility. It's public API so
deprecation cycle is required if we want to make a breaking change.
2020-03-25 06:05:57 +09:00
Jatin Dhankhar
5df9b4584c
Add Date and Time #yesterday? and #tomorrow? (#37625)
Add Date and Time `#yesterday?` and `#tomorrow?` alongside `#today?`.

Aliased to `#prev_day?` and `#next_day?` to match the existing `#prev/next_day` methods.
2020-03-19 20:30:14 -07:00
Eugene Kenny
a4914a436e Add Enumerable#pick to complement Relation#pick
This allows `pick` to be called on an object that could either be an
enumerable or a relation.

Also clarify the documentation for `Enumerable#pluck`, and add an
example of plucking multiple keys to the core extensions guide.
2020-03-18 20:03:56 +00:00
utilum
879918b586 Fix variable not initialized warnings
```
activesupport/test/concern_test.rb:20: warning: instance variable
@included_ran not initialized

activesupport/test/concern_test.rb:28: warning: instance variable
@prepended_ran not initialized
```
2020-03-13 00:14:45 +01:00
Rafael França
40b7d93c5b
Merge pull request #38576 from Edouard-chin/ec-activejob-deprecation
Fix AJ wrong deprecation message on `after_callbacks_if_terminated`:
2020-03-03 15:28:50 -05:00
Edouard CHIN
06dd162fb3 ActiveSupport::Calbacks#halted_callback_hook receive callback name:
- The `halted_callback_hook` method is called whenever the
  `terminator` halt the callback execution.
  Usually, this translate to when a `before` callback throw
  an `:abort`.

  <details>
    <summary> Example </summary>

    ```ruby
      class Foo
        include ActiveSupport::Callbacks

	define_callbacks :save
	set_callback(:save, :before) { throw(:abort) }

	def run
	  run_callbacks(:save) do
	    'hello'
	  end
	end

	def halted_callback_hook(filter)
	  # filter is the proc passed to `set_callback` above
	end
      end
    ```
  </details>

  ### Problem

  When a class has multiple callbacks, (i.e. `save`, `validate` ...),
  it's impossible to tell in the halted_callback_hook which type of
  callback halted the execution.
  This is useful to take different action based on the callback.

  <details>
    <summary> Use Case </summary>

    ```ruby
      class Foo
        include ActiveSupport::Callbacks

	define_callbacks :save
	define_callbacks :validate

	set_callback(:save, :before) { throw(:abort) }
	set_callback(:validate, :before) { throw(:abort) }

	def run
	  run_callbacks(:validate) do
	    ...
	  end

	  run_callbacks(:save) do
	    ...
	  end
	end

	def halted_callback_hook(filter)
	  Rails.logger.warn("Couldn't save the record, the ??? callback halted the execution")
	end
      end
    ```
  </details>

  ### Solution

  Allow `halted_callback_hook` to receive a second argument which is
  the name of the callback being run.
2020-03-03 16:17:55 -04:00
Abhay Nikam
339d1cdc27 Fixes TypeError raised for parameter filter if the json data has key as integer 2020-02-28 17:27:58 +09:00
Ryuta Kamizono
12e48544cf Fix delegate_missing_to to allow keyword arguments 2020-02-28 04:20:01 +09:00
Kasper Timm Hansen
51d73fb84b
Merge pull request #37624
Closes #37624
2020-02-17 01:32:23 +01:00