From f64da8003515df460bd26ff0df455d36d3155a48 Mon Sep 17 00:00:00 2001 From: The Major Date: Sun, 24 Nov 2024 23:40:50 +0000 Subject: [PATCH] raise ArgumentError on unknown directive Array pack/ String unpack --- CHANGELOG.md | 2 ++ spec/ruby/core/array/pack/shared/basic.rb | 6 +++--- spec/ruby/core/string/unpack/shared/basic.rb | 9 +++++++++ spec/tags/core/array/pack/a_tags.txt | 2 -- spec/tags/core/array/pack/at_tags.txt | 1 - spec/tags/core/array/pack/b_tags.txt | 2 -- spec/tags/core/array/pack/c_tags.txt | 2 -- spec/tags/core/array/pack/h_tags.txt | 2 -- spec/tags/core/array/pack/i_tags.txt | 2 -- spec/tags/core/array/pack/j_tags.txt | 2 -- spec/tags/core/array/pack/l_tags.txt | 2 -- spec/tags/core/array/pack/m_tags.txt | 2 -- spec/tags/core/array/pack/n_tags.txt | 2 -- spec/tags/core/array/pack/p_tags.txt | 2 -- spec/tags/core/array/pack/q_tags.txt | 2 -- spec/tags/core/array/pack/s_tags.txt | 2 -- spec/tags/core/array/pack/u_tags.txt | 2 -- spec/tags/core/array/pack/v_tags.txt | 2 -- spec/tags/core/array/pack/w_tags.txt | 1 - spec/tags/core/array/pack/x_tags.txt | 2 -- spec/tags/core/array/pack/z_tags.txt | 1 - .../truffleruby/core/format/pack/SimplePackListener.java | 1 + .../truffleruby/core/format/pack/SimplePackParser.java | 3 +-- .../core/format/pack/SimplePackTreeBuilder.java | 5 +++++ .../core/format/unpack/SimpleUnpackTreeBuilder.java | 5 +++++ 25 files changed, 26 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13d84934e6b..805228e316d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ Compatibility: * Add `IO#{pread, pwrite}` methods (#3718, @andrykonchin). * Add `rb_io_closed_p()` (#3681, @andrykonchin). * Add `rb_io_open_descriptor()` (#3681, @andrykonchin). +* `Array#pack` now raises `ArgumentError` for unknown directives (#3681, @Th3-M4jor). +* `String#unpack` now raises `ArgumentError` for unknown directives (#3681, @Th3-M4jor). Performance: diff --git a/spec/ruby/core/array/pack/shared/basic.rb b/spec/ruby/core/array/pack/shared/basic.rb index 5e3eea55f91f..4b28de7ed040 100644 --- a/spec/ruby/core/array/pack/shared/basic.rb +++ b/spec/ruby/core/array/pack/shared/basic.rb @@ -57,9 +57,9 @@ # NOTE: Added this case just to not forget about the decision in the ticket it "raise ArgumentError when a directive is unknown" do # additional directive ('a') is required for the X directive - -> { [@obj, @obj].pack("a R" + pack_format) }.should raise_error(ArgumentError) - -> { [@obj, @obj].pack("a 0" + pack_format) }.should raise_error(ArgumentError) - -> { [@obj, @obj].pack("a :" + pack_format) }.should raise_error(ArgumentError) + -> { [@obj, @obj].pack("a R" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive 'R'/) + -> { [@obj, @obj].pack("a 0" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive '0'/) + -> { [@obj, @obj].pack("a :" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive ':'/) end end diff --git a/spec/ruby/core/string/unpack/shared/basic.rb b/spec/ruby/core/string/unpack/shared/basic.rb index bb5302edc532..b37a447683a9 100644 --- a/spec/ruby/core/string/unpack/shared/basic.rb +++ b/spec/ruby/core/string/unpack/shared/basic.rb @@ -8,6 +8,15 @@ d.should_receive(:to_str).and_return("a"+unpack_format) "abc".unpack(d).should be_an_instance_of(Array) end + + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19150 + it 'raise ArgumentError when a directive is unknown' do + -> { "abcdefgh".unpack("a R" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive 'R'/) + -> { "abcdefgh".unpack("a 0" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive '0'/) + -> { "abcdefgh".unpack("a :" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive ':'/) + end + end end describe :string_unpack_no_platform, shared: true do diff --git a/spec/tags/core/array/pack/a_tags.txt b/spec/tags/core/array/pack/a_tags.txt index 3ab967f83288..41cef01ed383 100644 --- a/spec/tags/core/array/pack/a_tags.txt +++ b/spec/tags/core/array/pack/a_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'A' warns that a directive is unknown fails:Array#pack with format 'a' warns that a directive is unknown -fails:Array#pack with format 'A' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'a' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/at_tags.txt b/spec/tags/core/array/pack/at_tags.txt index 4c5544732671..2e258a4fa543 100644 --- a/spec/tags/core/array/pack/at_tags.txt +++ b/spec/tags/core/array/pack/at_tags.txt @@ -1,2 +1 @@ fails:Array#pack with format '@' warns that a directive is unknown -fails:Array#pack with format '@' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/b_tags.txt b/spec/tags/core/array/pack/b_tags.txt index 597e8da16301..663597e244dc 100644 --- a/spec/tags/core/array/pack/b_tags.txt +++ b/spec/tags/core/array/pack/b_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'B' warns that a directive is unknown fails:Array#pack with format 'b' warns that a directive is unknown -fails:Array#pack with format 'B' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'b' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/c_tags.txt b/spec/tags/core/array/pack/c_tags.txt index c6676db7c4cd..12b8bf9cc60f 100644 --- a/spec/tags/core/array/pack/c_tags.txt +++ b/spec/tags/core/array/pack/c_tags.txt @@ -1,6 +1,4 @@ fails:Array#pack with format 'C' warns that a directive is unknown fails:Array#pack with format 'c' warns that a directive is unknown -fails:Array#pack with format 'C' raise ArgumentError when a directive is unknown fails:Array#pack with format 'C' raise ArgumentError for NULL bytes between directives -fails:Array#pack with format 'c' raise ArgumentError when a directive is unknown fails:Array#pack with format 'c' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/h_tags.txt b/spec/tags/core/array/pack/h_tags.txt index 84a5c5128451..a0fe0fa8f86e 100644 --- a/spec/tags/core/array/pack/h_tags.txt +++ b/spec/tags/core/array/pack/h_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'H' warns that a directive is unknown fails:Array#pack with format 'h' warns that a directive is unknown -fails:Array#pack with format 'H' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'h' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/i_tags.txt b/spec/tags/core/array/pack/i_tags.txt index 9e420a3a62b6..c6790f87042d 100644 --- a/spec/tags/core/array/pack/i_tags.txt +++ b/spec/tags/core/array/pack/i_tags.txt @@ -1,7 +1,5 @@ fails:Array#pack with format 'I' warns that a directive is unknown fails:Array#pack with format 'i' warns that a directive is unknown -fails:Array#pack with format 'I' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'i' raise ArgumentError when a directive is unknown fails:Array#pack with format 'I' with modifier '<' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'I' with modifier '<' and '_' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'I' with modifier '<' and '!' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/j_tags.txt b/spec/tags/core/array/pack/j_tags.txt index 2608885894bc..e5e22493e4b8 100644 --- a/spec/tags/core/array/pack/j_tags.txt +++ b/spec/tags/core/array/pack/j_tags.txt @@ -1,7 +1,5 @@ fails:Array#pack with format 'J' warns that a directive is unknown fails:Array#pack with format 'j' warns that a directive is unknown -fails:Array#pack with format 'J' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'j' raise ArgumentError when a directive is unknown fails:Array#pack with format 'J' with modifier '_' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'J' with modifier '!' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'j' with modifier '_' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/l_tags.txt b/spec/tags/core/array/pack/l_tags.txt index 2a246fb643f5..e31f9a559c15 100644 --- a/spec/tags/core/array/pack/l_tags.txt +++ b/spec/tags/core/array/pack/l_tags.txt @@ -1,7 +1,5 @@ fails:Array#pack with format 'L' warns that a directive is unknown fails:Array#pack with format 'l' warns that a directive is unknown -fails:Array#pack with format 'L' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'l' raise ArgumentError when a directive is unknown fails:Array#pack with format 'L' with modifier '<' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'L' with modifier '>' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'L' with modifier '<' and '_' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/m_tags.txt b/spec/tags/core/array/pack/m_tags.txt index 51658a56fe9f..458fe7764ce5 100644 --- a/spec/tags/core/array/pack/m_tags.txt +++ b/spec/tags/core/array/pack/m_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'M' warns that a directive is unknown fails:Array#pack with format 'm' warns that a directive is unknown -fails:Array#pack with format 'M' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'm' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/n_tags.txt b/spec/tags/core/array/pack/n_tags.txt index 95d9f5cdc4c8..f8f6af496ee5 100644 --- a/spec/tags/core/array/pack/n_tags.txt +++ b/spec/tags/core/array/pack/n_tags.txt @@ -1,6 +1,4 @@ fails:Array#pack with format 'N' warns that a directive is unknown fails:Array#pack with format 'n' warns that a directive is unknown -fails:Array#pack with format 'N' raise ArgumentError when a directive is unknown fails:Array#pack with format 'N' raise ArgumentError for NULL bytes between directives -fails:Array#pack with format 'n' raise ArgumentError when a directive is unknown fails:Array#pack with format 'n' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/p_tags.txt b/spec/tags/core/array/pack/p_tags.txt index 8ddfcdbf0cdc..a4da6647e19a 100644 --- a/spec/tags/core/array/pack/p_tags.txt +++ b/spec/tags/core/array/pack/p_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'P' warns that a directive is unknown fails:Array#pack with format 'p' warns that a directive is unknown -fails:Array#pack with format 'P' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'p' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/q_tags.txt b/spec/tags/core/array/pack/q_tags.txt index 357f1792fea2..2b69199f5c68 100644 --- a/spec/tags/core/array/pack/q_tags.txt +++ b/spec/tags/core/array/pack/q_tags.txt @@ -1,7 +1,5 @@ fails:Array#pack with format 'Q' warns that a directive is unknown fails:Array#pack with format 'q' warns that a directive is unknown -fails:Array#pack with format 'Q' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'q' raise ArgumentError when a directive is unknown fails:Array#pack with format 'Q' with modifier '<' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'Q' with modifier '>' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'q' with modifier '<' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/s_tags.txt b/spec/tags/core/array/pack/s_tags.txt index 7c0c0b55e564..28a894f20b42 100644 --- a/spec/tags/core/array/pack/s_tags.txt +++ b/spec/tags/core/array/pack/s_tags.txt @@ -1,7 +1,5 @@ fails:Array#pack with format 'S' warns that a directive is unknown fails:Array#pack with format 's' warns that a directive is unknown -fails:Array#pack with format 'S' raise ArgumentError when a directive is unknown -fails:Array#pack with format 's' raise ArgumentError when a directive is unknown fails:Array#pack with format 'S' with modifier '<' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'S' with modifier '<' and '_' raise ArgumentError for NULL bytes between directives fails:Array#pack with format 'S' with modifier '<' and '!' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/u_tags.txt b/spec/tags/core/array/pack/u_tags.txt index 315aa3a1fa9b..c6d87f992412 100644 --- a/spec/tags/core/array/pack/u_tags.txt +++ b/spec/tags/core/array/pack/u_tags.txt @@ -1,5 +1,3 @@ fails:Array#pack with format 'U' warns that a directive is unknown fails:Array#pack with format 'u' warns that a directive is unknown -fails:Array#pack with format 'U' raise ArgumentError when a directive is unknown fails:Array#pack with format 'U' raise ArgumentError for NULL bytes between directives -fails:Array#pack with format 'u' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/v_tags.txt b/spec/tags/core/array/pack/v_tags.txt index 0f9660df0ac4..0ae8174ab5a0 100644 --- a/spec/tags/core/array/pack/v_tags.txt +++ b/spec/tags/core/array/pack/v_tags.txt @@ -1,6 +1,4 @@ fails:Array#pack with format 'V' warns that a directive is unknown fails:Array#pack with format 'v' warns that a directive is unknown -fails:Array#pack with format 'V' raise ArgumentError when a directive is unknown fails:Array#pack with format 'V' raise ArgumentError for NULL bytes between directives -fails:Array#pack with format 'v' raise ArgumentError when a directive is unknown fails:Array#pack with format 'v' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/w_tags.txt b/spec/tags/core/array/pack/w_tags.txt index 2ce31fc80272..455acf100a5e 100644 --- a/spec/tags/core/array/pack/w_tags.txt +++ b/spec/tags/core/array/pack/w_tags.txt @@ -1,3 +1,2 @@ fails:Array#pack with format 'w' warns that a directive is unknown -fails:Array#pack with format 'w' raise ArgumentError when a directive is unknown fails:Array#pack with format 'w' raise ArgumentError for NULL bytes between directives diff --git a/spec/tags/core/array/pack/x_tags.txt b/spec/tags/core/array/pack/x_tags.txt index a3acb7a49c67..759ca242150f 100644 --- a/spec/tags/core/array/pack/x_tags.txt +++ b/spec/tags/core/array/pack/x_tags.txt @@ -1,4 +1,2 @@ fails:Array#pack with format 'x' warns that a directive is unknown fails:Array#pack with format 'X' warns that a directive is unknown -fails:Array#pack with format 'x' raise ArgumentError when a directive is unknown -fails:Array#pack with format 'X' raise ArgumentError when a directive is unknown diff --git a/spec/tags/core/array/pack/z_tags.txt b/spec/tags/core/array/pack/z_tags.txt index 4c19fa07c585..ae31e4554a5a 100644 --- a/spec/tags/core/array/pack/z_tags.txt +++ b/spec/tags/core/array/pack/z_tags.txt @@ -1,2 +1 @@ fails:Array#pack with format 'Z' warns that a directive is unknown -fails:Array#pack with format 'Z' raise ArgumentError when a directive is unknown diff --git a/src/main/java/org/truffleruby/core/format/pack/SimplePackListener.java b/src/main/java/org/truffleruby/core/format/pack/SimplePackListener.java index 78396166aca9..2da44d146020 100644 --- a/src/main/java/org/truffleruby/core/format/pack/SimplePackListener.java +++ b/src/main/java/org/truffleruby/core/format/pack/SimplePackListener.java @@ -59,4 +59,5 @@ public interface SimplePackListener { void warn(String message); + String packListenerMode(); } diff --git a/src/main/java/org/truffleruby/core/format/pack/SimplePackParser.java b/src/main/java/org/truffleruby/core/format/pack/SimplePackParser.java index cf0cc99a256d..f70a8b5c14b3 100644 --- a/src/main/java/org/truffleruby/core/format/pack/SimplePackParser.java +++ b/src/main/java/org/truffleruby/core/format/pack/SimplePackParser.java @@ -427,8 +427,7 @@ public void parse() throws DeferredRaiseException { default: n++; - listener.warn(String.format("unknown pack directive '%c'", (char) b)); - break; + listener.error(String.format("unknown %s directive '%c'", listener.packListenerMode(), (char) b)); } } } diff --git a/src/main/java/org/truffleruby/core/format/pack/SimplePackTreeBuilder.java b/src/main/java/org/truffleruby/core/format/pack/SimplePackTreeBuilder.java index 767fc178f527..e5b16ac115e8 100644 --- a/src/main/java/org/truffleruby/core/format/pack/SimplePackTreeBuilder.java +++ b/src/main/java/org/truffleruby/core/format/pack/SimplePackTreeBuilder.java @@ -271,6 +271,11 @@ public void warn(String message) { } } + @Override + public String packListenerMode() { + return "pack"; + } + public FormatNode getNode() { return sequenceStack.peek().get(0); } diff --git a/src/main/java/org/truffleruby/core/format/unpack/SimpleUnpackTreeBuilder.java b/src/main/java/org/truffleruby/core/format/unpack/SimpleUnpackTreeBuilder.java index e177fa0be67d..4d5dbaa1a2a0 100644 --- a/src/main/java/org/truffleruby/core/format/unpack/SimpleUnpackTreeBuilder.java +++ b/src/main/java/org/truffleruby/core/format/unpack/SimpleUnpackTreeBuilder.java @@ -279,6 +279,11 @@ public void warn(String message) { throw CompilerDirectives.shouldNotReachHere(); } + @Override + public String packListenerMode() { + return "unpack"; + } + public FormatNode getNode() { return sequenceStack.peek().get(0); }