Throw NRE if src or dst in Memmove are nulls (mono/mono#16650)
authorEgor Bogatov <egorbo@gmail.com>
Wed, 4 Sep 2019 09:01:53 +0000 (12:01 +0300)
committerBernhard Urban <lewurm@gmail.com>
Wed, 4 Sep 2019 09:01:53 +0000 (11:01 +0200)
Commit migrated from https://github.com/mono/mono/commit/1558316cecdf7186a3b792b021304c6356079bfe

src/mono/mono/mini/intrinsics.c

index 9f7e190..962de10 100644 (file)
@@ -224,8 +224,13 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 
        if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) {
                if (!strcmp (cmethod->name, "Memmove") && fsig->param_count == 3 && fsig->params [0]->type == MONO_TYPE_PTR && fsig->params [1]->type == MONO_TYPE_PTR) {
-                       opcode = OP_MEMMOVE;
-                       MONO_INST_NEW (cfg, ins, opcode);
+                       // throw NRE if src or dst are nulls
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
+                       MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, 0);
+                       MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
+
+                       MONO_INST_NEW (cfg, ins, OP_MEMMOVE);
                        ins->sreg1 = args [0]->dreg; // i1* dst
                        ins->sreg2 = args [1]->dreg; // i1* src
                        ins->sreg3 = args [2]->dreg; // i32/i64 len