From 5acea42bfb17b59aff01ce77fe63d880b4ef5878 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Thu, 26 Apr 2001 11:11:02 -0700 Subject: [PATCH] verify.c (verify_jvm_instructions): For field instructions, check that field index is valid. * verify.c (verify_jvm_instructions): For field instructions, check that field index is valid. For invoke instructions, check that method index is valid. From-SVN: r41600 --- gcc/java/ChangeLog | 6 ++++++ gcc/java/verify.c | 52 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index a6c8b540ca3..1f8fd67c9f3 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,9 @@ +2001-04-25 Per Bothner + + * verify.c (verify_jvm_instructions): For field instructions, + check that field index is valid. For invoke instructions, check that + method index is valid. + 2001-04-25 Alexandre Oliva * config-lang.in (target_libs): Copy from $libgcj_saved. diff --git a/gcc/java/verify.c b/gcc/java/verify.c index 9b83363cf55..0a63477d715 100644 --- a/gcc/java/verify.c +++ b/gcc/java/verify.c @@ -901,9 +901,15 @@ verify_jvm_instructions (jcf, byte_ops, length) case OPCODE_putfield: is_putting = 1; is_static = 0; goto field; field: { - int index = IMMEDIATE_u2; - tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index); - tree field_type = get_type_from_signature (field_signature); + tree field_signature, field_type; + index = IMMEDIATE_u2; + if (index <= 0 || index >= JPOOL_SIZE(current_jcf)) + VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d"); + if (JPOOL_TAG (current_jcf, index) != CONSTANT_Fieldref) + VERIFICATION_ERROR + ("field instruction does not reference a Fieldref"); + field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index); + field_type = get_type_from_signature (field_signature); if (is_putting) POP_TYPE (field_type, "incorrect type for field"); if (! is_static) @@ -959,7 +965,7 @@ verify_jvm_instructions (jcf, byte_ops, length) index = IMMEDIATE_u2; goto ldc; ldc: if (index <= 0 || index >= JPOOL_SIZE(current_jcf)) - VERIFICATION_ERROR ("bad constant pool index in ldc"); + VERIFICATION_ERROR_WITH_INDEX ("bad constant pool index %d in ldc"); int_value = -1; switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag) { @@ -988,13 +994,32 @@ verify_jvm_instructions (jcf, byte_ops, length) case OPCODE_invokestatic: case OPCODE_invokeinterface: { - int index = IMMEDIATE_u2; - tree sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index); - tree self_type = get_class_constant + tree sig, method_name, method_type, self_type; + int self_is_interface, tag; + index = IMMEDIATE_u2; + if (index <= 0 || index >= JPOOL_SIZE(current_jcf)) + VERIFICATION_ERROR_WITH_INDEX + ("bad constant pool index %d for invoke"); + tag = JPOOL_TAG (current_jcf, index); + if (op_code == OPCODE_invokeinterface) + { + if (tag != CONSTANT_InterfaceMethodref) + VERIFICATION_ERROR + ("invokeinterface does not reference an InterfaceMethodref"); + } + else + { + if (tag != CONSTANT_Methodref) + VERIFICATION_ERROR ("invoke does not reference a Methodref"); + } + sig = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, index); + self_type = get_class_constant (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, index)); - tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index); - tree method_type; + if (! CLASS_LOADED_P (self_type)) + load_class (self_type, 1); + self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type)); + method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, index); method_type = parse_signature_string (IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig)); if (TREE_CODE (method_type) != FUNCTION_TYPE) @@ -1027,7 +1052,14 @@ verify_jvm_instructions (jcf, byte_ops, length) if (!nargs || notZero) VERIFICATION_ERROR ("invalid argument number in invokeinterface"); - break; + // If we verify/resolve the constant pool, as we should, + // this test (and the one just following) are redundant. + if (! self_is_interface) + VERIFICATION_ERROR ("invokeinterface calls method not in interface"); + break; + default: + if (self_is_interface) + VERIFICATION_ERROR ("method in interface called"); } } -- 2.30.2