Skip to content

String#unpack1 returns an array instead of a single string #6134

Description

@lopopolo

Reproducer

MRI 3.3.0

$ irb
[3.3.0] > puts RUBY_VERSION, RUBY_ENGINE
3.3.0
ruby
=> nil
[3.3.0] > "U2VuZCByZWluZm9yY2VtZW50cw==\n".unpack1("m")
=> "Send reinforcements"

mruby 3.2.0

$ ./bin/mirb
mirb - Embeddable Interactive Ruby Shell

> puts RUBY_VERSION, RUBY_ENGINE
3.2
mruby
 => nil
> "U2VuZCByZWluZm9yY2VtZW50cw==\n".unpack1("m")
 => ["Send reinforcements"]

Issue

The hex decode ends with a continue:

    case PACK_DIR_BASE64:
      srcidx += unpack_base64(mrb, sptr, srclen - srcidx, result);
      continue;

which brings it to the top of the while loop. has_tmpl returns false and the if (single) block which is inside the while loop is never executed.

Fix

$ g diff
diff --git i/artichoke-backend/vendor/mruby/mrbgems/mruby-pack/src/pack.c w/artichoke-backend/vendor/mruby/mrbgems/mruby-pack/src/pack.c
index b5ecdc6479..ab51662d48 100644
--- i/mrbgems/mruby-pack/src/pack.c
+++ w/mrbgems/mruby-pack/src/pack.c
@@ -1575,12 +1575,12 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
         count--;
       }
     }
-    if (single) {
-      if (RARRAY_LEN(result) > 0) {
-        return RARRAY_PTR(result)[0];
-      }
-      return mrb_nil_value();
+  }
+  if (single) {
+    if (RARRAY_LEN(result) > 0) {
+      return RARRAY_PTR(result)[0];
     }
+    return mrb_nil_value();
   }
   return result;
 }

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