From 938b5fc93bdaa15b6c60de043c65e7764efaafa5 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 28 Mar 2024 13:38:57 +0100 Subject: [PATCH] Add compatibility with --enable-frozen-string-literal Fix: https://github.com/boazsegev/combine_pdf/pull/168 Ref: https://bugs.ruby-lang.org/issues/20205 Ruby 3.4 will emit deprecation warnings when mutating string literals, and a future version is likely to make frozen string literals the default. --- .github/workflows/main.yml | 8 ++++++-- lib/combine_pdf.rb | 1 + lib/combine_pdf/api.rb | 1 + lib/combine_pdf/basic_writer.rb | 1 + lib/combine_pdf/decrypt.rb | 3 ++- lib/combine_pdf/exceptions.rb | 2 ++ lib/combine_pdf/filter.rb | 1 + lib/combine_pdf/fonts.rb | 1 + lib/combine_pdf/page_methods.rb | 1 + lib/combine_pdf/parser.rb | 4 ++-- lib/combine_pdf/pdf_protected.rb | 2 ++ lib/combine_pdf/pdf_public.rb | 7 ++++--- lib/combine_pdf/renderer.rb | 5 +++-- lib/combine_pdf/version.rb | 4 +++- test/combine_pdf/renderer_test.rb | 2 +- 15 files changed, 31 insertions(+), 12 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6e2e1e1..3d84327 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,11 @@ jobs: strategy: fail-fast: false matrix: - ruby: ["2.7", "3.0", "3.1", "3.2"] + ruby: ["2.7", "3.0", "3.1", "3.2", "3.3"] + rubyopt: [""] + include: + - ruby: "3.3" + rubyopt: "--enable-frozen-string-literal --debug-frozen-string-literal" steps: - name: Checkout code @@ -25,4 +29,4 @@ jobs: run: bundle lock - name: Run tests - run: bundle exec rake test + run: bundle exec rake test RUBYOPT="${{ matrix.rubyopt }}" diff --git a/lib/combine_pdf.rb b/lib/combine_pdf.rb index 4713803..5a11689 100644 --- a/lib/combine_pdf.rb +++ b/lib/combine_pdf.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true require 'zlib' require 'securerandom' diff --git a/lib/combine_pdf/api.rb b/lib/combine_pdf/api.rb index ac5ff9d..72fc641 100644 --- a/lib/combine_pdf/api.rb +++ b/lib/combine_pdf/api.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true module CombinePDF module_function diff --git a/lib/combine_pdf/basic_writer.rb b/lib/combine_pdf/basic_writer.rb index a822ccf..30661e4 100644 --- a/lib/combine_pdf/basic_writer.rb +++ b/lib/combine_pdf/basic_writer.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code diff --git a/lib/combine_pdf/decrypt.rb b/lib/combine_pdf/decrypt.rb index 70938c3..8976765 100644 --- a/lib/combine_pdf/decrypt.rb +++ b/lib/combine_pdf/decrypt.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code @@ -137,7 +138,7 @@ def decrypt_AES(encrypted, encrypted_id, encrypted_generation, _encrypted_filter object_key = @key.dup object_key << [encrypted_id].pack('i')[0..2] object_key << [encrypted_generation].pack('i')[0..1] - object_key << 'sAlT'.force_encoding(Encoding::ASCII_8BIT) + object_key << 'sAlT'.b key_length = object_key.length < 16 ? object_key.length : 16 begin diff --git a/lib/combine_pdf/exceptions.rb b/lib/combine_pdf/exceptions.rb index 5c8bbe0..5d59747 100644 --- a/lib/combine_pdf/exceptions.rb +++ b/lib/combine_pdf/exceptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module CombinePDF class EncryptionError < StandardError end diff --git a/lib/combine_pdf/filter.rb b/lib/combine_pdf/filter.rb index 7ec033b..ebf9be4 100644 --- a/lib/combine_pdf/filter.rb +++ b/lib/combine_pdf/filter.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code diff --git a/lib/combine_pdf/fonts.rb b/lib/combine_pdf/fonts.rb index 3b266de..2544b92 100644 --- a/lib/combine_pdf/fonts.rb +++ b/lib/combine_pdf/fonts.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code diff --git a/lib/combine_pdf/page_methods.rb b/lib/combine_pdf/page_methods.rb index 078bfab..20b3fcb 100644 --- a/lib/combine_pdf/page_methods.rb +++ b/lib/combine_pdf/page_methods.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code diff --git a/lib/combine_pdf/parser.rb b/lib/combine_pdf/parser.rb index 2689750..9b7f203 100644 --- a/lib/combine_pdf/parser.rb +++ b/lib/combine_pdf/parser.rb @@ -262,7 +262,7 @@ def _parse_ ########################################## elsif @scanner.scan(/\(/) # warn "Found a literal string" - str = ''.force_encoding(Encoding::ASCII_8BIT) + str = ''.b count = 1 while count > 0 && @scanner.rest? scn = @scanner.scan_until(/[\(\)]/) @@ -379,7 +379,7 @@ def _parse_ length = 0 if(length < 0) length -= 1 if(@scanner.string[old_pos + length - 1] == "\n") length -= 1 if(@scanner.string[old_pos + length - 1] == "\r") - str = (length > 0) ? @scanner.string.slice(old_pos, length) : '' + str = (length > 0) ? @scanner.string.slice(old_pos, length) : +'' # warn "CombinePDF parser: detected Stream #{str.length} bytes long #{str[0..3]}...#{str[-4..-1]}" diff --git a/lib/combine_pdf/pdf_protected.rb b/lib/combine_pdf/pdf_protected.rb index 8e78a28..7dd24dd 100644 --- a/lib/combine_pdf/pdf_protected.rb +++ b/lib/combine_pdf/pdf_protected.rb @@ -1,4 +1,5 @@ # -*- encoding : utf-8 -*- +# frozen_string_literal: true ######################################################## ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code @@ -186,6 +187,7 @@ def remove_old_ids POSSIBLE_NAME_TREES = [:Dests, :AP, :Pages, :IDS, :Templates, :URLS, :JavaScript, :EmbeddedFiles, :AlternatePresentations, :Renditions].to_set.freeze def rebuild_names(name_tree = nil, base = 'CombinePDF_0000000') + base = +base if name_tree return nil unless name_tree.is_a?(Hash) name_tree = name_tree[:referenced_object] || name_tree diff --git a/lib/combine_pdf/pdf_public.rb b/lib/combine_pdf/pdf_public.rb index b4c910e..5fe665f 100644 --- a/lib/combine_pdf/pdf_public.rb +++ b/lib/combine_pdf/pdf_public.rb @@ -1,5 +1,6 @@ # -*- encoding : utf-8 -*- -######################################################## +## frozen_string_literal: true +####################################################### ## Thoughts from reading the ISO 32000-1:2008 ## this file is part of the CombinePDF library and the code ## is subject to the same license. @@ -93,7 +94,7 @@ def initialize(parser = nil) @version = 0 @viewer_preferences = {} @info = {} - parser ||= PDFParser.new('') + parser ||= PDFParser.new(+'') raise TypeError, "initialization error, expecting CombinePDF::PDFParser or nil, but got #{parser.class.name}" unless parser.is_a? PDFParser @objects = parser.parse @@ -216,7 +217,7 @@ def to_pdf(options = {}) # when finished, remove the numbering system and keep only pointers remove_old_ids # output the pdf stream - out.join("\n".force_encoding(Encoding::ASCII_8BIT)).force_encoding(Encoding::ASCII_8BIT) + out.join("\n").force_encoding(Encoding::ASCII_8BIT) end # this method returns all the pages cataloged in the catalog. diff --git a/lib/combine_pdf/renderer.rb b/lib/combine_pdf/renderer.rb index eaa43b7..71a8a03 100644 --- a/lib/combine_pdf/renderer.rb +++ b/lib/combine_pdf/renderer.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true module CombinePDF ################################################################ ## These are common functions, used within the different classes @@ -123,12 +124,12 @@ def format_hash_to_pdf(object) # if the object is not a simple object, it is a dictionary # A dictionary shall be written as a sequence of key-value pairs enclosed in double angle brackets (<<...>>) # (using LESS-THAN SIGNs (3Ch) and GREATER-THAN SIGNs (3Eh)). - out << "<<\n".force_encoding(Encoding::ASCII_8BIT) + out << "<<\n".b object.each do |key, value| out << "#{object_to_pdf key} #{object_to_pdf value}\n".force_encoding(Encoding::ASCII_8BIT) unless PDF::PRIVATE_HASH_KEYS.include? key end object.delete :Length - out << '>>'.force_encoding(Encoding::ASCII_8BIT) + out << '>>'.b out << "\nstream\n#{object[:raw_stream_content]}\nendstream".force_encoding(Encoding::ASCII_8BIT) if object[:raw_stream_content] out << "\nendobj\n" if object[:indirect_reference_id] out.join.force_encoding(Encoding::ASCII_8BIT) diff --git a/lib/combine_pdf/version.rb b/lib/combine_pdf/version.rb index f5d6e53..61415d1 100644 --- a/lib/combine_pdf/version.rb +++ b/lib/combine_pdf/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module CombinePDF - VERSION = '1.0.26'.freeze + VERSION = '1.0.26' end diff --git a/test/combine_pdf/renderer_test.rb b/test/combine_pdf/renderer_test.rb index 53ec41a..bfd4940 100644 --- a/test/combine_pdf/renderer_test.rb +++ b/test/combine_pdf/renderer_test.rb @@ -12,7 +12,7 @@ def test_object(object) def test_numeric_array_to_pdf input = [1.234567, 0.000054, 5, -0.000099] - expected = "[1.234567 0.000054 5 -0.000099]".force_encoding('BINARY') + expected = "[1.234567 0.000054 5 -0.000099]".b actual = TestRenderer.new.test_object(input) assert_equal(expected, actual)