快速业务通道

数组协变带来的静态类型漏洞 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
// "[Ljava/lang/Object;" const #11 = Asciz a string; const #12 = String #11; // a string const #13 = Asciz toString; const #14 = Asciz ()V; const #15 = NameAndType #13:#14;// toString:()V const #16 = Method #4.#15; // java/lang/Object.toString:()V const #17 = Asciz Code; { public static void main(java.lang.String[]); Code: Stack=3, Locals=1, Args_size=1 0: iconst_1 1: anewarray #8; //class java/lang/Float 4: checkcast #10; //class "[Ljava/lang/Object;" 7: astore_0 8: aload_0 9: iconst_0 10: ldc #12; //String a string 12: aastore 13: aload_0 14: iconst_0 15: aaload 16: invokevirtual #16; //Method java/lang/Object.toString:()V 19: return }

数组协变带来的静态类型漏洞(3)

时间:2011-10-07 javaeye RednaxelaFX

这次的代码其实直接用Java源码也能表示出来,也就是:

Java代码

public class TestVerification {
    public static void main(String[] args) {
        Object[] array = (Object[]) new Float[1];
        array[0] = "a string"; // 问题出在这里
        array[0].toString();
    }
}

编译不会有任何问题。这代码也是完全符合Java规范,也满足JVM的静态校验对类型的要求,所以加载 时的校验也没问题。

但是运行的话……

Command prompt代码

Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
        at TestVerification.main(Unknown Source)

很明显我们没办法把一个String类型的对象保存到一个Float[]里,但由于Java数组是协变的,所以 Java的静态类型系统允许我们这么做,却会到运行时扔异常出来。

.NET很不幸的模仿了Java的这个特性,也把数组设计为协变的。因而CLI与JVM一样(JVM:aastore; CLI:stelem),也必须在运行时对数组的保存做动态类型检查。这对性能的影响自然不太好,而且也使 得VM的实现更复杂……诶。

《Virtual Machines: Versatile Platforms for Systems and Processes》影印版第289页倒数第二 段提到:

引用

Hence, if an object is accessed, the field information for the access can also be checked statically (there is an exception for arrays, given in the next paragraph).

然后在接下来的一段里,这本书却只提到了动态检查数组访问时越界检查,而没有提到由协变带来的 静态类型漏洞。我觉得这里还是提一下协变问题比较好的。毕竟,数组长度并不是Java的静态类型的一部 分,它的检查只能留待运行时检查(VM可以根据数据流分析而消除许多数组越界和空指针检查就是了); 而类型协变是静态类型系统的一部分,却有漏洞所以运行时仍然要检查,这就不爽了。

数组协变带来的静态类型漏洞(4)

时间:2011-10-07 javaeye RednaxelaFX

看看Martin Odersky在最近的一个访谈里对Java数组的协变的评论:

Martin Odersky 写道

Bill Venners: You said you found it frustrating at times to have the constraints of needing to be backwards compatible with Java. Can you give some specific examples of things you couldn''t do when you were trying to live within those constraints, which you were then able to do when you changed to doing something that''s binary but not source compatible?

Martin Odersky: In the generics design, there were a

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号