Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rubygem-haml for openSUSE:Factory checked in at 2021-01-21 21:55:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-haml (Old) and /work/SRC/openSUSE:Factory/.rubygem-haml.new.28504 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-haml" Thu Jan 21 21:55:43 2021 rev:32 rq:865194 version:5.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-haml/rubygem-haml.changes 2020-03-07 21:38:22.280277529 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-haml.new.28504/rubygem-haml.changes 2021-01-21 21:55:44.181809851 +0100 @@ -1,0 +2,23 @@ +Wed Jan 20 12:46:37 UTC 2021 - Stephan Kulow <co...@suse.com> + +updated to version 5.2.1 + see installed CHANGELOG.md + + ## 5.2.1 + + Released on November 30, 2020 + ([diff](https://github.com/haml/haml/compare/v5.2.0...v5.2.1)). + + * Add in improved "multiline" support for attributes [#1043](https://github.com/haml/haml/issues/1043) + + ## 5.2 + + Released on September 28, 2020 + ([diff](https://github.com/haml/haml/compare/v5.1.2...v5.2.0)). + + * Fix crash in the attribute optimizer when `#inspect` is overridden in TrueClass / FalseClass [#972](https://github.com/haml/haml/issues/972) + * Do not HTML-escape templates that are declared to be plaintext [#1014](https://github.com/haml/haml/issues/1014) (Thanks [@cesarizu](https://github.com/cesarizu)) + * Class names are no longer ordered alphabetically, and now follow a new specification as laid out in REFERENCE [#306](https://github.com/haml/haml/issues/306) + + +------------------------------------------------------------------- Old: ---- haml-5.1.2.gem New: ---- haml-5.2.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-haml.spec ++++++ --- /var/tmp/diff_new_pack.9JAjQi/_old 2021-01-21 21:55:44.805810286 +0100 +++ /var/tmp/diff_new_pack.9JAjQi/_new 2021-01-21 21:55:44.809810289 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-haml # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-haml -Version: 5.1.2 +Version: 5.2.1 Release: 0 %define mod_name haml %define mod_full_name %{mod_name}-%{version} ++++++ haml-5.1.2.gem -> haml-5.2.1.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 2019-08-06 14:35:39.000000000 +0200 +++ new/.gitignore 2020-11-30 20:36:33.000000000 +0100 @@ -1,3 +1,4 @@ +/.idea /.yardoc /coverage /doc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.travis.yml new/.travis.yml --- old/.travis.yml 2019-08-06 14:35:39.000000000 +0200 +++ new/.travis.yml 2020-11-30 20:36:33.000000000 +0100 @@ -1,18 +1,17 @@ sudo: false dist: trusty language: ruby -cache: bundler +cache: + bundler: true rvm: - ruby-head - - 2.6.3 - - 2.5.5 - - 2.4.6 - - 2.3.8 - - 2.2.10 - - 2.1.10 - - 2.0.0 - - jruby-9.2.7.0 - - rbx-3 + - 2.7 + - 2.6 + - 2.5 + - jruby-9.2 +env: + - RUBYOPT="--enable-frozen-string-literal" + - RUBYOPT="" gemfile: - test/gemfiles/Gemfile.rails-6.0.x - test/gemfiles/Gemfile.rails-5.2.x @@ -24,74 +23,89 @@ - test/gemfiles/Gemfile.rails-4.0.x matrix: exclude: - - rvm: 2.0.0 - gemfile: test/gemfiles/Gemfile.rails-6.0.x - - rvm: 2.1.10 - gemfile: test/gemfiles/Gemfile.rails-6.0.x - - rvm: 2.2.10 - gemfile: test/gemfiles/Gemfile.rails-6.0.x - - rvm: 2.3.8 - gemfile: test/gemfiles/Gemfile.rails-6.0.x - - rvm: 2.4.6 - gemfile: test/gemfiles/Gemfile.rails-6.0.x - - rvm: 2.0.0 - gemfile: test/gemfiles/Gemfile.rails-5.2.x - - rvm: 2.1.10 - gemfile: test/gemfiles/Gemfile.rails-5.2.x - - rvm: 2.0.0 - gemfile: test/gemfiles/Gemfile.rails-5.1.x - - rvm: 2.1.10 - gemfile: test/gemfiles/Gemfile.rails-5.1.x - - rvm: 2.0.0 - gemfile: test/gemfiles/Gemfile.rails-5.0.x - - rvm: 2.0.0 - gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi - - rvm: 2.1.10 - gemfile: test/gemfiles/Gemfile.rails-5.0.x - - rvm: 2.1.10 - gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi - - rvm: 2.4.6 + - rvm: 2.5 gemfile: test/gemfiles/Gemfile.rails-4.0.x - - rvm: 2.4.6 + - rvm: 2.5 gemfile: test/gemfiles/Gemfile.rails-4.1.x - - rvm: 2.4.6 + - rvm: 2.5 gemfile: test/gemfiles/Gemfile.rails-4.2.x - - rvm: 2.5.5 + - rvm: 2.5 + gemfile: test/gemfiles/Gemfile.rails-5.0.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.5 + gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.5 + gemfile: test/gemfiles/Gemfile.rails-5.1.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.6 gemfile: test/gemfiles/Gemfile.rails-4.0.x - - rvm: 2.5.5 + - rvm: 2.6 gemfile: test/gemfiles/Gemfile.rails-4.1.x - - rvm: 2.5.5 + - rvm: 2.6 gemfile: test/gemfiles/Gemfile.rails-4.2.x - - rvm: 2.6.3 + - rvm: 2.6 + gemfile: test/gemfiles/Gemfile.rails-5.0.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.6 + gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.6 + gemfile: test/gemfiles/Gemfile.rails-5.1.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.7 gemfile: test/gemfiles/Gemfile.rails-4.0.x - - rvm: 2.6.3 + - rvm: 2.7 gemfile: test/gemfiles/Gemfile.rails-4.1.x - - rvm: 2.6.3 + - rvm: 2.7 gemfile: test/gemfiles/Gemfile.rails-4.2.x + - rvm: 2.7 + gemfile: test/gemfiles/Gemfile.rails-5.0.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.7 + gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: 2.7 + gemfile: test/gemfiles/Gemfile.rails-5.1.x + env: RUBYOPT="--enable-frozen-string-literal" - rvm: ruby-head gemfile: test/gemfiles/Gemfile.rails-4.0.x - rvm: ruby-head gemfile: test/gemfiles/Gemfile.rails-4.1.x - rvm: ruby-head gemfile: test/gemfiles/Gemfile.rails-4.2.x + - rvm: jruby-9.2 + gemfile: test/gemfiles/Gemfile.rails-5.0.x + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: jruby-9.2 + gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi + env: RUBYOPT="--enable-frozen-string-literal" + - rvm: jruby-9.2 + gemfile: test/gemfiles/Gemfile.rails-5.1.x + env: RUBYOPT="--enable-frozen-string-literal" include: - - rvm: 2.6.3 + - rvm: 2.7 gemfile: test/gemfiles/Gemfile.rails-edge allow_failures: - rvm: ruby-head - - rvm: rbx-3 - gemfile: test/gemfiles/Gemfile.rails-edge - - rvm: jruby-9.2.7.0 + - rvm: jruby-9.2 gemfile: test/gemfiles/Gemfile.rails-4.2.x - - rvm: jruby-9.2.7.0 + - rvm: jruby-9.2 gemfile: test/gemfiles/Gemfile.rails-4.1.x - - rvm: jruby-9.2.7.0 + - rvm: jruby-9.2 gemfile: test/gemfiles/Gemfile.rails-4.0.x - - rvm: jruby-9.2.7.0 + - rvm: jruby-9.2 gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi fast_finish: true before_install: - - gem i rubygems-update -v '<3' && update_rubygems # https://github.com/travis-ci/travis-ci/issues/8974 - - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true - - gem i bundler -v '<2' + # install older versions of rubygems and bundler only on Ruby < 2.7 + - if [ `echo "${TRAVIS_RUBY_VERSION:0:3} < 2.7" | bc` == 1 ]; then gem i rubygems-update -v '<3' && update_rubygems; fi; # https://github.com/travis-ci/travis-ci/issues/8974 + - if [ `echo "${TRAVIS_RUBY_VERSION:0:3} < 2.7" | bc` == 1 ]; then gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true; fi; + - if [ `echo "${TRAVIS_RUBY_VERSION:0:3} < 2.7" | bc` == 1 ]; then gem i bundler -v '<2'; fi; + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build script: "bundle exec rake submodules test" +after_script: + - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2019-08-06 14:35:39.000000000 +0200 +++ new/CHANGELOG.md 2020-11-30 20:36:33.000000000 +0100 @@ -1,5 +1,21 @@ # Haml Changelog +## 5.2.1 + +Released on November 30, 2020 +([diff](https://github.com/haml/haml/compare/v5.2.0...v5.2.1)). + +* Add in improved "multiline" support for attributes [#1043](https://github.com/haml/haml/issues/1043) + +## 5.2 + +Released on September 28, 2020 +([diff](https://github.com/haml/haml/compare/v5.1.2...v5.2.0)). + +* Fix crash in the attribute optimizer when `#inspect` is overridden in TrueClass / FalseClass [#972](https://github.com/haml/haml/issues/972) +* Do not HTML-escape templates that are declared to be plaintext [#1014](https://github.com/haml/haml/issues/1014) (Thanks [@cesarizu](https://github.com/cesarizu)) +* Class names are no longer ordered alphabetically, and now follow a new specification as laid out in REFERENCE [#306](https://github.com/haml/haml/issues/306) + ## 5.1.2 Released on August 6, 2019 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile new/Gemfile --- old/Gemfile 2019-08-06 14:35:39.000000000 +0200 +++ new/Gemfile 2020-11-30 20:36:33.000000000 +0100 @@ -3,6 +3,7 @@ gem "m" gem "pry" +gem "simplecov" group :docs do gem "yard" @@ -13,7 +14,3 @@ platform :mri do gem "ruby-prof" end - -platform :mri_21 do - gem "simplecov" -end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2019-08-06 14:35:39.000000000 +0200 +++ new/README.md 2020-11-30 20:36:33.000000000 +0100 @@ -1,9 +1,8 @@ # Haml [](http://rubygems.org/gems/haml) -[](http://travis-ci.org/haml/haml) +[](http://travis-ci.org/haml/haml) [](https://codeclimate.com/github/haml/haml) -[](https://coveralls.io/r/haml/haml) [](http://inch-ci.org/github/haml/haml) Haml is a templating engine for HTML. It's designed to make it both easier and @@ -32,7 +31,7 @@ haml --help ~~~ -To use Haml programatically, check out the [YARD documentation](http://haml.info/docs/yardoc/). +To use Haml programmatically, check out the [YARD documentation](http://haml.info/docs/yardoc/). ## Using Haml with Rails diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/REFERENCE.md new/REFERENCE.md --- old/REFERENCE.md 2019-08-06 14:35:39.000000000 +0200 +++ new/REFERENCE.md 2020-11-30 20:36:33.000000000 +0100 @@ -228,15 +228,19 @@ <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'></html> Attribute hashes can also be stretched out over multiple lines to accommodate -many attributes. However, newlines may only be placed immediately after commas. -For example: +many attributes. - %script{:type => "text/javascript", - :src => "javascripts/script_#{2 + 7}"} + %script{ + "type": text/javascript", + "src": javascripts/script_#{2 + 7}", + "data": { + "controller": "reporter", + }, + } is compiled to: - <script src='javascripts/script_9' type='text/javascript'></script> + <script src='javascripts/script_9' type='text/javascript' data-controller='reporter'></script> #### `:class` and `:id` Attributes {#class-and-id-attributes} @@ -517,6 +521,24 @@ </div> </div> +#### Class Name Merging and Ordering + +Class names are ordered in the following way: + +1) Tag identifiers in order (aka, ".alert.me" => "alert me") +2) Classes appearing in HTML-style attributes +3) Classes appearing in Hash-style attributes + +For instance, this is a complicated and unintuitive test case illustrating the ordering + + .foo.moo{:class => ['bar', 'alpha']}(class='baz') + +The resulting HTML would be as follows: + + <div class='foo moo baz bar alpha'></div> + +*Versions of Haml prior to 5.0 would alphabetically sort class names.* + ### Empty (void) Tags: `/` The forward slash character, when placed at the end of a tag definition, causes @@ -853,7 +875,7 @@ ## Ruby Evaluation -### Inserting Ruby: `=` +### Inserting Ruby: `=` {#inserting_ruby} The equals character is followed by Ruby code. This code is evaluated and the output is inserted into the document. For example: @@ -1323,7 +1345,7 @@ So data structures and functions that require lots of arguments can be wrapped over multiple lines, as long as each line but the last ends in a comma -(see [Inserting Ruby](#inserting_ruby_)). +(see [Inserting Ruby](#inserting_ruby)). ## Whitespace Preservation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Rakefile new/Rakefile --- old/Rakefile 2019-08-06 14:35:39.000000000 +0200 +++ new/Rakefile 2020-11-30 20:36:33.000000000 +0100 @@ -14,7 +14,7 @@ end Rake::TestTask.new do |t| t.libs << 'test' - t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] - isolated_test.file_list + t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] + Dir['test/cases/*_test.rb'] - isolated_test.file_list t.warning = true t.verbose = true end @@ -26,13 +26,6 @@ sh "ruby benchmark.rb #{ENV['TIMES']}" end -task :set_coverage_env do - ENV["COVERAGE"] = "true" -end - -desc "Run Simplecov" -task :coverage => [:set_coverage_env, :test] - task :submodules do if File.exist?(File.dirname(__FILE__) + "/.git") sh %{git submodule sync} Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haml.gemspec new/haml.gemspec --- old/haml.gemspec 2019-08-06 14:35:39.000000000 +0200 +++ new/haml.gemspec 2020-11-30 20:36:33.000000000 +0100 @@ -16,7 +16,7 @@ spec.license = "MIT" spec.metadata = { "bug_tracker_uri" => "https://github.com/haml/haml/issues", - "changelog_uri" => "https://github.com/haml/haml/blob/master/CHANGELOG.md", + "changelog_uri" => "https://github.com/haml/haml/blob/main/CHANGELOG.md", "documentation_uri" => "http://haml.info/docs.html", "homepage_uri" => "http://haml.info", "mailing_list_uri" => "https://groups.google.com/forum/?fromgroups#!forum/haml", @@ -32,6 +32,7 @@ spec.add_development_dependency 'rbench' spec.add_development_dependency 'minitest', '>= 4.0' spec.add_development_dependency 'nokogiri' + spec.add_development_dependency 'simplecov' spec.description = <<-END Haml (HTML Abstraction Markup Language) is a layer on top of HTML or XML that's diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/attribute_builder.rb new/lib/haml/attribute_builder.rb --- old/lib/haml/attribute_builder.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/attribute_builder.rb 2020-11-30 20:36:33.000000000 +0100 @@ -36,9 +36,9 @@ value = if escape_attrs == :once - Haml::Helpers.escape_once(value.to_s) + Haml::Helpers.escape_once_without_haml_xss(value.to_s) elsif escape_attrs - Haml::Helpers.html_escape(value.to_s) + Haml::Helpers.html_escape_without_haml_xss(value.to_s) else value.to_s end @@ -126,7 +126,7 @@ elsif key == 'class' merged_class = filter_and_join(from, ' ') if to && merged_class - merged_class = (merged_class.split(' ') | to.split(' ')).sort.join(' ') + merged_class = (to.split(' ') | merged_class.split(' ')).join(' ') elsif to || merged_class merged_class ||= to end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/attribute_compiler.rb new/lib/haml/attribute_compiler.rb --- old/lib/haml/attribute_compiler.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/attribute_compiler.rb 2020-11-30 20:36:33.000000000 +0100 @@ -7,27 +7,7 @@ # @param type [Symbol] :static or :dynamic # @param key [String] # @param value [String] Actual string value for :static type, value's Ruby literal for :dynamic type. - AttributeValue = Struct.new(:type, :key, :value) do - # @return [String] A Ruby literal of value. - def to_literal - case type - when :static - Haml::Util.inspect_obj(value) - when :dynamic - value - end - end - end - - # Returns a script to render attributes on runtime. - # - # @param attributes [Hash] - # @param object_ref [String,:nil] - # @param dynamic_attributes [DynamicAttributes] - # @return [String] Attributes rendering code - def self.runtime_build(attributes, object_ref, dynamic_attributes) - "_hamlout.attributes(#{Haml::Util.inspect_obj(attributes)}, #{object_ref},#{dynamic_attributes.to_literal})" - end + AttributeValue = Struct.new(:type, :key, :value) # @param options [Haml::Options] def initialize(options) @@ -41,16 +21,16 @@ # # @param attributes [Hash] # @param object_ref [String,:nil] - # @param dynamic_attributes [DynamicAttributes] + # @param dynamic_attributes [Haml::Parser::DynamicAttributes] # @return [Array] Temple expression def compile(attributes, object_ref, dynamic_attributes) if object_ref != :nil || !AttributeParser.available? - return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)] + return [:dynamic, compile_runtime_build(attributes, object_ref, dynamic_attributes)] end parsed_hashes = [dynamic_attributes.new, dynamic_attributes.old].compact.map do |attribute_hash| unless (hash = AttributeParser.parse(attribute_hash)) - return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)] + return [:dynamic, compile_runtime_build(attributes, object_ref, dynamic_attributes)] end hash end @@ -64,6 +44,16 @@ private + # Returns a script to render attributes on runtime. + # + # @param attributes [Hash] + # @param object_ref [String,:nil] + # @param dynamic_attributes [Haml::Parser::DynamicAttributes] + # @return [String] Attributes rendering code + def compile_runtime_build(attributes, object_ref, dynamic_attributes) + "_hamlout.attributes(#{to_literal(attributes)}, #{object_ref}, #{dynamic_attributes.to_literal})" + end + # Build array of grouped values whose sort order may go back and forth, which is also sorted with key name. # This method needs to group values with the same start because it can be changed in `Haml::AttributeBuidler#build_data_keys`. # @param values [Array<Haml::AttributeCompiler::AttributeValue>] @@ -130,7 +120,7 @@ arguments = [@is_html, @attr_wrapper, @escape_attrs, @hyphenate_data_attrs] code = "::Haml::AttributeBuilder.build_attributes"\ - "(#{arguments.map { |a| Haml::Util.inspect_obj(a) }.join(', ')}, { #{hash_content} })" + "(#{arguments.map(&method(:to_literal)).join(', ')}, { #{hash_content} })" [:static, eval(code).to_s] end @@ -139,16 +129,16 @@ # @return [String] def merged_value(key, values) if values.size == 1 - values.first.to_literal + attr_literal(values.first) else - "::Haml::AttributeBuilder.merge_values(#{frozen_string(key)}, #{values.map(&:to_literal).join(', ')})" + "::Haml::AttributeBuilder.merge_values(#{frozen_string(key)}, #{values.map(&method(:attr_literal)).join(', ')})" end end # @param str [String] # @return [String] def frozen_string(str) - "#{Haml::Util.inspect_obj(str)}.freeze" + "#{to_literal(str)}.freeze" end # Compiles attribute values for one key to Temple expression that generates ` key='value'`. @@ -157,7 +147,7 @@ # @param values [Array<AttributeValue>] # @return [Array] Temple expression def compile_attribute(key, values) - if values.all? { |v| Temple::StaticAnalyzer.static?(v.to_literal) } + if values.all? { |v| Temple::StaticAnalyzer.static?(attr_literal(v)) } return static_build(values) end @@ -181,7 +171,7 @@ ['false, nil', [:multi]], [:else, [:multi, [:static, " #{id_or_class}=#{@attr_wrapper}"], - [:escape, @escape_attrs, [:dynamic, var]], + [:escape, Escapable::EscapeSafeBuffer.new(@escape_attrs), [:dynamic, var]], [:static, @attr_wrapper]], ] ], @@ -201,7 +191,7 @@ ['false, nil', [:multi]], [:else, [:multi, [:static, " #{key}=#{@attr_wrapper}"], - [:escape, @escape_attrs, [:dynamic, var]], + [:escape, Escapable::EscapeSafeBuffer.new(@escape_attrs), [:dynamic, var]], [:static, @attr_wrapper]], ] ], @@ -220,5 +210,26 @@ @unique_name ||= 0 "_haml_attribute_compiler#{@unique_name += 1}" end + + # @param [Haml::AttributeCompiler::AttributeValue] attr + def attr_literal(attr) + case attr.type + when :static + to_literal(attr.value) + when :dynamic + attr.value + end + end + + # For haml/haml#972 + # @param [Object] value + def to_literal(value) + case value + when true, false + value.to_s + else + Haml::Util.inspect_obj(value) + end + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/escapable.rb new/lib/haml/escapable.rb --- old/lib/haml/escapable.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/escapable.rb 2020-11-30 20:36:33.000000000 +0100 @@ -4,30 +4,31 @@ # Like Temple::Filters::Escapable, but with support for escaping by # Haml::Herlpers.html_escape and Haml::Herlpers.escape_once. class Escapable < Temple::Filter + # Special value of `flag` to ignore html_safe? + EscapeSafeBuffer = Struct.new(:value) + def initialize(*) super - @escape_code = "::Haml::Helpers.html_escape((%s))" - @escaper = eval("proc {|v| #{@escape_code % 'v'} }") - @once_escape_code = "::Haml::Helpers.escape_once((%s))" - @once_escaper = eval("proc {|v| #{@once_escape_code % 'v'} }") @escape = false + @escape_safe_buffer = false end def on_escape(flag, exp) - old = @escape - @escape = flag + old_escape, old_escape_safe_buffer = @escape, @escape_safe_buffer + @escape_safe_buffer = flag.is_a?(EscapeSafeBuffer) + @escape = @escape_safe_buffer ? flag.value : flag compile(exp) ensure - @escape = old + @escape, @escape_safe_buffer = old_escape, old_escape_safe_buffer end # The same as Haml::AttributeBuilder.build_attributes def on_static(value) [:static, if @escape == :once - @once_escaper[value] + escape_once(value) elsif @escape - @escaper[value] + escape(value) else value end @@ -38,13 +39,39 @@ def on_dynamic(value) [:dynamic, if @escape == :once - @once_escape_code % value + escape_once_code(value) elsif @escape - @escape_code % value + escape_code(value) else "(#{value}).to_s" end ] end + + private + + def escape_once(value) + if @escape_safe_buffer + ::Haml::Helpers.escape_once_without_haml_xss(value) + else + ::Haml::Helpers.escape_once(value) + end + end + + def escape(value) + if @escape_safe_buffer + ::Haml::Helpers.html_escape_without_haml_xss(value) + else + ::Haml::Helpers.html_escape(value) + end + end + + def escape_once_code(value) + "::Haml::Helpers.escape_once#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))" + end + + def escape_code(value) + "::Haml::Helpers.html_escape#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))" + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/helpers/xss_mods.rb new/lib/haml/helpers/xss_mods.rb --- old/lib/haml/helpers/xss_mods.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/helpers/xss_mods.rb 2020-11-30 20:36:33.000000000 +0100 @@ -8,12 +8,15 @@ # to work with Rails' XSS protection methods. module XssMods def self.included(base) - %w[html_escape find_and_preserve preserve list_of surround - precede succeed capture_haml haml_concat haml_internal_concat haml_indent - escape_once].each do |name| + %w[find_and_preserve preserve list_of surround + precede succeed capture_haml haml_concat haml_internal_concat haml_indent].each do |name| base.send(:alias_method, "#{name}_without_haml_xss", name) base.send(:alias_method, name, "#{name}_with_haml_xss") end + # Those two always have _without_haml_xss + %w[html_escape escape_once].each do |name| + base.send(:alias_method, name, "#{name}_with_haml_xss") + end end # Don't escape text that's already safe, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/helpers.rb new/lib/haml/helpers.rb --- old/lib/haml/helpers.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/helpers.rb 2020-11-30 20:36:33.000000000 +0100 @@ -607,9 +607,12 @@ # @param text [String] The string to sanitize # @return [String] The sanitized string def html_escape(text) - ERB::Util.html_escape(text) + CGI.escapeHTML(text.to_s) end + # Always escape text regardless of html_safe? + alias_method :html_escape_without_haml_xss, :html_escape + HTML_ESCAPE_ONCE_REGEX = /['"><]|&(?!(?:[a-zA-Z]+|#(?:\d+|[xX][0-9a-fA-F]+));)/ # Escapes HTML entities in `text`, but without escaping an ampersand @@ -622,6 +625,9 @@ text.gsub(HTML_ESCAPE_ONCE_REGEX, HTML_ESCAPE) end + # Always escape text once regardless of html_safe? + alias_method :escape_once_without_haml_xss, :escape_once + # Returns whether or not the current template is a Haml template. # # This function, unlike other {Haml::Helpers} functions, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/parser.rb new/lib/haml/parser.rb --- old/lib/haml/parser.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/parser.rb 2020-11-30 20:36:33.000000000 +0100 @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'ripper' require 'strscan' module Haml @@ -90,6 +91,9 @@ ID_KEY = 'id'.freeze CLASS_KEY = 'class'.freeze + # Used for scanning old attributes, substituting the first '{' + METHOD_CALL_PREFIX = 'a(' + def initialize(options) @options = Options.wrap(options) # Record the indent levels of "if" statements to validate the subsequent @@ -307,7 +311,7 @@ return ParseNode.new(:plain, line.index + 1, :text => line.text) end - escape_html = @options.escape_html if escape_html.nil? + escape_html = @options.escape_html && @options.mime_type != 'text/plain' if escape_html.nil? line.text = unescape_interpolation(line.text, escape_html) script(line, false) end @@ -651,13 +655,18 @@ # @return [String] rest # @return [Integer] last_line def parse_old_attributes(text) - text = text.dup last_line = @line.index + 1 begin - attributes_hash, rest = balance(text, ?{, ?}) + # Old attributes often look like a valid Hash literal, but it sometimes allow code like + # `{ hash, foo: bar }`, which is compiled to `_hamlout.attributes({}, nil, hash, foo: bar)`. + # + # To scan such code correctly, this scans `a( hash, foo: bar }` instead, stops when there is + # 1 more :on_embexpr_end (the last '}') than :on_embexpr_beg, and resurrects '{' afterwards. + balanced, rest = balance_tokens(text.sub(?{, METHOD_CALL_PREFIX), :on_embexpr_beg, :on_embexpr_end, count: 1) + attributes_hash = balanced.sub(METHOD_CALL_PREFIX, ?{) rescue SyntaxError => e - if text.strip[-1] == ?, && e.message == Error.message(:unbalanced_brackets) + if e.message == Error.message(:unbalanced_brackets) && !@template.empty? text << "\n#{@next_line.text}" last_line += 1 next_line @@ -811,6 +820,25 @@ Haml::Util.balance(*args) or raise(SyntaxError.new(Error.message(:unbalanced_brackets))) end + # Unlike #balance, this balances Ripper tokens to balance something like `{ a: "}" }` correctly. + def balance_tokens(buf, start, finish, count: 0) + text = ''.dup + Ripper.lex(buf).each do |_, token, str| + text << str + case token + when start + count += 1 + when finish + count -= 1 + end + + if count == 0 + return text, buf.sub(text, '') + end + end + raise SyntaxError.new(Error.message(:unbalanced_brackets)) + end + def block_opened? @next_line.tabs > @line.tabs end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/util.rb new/lib/haml/util.rb --- old/lib/haml/util.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/util.rb 2020-11-30 20:36:33.000000000 +0100 @@ -213,7 +213,7 @@ scan.scan(/\w+/) end content = eval("\"#{interpolated}\"") - content.prepend(char) if char == '@' || char == '$' + content = "#{char}#{content}" if char == '@' || char == '$' content = "Haml::Helpers.html_escape((#{content}))" if escape_html res << "\#{#{content}}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/haml/version.rb new/lib/haml/version.rb --- old/lib/haml/version.rb 2019-08-06 14:35:39.000000000 +0200 +++ new/lib/haml/version.rb 2020-11-30 20:36:33.000000000 +0100 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Haml - VERSION = "5.1.2" + VERSION = "5.2.1" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2019-08-06 14:35:39.000000000 +0200 +++ new/metadata 2020-11-30 20:36:33.000000000 +0100 @@ -1,17 +1,17 @@ --- !ruby/object:Gem::Specification name: haml version: !ruby/object:Gem::Version - version: 5.1.2 + version: 5.2.1 platform: ruby authors: - Natalie Weizenbaum - Hampton Catlin - Norman Clarke - Akira Matsuda -autorequire: +autorequire: bindir: bin cert_chain: [] -date: 2019-08-06 00:00:00.000000000 Z +date: 2020-11-30 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: temple @@ -97,6 +97,20 @@ - - ">=" - !ruby/object:Gem::Version version: '0' +- !ruby/object:Gem::Dependency + name: simplecov + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' description: | Haml (HTML Abstraction Markup Language) is a layer on top of HTML or XML that's designed to express the structure of documents in a non-repetitive, elegant, and @@ -165,12 +179,12 @@ - MIT metadata: bug_tracker_uri: https://github.com/haml/haml/issues - changelog_uri: https://github.com/haml/haml/blob/master/CHANGELOG.md + changelog_uri: https://github.com/haml/haml/blob/main/CHANGELOG.md documentation_uri: http://haml.info/docs.html homepage_uri: http://haml.info mailing_list_uri: https://groups.google.com/forum/?fromgroups#!forum/haml source_code_uri: https://github.com/haml/haml -post_install_message: +post_install_message: rdoc_options: [] require_paths: - lib @@ -185,8 +199,8 @@ - !ruby/object:Gem::Version version: '0' requirements: [] -rubygems_version: 3.0.3 -signing_key: +rubygems_version: 3.1.4 +signing_key: specification_version: 4 summary: An elegant, structured (X)HTML/XML templating engine. test_files: []