lopopolo · GitHub

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;
 }

Read the original on github.com ↗