Skip to content

SystemStackError when dumping objects containing ActiveSupport::Duration using rabl templates since json-1.19.0 #957

@adamruzicka

Description

@adamruzicka

We have a rails model containing an ActiveSupport::Duration attribute. In API, we render the responses using RABL templates. Since json-2.19.0, our tests are failing due to a SystemStackError being raised during the rendering of the template.

Stack trace

/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1112:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/core_ext/object/json.rb:39:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `_generate_no_fallback'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/core_ext/object/json.rb:39:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `_generate_no_fallback'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/core_ext/object/json.rb:39:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `_generate_no_fallback'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/core_ext/object/json.rb:39:in `to_json'
-----B<-----SNIP-----B<-----
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `_generate_no_fallback'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:1121:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/core_ext/object/json.rb:39:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:958:in `generate'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/json-2.19.0/lib/json/common.rb:958:in `dump'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/rabl-0.17.0/lib/rabl/engine.rb:341:in `format_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/rabl-0.17.0/lib/rabl/engine.rb:114:in `to_json'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/rabl-0.17.0/lib/rabl/engine.rb:51:in `block in render'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/rabl-0.17.0/lib/rabl/engine.rb:392:in `cache_results'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/rabl-0.17.0/lib/rabl/engine.rb:50:in `render'
/Users/aruzicka/vcs/foreman/foreman/config/initializers/rabl_init.rb:48:in `render'
/Users/aruzicka/vcs/foreman/foreman-tasks/app/views/foreman_tasks/api/tasks/show.json.rabl:3:in `___sers_aruzicka_vcs_foreman_foreman_tasks_app_views_foreman_tasks_api_tasks_show_json_rabl___1148070436913130591_515500'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/base.rb:244:in `public_send'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/base.rb:244:in `_run'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/template.rb:157:in `block in render'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications.rb:206:in `block in instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications.rb:206:in `instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/template.rb:361:in `instrument_render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/template.rb:155:in `render'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/template_renderer.rb:65:in `block (2 levels) in render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications.rb:206:in `block in instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/activesupport-7.0.10/lib/active_support/notifications.rb:206:in `instrument'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/template_renderer.rb:60:in `block in render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/template_renderer.rb:79:in `render_with_layout'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/template_renderer.rb:59:in `render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/template_renderer.rb:11:in `render'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/renderer.rb:61:in `render_template_to_object'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/renderer/renderer.rb:29:in `render_to_object'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/rendering.rb:117:in `block in _render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/base.rb:270:in `in_rendering_context'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/rendering.rb:116:in `_render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionpack-7.0.10/lib/action_controller/metal/streaming.rb:216:in `_render_template'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionview-7.0.10/lib/action_view/rendering.rb:103:in `render_to_body'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionpack-7.0.10/lib/action_controller/metal/rendering.rb:158:in `render_to_body'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionpack-7.0.10/lib/action_controller/metal/renderers.rb:141:in `render_to_body'
/Users/aruzicka/.local/share/rv/gems/ruby/3.3.0/gems/actionpack-7.0.10/lib/abstract_controller/rendering.rb:27:in `render'
-----B<-----SNIP-----B<-----

I haven't managed to put together an isolated reproducer yet.

Dependencies:
json 2.19.0 (and also .1 and .2)
rails and friends 7.0.10
rabl 0.17.0

As a workaround, we can cast the duration to a more basic type in the template, but it would be nice if we didn't have to do this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions