New Upstream Snapshot - ruby-liquid-c

Ready changes

Summary

Merged new upstream version: 4.1.0+git20221020.1.8780e2d (was: 4.1.0).

Resulting package

Built on 2023-01-25T01:11 (took 4m57s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots ruby-liquid-c-dbgsymapt install -t fresh-snapshots ruby-liquid-c

Lintian Result

Diff

diff --git a/.github/workflows/liquid.yml b/.github/workflows/liquid.yml
deleted file mode 100644
index ccc3c0d..0000000
--- a/.github/workflows/liquid.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-name: Liquid
-on: [push, pull_request]
-jobs:
-  test:
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        entry:
-          - { ruby: '2.5', allowed-failure: false }
-          - { ruby: '2.7', allowed-failure: false }
-          - { ruby: '3.0', allowed-failure: false }
-          - { ruby: ruby-head, allowed-failure: true }
-    name: test (${{ matrix.entry.ruby }})
-    steps:
-      - uses: actions/checkout@v2
-      - uses: ruby/setup-ruby@v1
-        with:
-          ruby-version: ${{ matrix.entry.ruby }}
-      - uses: actions/cache@v1
-        with:
-          path: vendor/bundle
-          key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile') }}
-          restore-keys: ${{ runner.os }}-gems-
-      - run: bundle install --jobs=3 --retry=3 --path=vendor/bundle
-      - run: bundle exec rake
-        continue-on-error: ${{ matrix.entry.allowed-failure }}
-        env:
-          LIQUID_C_PEDANTIC: 'true'
-      - run: bundle exec rubocop
-
-  valgrind:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - uses: ruby/setup-ruby@v1
-        with:
-          ruby-version: '3.0'
-      - run: sudo apt-get install -y valgrind
-      - uses: actions/cache@v1
-        with:
-          path: vendor/bundle
-          key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile') }}
-          restore-keys: ${{ runner.os }}-gems-
-      - run: bundle install --jobs=3 --retry=3 --path=vendor/bundle
-      - run: bundle exec rake test:valgrind
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 2934b7f..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.gem
-*.rbc
-Gemfile.lock
-pkg
-tmp
-*.o
-*.bundle
-ext/*/Makefile
-*.so
-instruments*.trace
-*.cpu
-*.object
-*.dSYM
diff --git a/debian/changelog b/debian/changelog
index 18fca96..1ee711d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,12 +1,18 @@
-ruby-liquid-c (4.1.0-3~1.gbp70410e) UNRELEASED; urgency=medium
+ruby-liquid-c (4.1.0+git20221020.1.8780e2d-1) UNRELEASED; urgency=medium
 
+  [ Daniel Leidert ]
   ** SNAPSHOT build @70410e1e5603c13913381d259796aa292a6c45f9 **
 
   * Team upload.
   * d/watch: Fix watch file by using the github tags page.
   * UNRELEASED
 
- -- Daniel Leidert <dleidert@debian.org>  Wed, 25 Jan 2023 01:59:18 +0100
+  [ Debian Janitor ]
+  * New upstream snapshot.
+  * Drop patch 0002-test_helper-skip-GC-compaction-on-unsupported-platfo.patch,
+    present upstream.
+
+ -- Daniel Leidert <dleidert@debian.org>  Wed, 25 Jan 2023 01:07:34 -0000
 
 ruby-liquid-c (4.1.0-2) unstable; urgency=medium
 
diff --git a/debian/patches/0001-Drop-git-from-gemspec.patch b/debian/patches/0001-Drop-git-from-gemspec.patch
index 1304d3b..231959a 100644
--- a/debian/patches/0001-Drop-git-from-gemspec.patch
+++ b/debian/patches/0001-Drop-git-from-gemspec.patch
@@ -7,10 +7,10 @@ Forwarded: not-needed
  liquid-c.gemspec | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-diff --git a/liquid-c.gemspec b/liquid-c.gemspec
-index b47867a..808e4fb 100755
---- a/liquid-c.gemspec
-+++ b/liquid-c.gemspec
+Index: ruby-liquid-c.git/liquid-c.gemspec
+===================================================================
+--- ruby-liquid-c.git.orig/liquid-c.gemspec
++++ ruby-liquid-c.git/liquid-c.gemspec
 @@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
    spec.license       = "MIT"
  
diff --git a/debian/patches/0002-test_helper-skip-GC-compaction-on-unsupported-platfo.patch b/debian/patches/0002-test_helper-skip-GC-compaction-on-unsupported-platfo.patch
deleted file mode 100644
index ab7d646..0000000
--- a/debian/patches/0002-test_helper-skip-GC-compaction-on-unsupported-platfo.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Antonio Terceiro <terceiro@debian.org>
-Date: Thu, 22 Sep 2022 18:38:39 -0300
-Subject: test_helper: skip GC compaction on unsupported platforms
-
-Not all platforms support GC compaction (e.g. 64-bit little endian
-PowerPC, ppc64el on Debian/Ubuntu). Handling NotImplementedError when
-enabling it allows us to run the test suite on those platforms.
-
-Forwarded: https://github.com/Shopify/liquid-c/pull/180
----
- test/test_helper.rb | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/test/test_helper.rb b/test/test_helper.rb
-index 0862ca0..115ea4b 100644
---- a/test/test_helper.rb
-+++ b/test/test_helper.rb
-@@ -8,7 +8,11 @@ require "liquid/c"
- if GC.respond_to?(:verify_compaction_references)
-   # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
-   # move objects around, helping to find object movement bugs.
--  GC.verify_compaction_references(double_heap: true, toward: :empty)
-+  begin
-+    GC.verify_compaction_references(double_heap: true, toward: :empty)
-+  rescue NotImplementedError
-+    puts "W: GC compaction not suppported by platform"
-+  end
- end
- 
- GC.stress = true if ENV["GC_STRESS"]
diff --git a/debian/patches/series b/debian/patches/series
index dfb8c97..d6130ea 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1 @@
 0001-Drop-git-from-gemspec.patch
-0002-test_helper-skip-GC-compaction-on-unsupported-platfo.patch
diff --git a/ext/liquid_c/block.c b/ext/liquid_c/block.c
index 5bd9007..3e4efc8 100644
--- a/ext/liquid_c/block.c
+++ b/ext/liquid_c/block.c
@@ -49,7 +49,7 @@ static void block_body_mark(void *ptr)
     } else {
         rb_gc_mark(body->as.intermediate.parse_context);
         if (body->as.intermediate.vm_assembler_pool)
-            vm_assembler_pool_gc_mark(body->as.intermediate.vm_assembler_pool);
+            rb_gc_mark(body->as.intermediate.vm_assembler_pool->self);
         if (body->as.intermediate.code)
             vm_assembler_gc_mark(body->as.intermediate.code);
     }
@@ -199,9 +199,14 @@ static tag_markup_t internal_block_body_parse(block_body_t *body, parse_context_
                 long name_len = name_end - name_start;
 
                 if (name_len == 0) {
-                    VALUE str = rb_enc_str_new(token.str_trimmed, token.len_trimmed, utf8_encoding);
-                    unknown_tag = (tag_markup_t) { str, str };
-                    goto loop_break;
+                    if (name_start < end && *name_start == '#') { // inline comment
+                        name_end++;
+                        name_len++;
+                    } else {
+                        VALUE str = rb_enc_str_new(token.str_trimmed, token.len_trimmed, utf8_encoding);
+                        unknown_tag = (tag_markup_t) { str, str };
+                        goto loop_break;
+                    }
                 }
 
                 if (name_len == 6 && strncmp(name_start, "liquid", 6) == 0) {
diff --git a/ext/liquid_c/document_body.c b/ext/liquid_c/document_body.c
index e1ef673..0faf4b4 100644
--- a/ext/liquid_c/document_body.c
+++ b/ext/liquid_c/document_body.c
@@ -9,6 +9,14 @@ static VALUE cLiquidCDocumentBody;
 static void document_body_mark(void *ptr)
 {
     document_body_t *body = ptr;
+    /* When Liquid::C::BlockBody#freeze is called, it calls
+     * document_body_write_block_body which sets the document_body_entry but
+     * does not yet set the compiled flag to true. During this time, the only
+     * reference to this Liquid::C::DocumentBody object is in the instance
+     * variables of the parse_context which is marked movable by Ruby. This
+     * causes the self reference here to be moved by compaction causing it to
+     * point to an incorrect object. */
+    rb_gc_mark(body->self);
     rb_gc_mark(body->constants);
 }
 
diff --git a/ext/liquid_c/parser.c b/ext/liquid_c/parser.c
index 80af5b6..821f18c 100644
--- a/ext/liquid_c/parser.c
+++ b/ext/liquid_c/parser.c
@@ -67,28 +67,40 @@ static VALUE parse_number(parser_t *p)
     return out;
 }
 
+static void raise_invalid_expression_type(const char *expr, int expr_len)
+{
+    rb_enc_raise(utf8_encoding, cLiquidSyntaxError, "Invalid expression type '%.*s' in range expression", expr_len, expr);
+}
+
 static VALUE try_parse_constant_range(parser_t *p)
 {
     parser_t saved_state = *p;
 
     parser_must_consume(p, TOKEN_OPEN_ROUND);
 
+    const char *begin_str = p->cur.val;
     VALUE begin = try_parse_constant_expression(p);
+    const char *begin_str_end = p->cur.val;
     if (begin == Qundef) {
         *p = saved_state;
         return Qundef;
     }
     parser_must_consume(p, TOKEN_DOTDOT);
 
+    const char *end_str = p->cur.val;
     VALUE end = try_parse_constant_expression(p);
+    const char *end_str_end = p->cur.val;
     if (end == Qundef) {
         *p = saved_state;
         return Qundef;
     }
     parser_must_consume(p, TOKEN_CLOSE_ROUND);
 
-    begin = rb_funcall(begin, id_to_i, 0);
-    end = rb_funcall(end, id_to_i, 0);
+    begin = rb_check_funcall(begin, id_to_i, 0, NULL);
+    if (begin == Qundef) raise_invalid_expression_type(begin_str, begin_str_end - begin_str);
+
+    end = rb_check_funcall(end, id_to_i, 0, NULL);
+    if (end == Qundef) raise_invalid_expression_type(end_str, end_str_end - end_str);
 
     bool exclude_end = false;
     return rb_range_new(begin, end, exclude_end);
diff --git a/ext/liquid_c/vm_assembler_pool.c b/ext/liquid_c/vm_assembler_pool.c
index 2adf00c..fcd4dac 100644
--- a/ext/liquid_c/vm_assembler_pool.c
+++ b/ext/liquid_c/vm_assembler_pool.c
@@ -3,8 +3,10 @@
 
 static VALUE cLiquidCVMAssemblerPool;
 
-void vm_assembler_pool_gc_mark(vm_assembler_pool_t *pool)
+static void vm_assembler_pool_mark(void *ptr)
 {
+    vm_assembler_pool_t *pool = ptr;
+
     rb_gc_mark(pool->self);
 }
 
@@ -39,7 +41,7 @@ static size_t vm_assembler_pool_memsize(const void *ptr)
 
 const rb_data_type_t vm_assembler_pool_data_type = {
     "liquid_vm_assembler_pool",
-    { NULL, vm_assembler_pool_free, vm_assembler_pool_memsize, },
+    { vm_assembler_pool_mark, vm_assembler_pool_free, vm_assembler_pool_memsize, },
     NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
diff --git a/ext/liquid_c/vm_assembler_pool.h b/ext/liquid_c/vm_assembler_pool.h
index a1ed9a8..8b2aa28 100644
--- a/ext/liquid_c/vm_assembler_pool.h
+++ b/ext/liquid_c/vm_assembler_pool.h
@@ -18,7 +18,6 @@ extern const rb_data_type_t vm_assembler_pool_data_type;
 #define VMAssemblerPool_Get_Struct(obj, sval) TypedData_Get_Struct(obj, vm_assembler_pool_t, &vm_assembler_pool_data_type, sval)
 
 void liquid_define_vm_assembler_pool(void);
-void vm_assembler_pool_gc_mark(vm_assembler_pool_t *pool);
 VALUE vm_assembler_pool_new(void);
 vm_assembler_t *vm_assembler_pool_alloc_assembler(vm_assembler_pool_t *pool);
 void vm_assembler_pool_free_assembler(vm_assembler_t *assembler);
diff --git a/lib/liquid/c.rb b/lib/liquid/c.rb
index 2649c36..259c7d8 100644
--- a/lib/liquid/c.rb
+++ b/lib/liquid/c.rb
@@ -86,7 +86,7 @@ Liquid::ParseContext.class_eval do
 
   def parse_expression(markup)
     if liquid_c_nodes_disabled?
-      Liquid::Expression.ruby_parse(markup)
+      Liquid::Expression.parse(markup)
     else
       Liquid::C::Expression.lax_parse(markup)
     end
@@ -207,22 +207,17 @@ Liquid::C::Expression.class_eval do
     def lax_parse(markup)
       strict_parse(markup)
     rescue Liquid::SyntaxError
-      Liquid::Expression.ruby_parse(markup)
+      Liquid::Expression.parse(markup)
     end
-  end
-end
-
-Liquid::Expression.class_eval do
-  class << self
-    alias_method :ruby_parse, :parse
 
-    def c_parse(markup)
-      Liquid::C::Expression.lax_parse(markup)
-    end
+    # Default to strict parsing, since Liquid::C::Expression.parse should only really
+    # be used with constant expressions.  Otherwise, prefer parse_context.parse_expression.
+    alias_method :parse, :strict_parse
   end
 end
 
 Liquid::Context.class_eval do
+  alias_method :ruby_parse_evaluate, :[]
   alias_method :ruby_evaluate, :evaluate
   alias_method :ruby_find_variable, :find_variable
   alias_method :ruby_strict_variables=, :strict_variables=
@@ -232,6 +227,10 @@ Liquid::Context.class_eval do
   def c_find_variable_kwarg(key, raise_on_not_found: true)
     c_find_variable(key, raise_on_not_found)
   end
+
+  def c_parse_evaluate(expression)
+    c_evaluate(Liquid::C::Expression.lax_parse(expression))
+  end
 end
 
 Liquid::ResourceLimits.class_eval do
@@ -256,15 +255,15 @@ module Liquid
       def enabled=(value)
         @enabled = value
         if value
+          Liquid::Context.send(:alias_method, :[], :c_parse_evaluate)
           Liquid::Context.send(:alias_method, :evaluate, :c_evaluate)
           Liquid::Context.send(:alias_method, :find_variable, :c_find_variable_kwarg)
           Liquid::Context.send(:alias_method, :strict_variables=, :c_strict_variables=)
-          Liquid::Expression.singleton_class.send(:alias_method, :parse, :c_parse)
         else
+          Liquid::Context.send(:alias_method, :[], :ruby_parse_evaluate)
           Liquid::Context.send(:alias_method, :evaluate, :ruby_evaluate)
           Liquid::Context.send(:alias_method, :find_variable, :ruby_find_variable)
           Liquid::Context.send(:alias_method, :strict_variables=, :ruby_strict_variables=)
-          Liquid::Expression.singleton_class.send(:alias_method, :parse, :ruby_parse)
         end
       end
     end
diff --git a/lib/liquid/c/version.rb b/lib/liquid/c/version.rb
index 41c8909..87f1743 100644
--- a/lib/liquid/c/version.rb
+++ b/lib/liquid/c/version.rb
@@ -2,6 +2,6 @@
 
 module Liquid
   module C
-    VERSION = "4.0.0"
+    VERSION = "4.1.0"
   end
 end
diff --git a/liquid-c.gemspec b/liquid-c.gemspec
index b47867a..ba5e353 100755
--- a/liquid-c.gemspec
+++ b/liquid-c.gemspec
@@ -24,6 +24,8 @@ Gem::Specification.new do |spec|
 
   spec.required_ruby_version = ">= 2.5.0"
 
+  spec.metadata["allowed_push_host"] = "https://rubygems.org"
+
   spec.add_dependency("liquid", ">= 5.0.1")
 
   spec.add_development_dependency("bundler", ">= 1.5") # has bugfix for segfaulting deploys
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 0862ca0..8f7c9bb 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,14 +1,21 @@
 # frozen_string_literal: true
 
-at_exit { GC.start }
-
 require "minitest/autorun"
 require "liquid/c"
 
 if GC.respond_to?(:verify_compaction_references)
   # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
   # move objects around, helping to find object movement bugs.
-  GC.verify_compaction_references(double_heap: true, toward: :empty)
+  begin
+    GC.verify_compaction_references(double_heap: true, toward: :empty)
+  rescue NotImplementedError
+    puts "W: GC compaction not suppported by platform"
+  end
+end
+
+# Enable auto-compaction in the GC if supported.
+if GC.respond_to?(:auto_compact=)
+  GC.auto_compact = true
 end
 
 GC.stress = true if ENV["GC_STRESS"]
diff --git a/test/unit/expression_test.rb b/test/unit/expression_test.rb
index 08e1bae..dbcf443 100644
--- a/test/unit/expression_test.rb
+++ b/test/unit/expression_test.rb
@@ -159,7 +159,7 @@ class ExpressionTest < MiniTest::Test
   end
 
   def test_disable_c_nodes
-    context = Liquid::Context.new({ "x" => 123 })
+    context = Liquid::Context.new({ "x" => 123, "y" => { 123 => 42 } })
 
     expr = Liquid::ParseContext.new.parse_expression("x")
     assert_instance_of(Liquid::C::Expression, expr)
@@ -168,6 +168,11 @@ class ExpressionTest < MiniTest::Test
     expr = Liquid::ParseContext.new(disable_liquid_c_nodes: true).parse_expression("x")
     assert_instance_of(Liquid::VariableLookup, expr)
     assert_equal(123, context.evaluate(expr))
+
+    expr = Liquid::ParseContext.new(disable_liquid_c_nodes: true).parse_expression("y[x]")
+    assert_instance_of(Liquid::VariableLookup, expr)
+    assert_instance_of(Liquid::VariableLookup, expr.lookups.first)
+    assert_equal(42, context.evaluate(expr))
   end
 
   private

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/debug/.build-id/d7/7b686d6c913f9c7dff6c079cbfe12fa4736926.debug
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/extensions/x86_64-linux/3.1.0/liquid-c-4.1.0/gem.build_complete
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/extensions/x86_64-linux/3.1.0/liquid-c-4.1.0/liquid_c.so
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/lib/liquid/c.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/lib/liquid/c/compile_ext.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/lib/liquid/c/version.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/performance/c_profile.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/rakelib/compile.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/rakelib/integration_test.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/rakelib/performance.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/rakelib/rubocop.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.1.0/rakelib/unit_test.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/specifications/liquid-c-4.1.0.gemspec

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/debug/.build-id/e5/e5ca9c39e75478c3f36558ae9ece032d6c23c7.debug
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/extensions/x86_64-linux/3.1.0/liquid-c-4.0.0/gem.build_complete
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/extensions/x86_64-linux/3.1.0/liquid-c-4.0.0/liquid_c.so
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/lib/liquid/c.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/lib/liquid/c/compile_ext.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/lib/liquid/c/version.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/performance/c_profile.rb
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/rakelib/compile.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/rakelib/integration_test.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/rakelib/performance.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/rakelib/rubocop.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/gems/liquid-c-4.0.0/rakelib/unit_test.rake
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0/specifications/liquid-c-4.0.0.gemspec

No differences were encountered between the control files of package ruby-liquid-c

Control files of package ruby-liquid-c-dbgsym: lines which differ (wdiff format)

  • Build-Ids: e5e5ca9c39e75478c3f36558ae9ece032d6c23c7 d77b686d6c913f9c7dff6c079cbfe12fa4736926

More details

Full run details