作者Lordaeron (Terry)
看板java
标题Re: [J2SE] string literal
时间Thu Jan 25 14:18:03 2007
※ 引述《godfat (godfat 真常)》之铭言:
: 我只能说我真的感到很吃惊,因为我从来没想过可能会有这种事情
: 尤其又是在 Java 这种强调安全的程式语言当中,居然可以玩这种花招
: 这是在 comp.lang.c++.moderated 看来的(咦?)
: topic 是 The D Programming Language(咦咦?)
: 内容是在讲 Java 的 string literal(咦咦咦?)
: well, 我不太会找连结,有人愿意的话可以帮忙提供个 link
: 这边就引用一些来自那里的文章,希望作者不会介意
: (顺便补上一点翻译好了,不过我只翻重点)
: Niklas Matthies wrote:
: > Well, it depends what one considers "basic". It's possible in Java to
: > have the statement
: > System.out.println("Hello, world!");
: 这行 Java 叙述,是有可能-
: > output "Suprise!" (or any other arbitrary string), by appropriate
: > preceding code.
: 印出 "Suprise!"(或是其他任何的字串),藉由印出字串前的一些手段。
: > (This is because string literals within a class are guaranteed to be
: > shared, so a different occurrence of "Hello, world!" in the source
: > code can be used to manipulate the contents of that shared String
: > object.)
: 因为字面字串是被共享的。
: 有人问起了这怎麽可能?(How is it possible? - by Andrei Alexandrescu)
: 於是 Niklas Matthies 就提供了 code...
: 我做了一点修改,增加一些其他人提供的例子
: class Test
: {
: public static void main(String[] args) throws Exception
: {
: java.util.HashSet<String> set = new java.util.HashSet<String>();
: set.add("Hello, World!");
: doEvil();
: set.add("Hello, World!");
: System.out.println(set); // prints "[Surprise!, Surprise!]"
: System.out.println("Hello, World!"); // prints "Surprise!"
: System.out.println("Hello, World!".indexOf('H')); // prints -1
: String s = new String("Hello, World!");
: System.out.println(s); // prints "Surprise!"
: }
: static void doEvil() throws Exception
: {
: String s = "Surprise!";
: String hw = "Hello, World!";
: setField(hw, "value", s.toCharArray());
: setField(hw, "count", Integer.valueOf(s.length()));
: setField(hw, "hash", Integer.valueOf(0));
: }
: static void setField(Object object, String name, Object value)
: throws Exception
: {
: java.lang.reflect.Field
: field = object.getClass().getDeclaredField(name);
: field.setAccessible(true);
: field.set(object, value);
: }
: }
: 另外也有人说,有个网站上也有一篇文章指出这个问题
: (做了一点编辑上的修改)
: peter koch larsen
: Andrei Alexandrescu (See Website For Email) skrev:
: > I didn't know that! How is it possible? Got code? Heck, it's not
: > possible in many C and C++ implementations - they put constant strings
: > in read-only pages.
: cheers! Andrei,
: I accidently fell over an article called something like
: "hi there".equals("cheers !") == true
: and skimming the article shows that this is exactly the article you
: requested. It is referenced at Kevlin Heeney'(?)s web (curbralan?), and
: I believe it was an article from Artima. Anyway, a quick google should
: get you home no sweat.
: hi there
: Peter
: 有兴趣的人可以去 google 看看,我是懒得看了
: 而我因为好奇而稍微翻了一下 Java API reflection 的部份,
: 大概知道是发生了什麽事情。上面红色标起来的那段程式是重点。
: 他找到了 string literal 的储存所在地,然後修改那段记忆体里的东西,
: 於是,Surprise!
: 重点就是,Java 为什麽允许这样的修改?
: Niklas Matthies 说这是为了使程式不用在 debugging mode 下也能进行 debug.
: 而,如果这个程式真的有安全性问题的话,应该要使用 SecurityManager
: 来阻止这件事发生,也就是使得那行 field.setAccessible(true); 失败
: Niklas Matthies
: On 2006-12-15 13:23, James Kanze wrote:
: > In the case of Java, the problem concerning literals may be the
: > most shocking, externally, but the fact that you can modify a
: > String after having passed it to another subsystem is far more
: > serious, since it undermines many of Java's security measures.
: No, it doesn't, because a security-conscious application will
: run under a SecurityManager that will prevent such accesses
: (the setAccessible() call will fail).
: The motivation for enabling such accesses is of course for use by a
: debugger without causing the debugging-enabled Java implementation to
: become non-conformant.
: -- Niklas Matthies
: what a surprise!
: 简言之,reflextion 不要乱用,SecurityManager 有时候要考虑用一下。
http://groups.google.com.tw/group/comp.lang.c++.moderated/b
rowse_thread/thread/a048420165ad4719/645ca9ac8aff4dab?lnk=st&
q=%22it+depends+what+one+considers+%22basic%22%22&rnum=2&
hl=zh-TW
#645ca9ac8aff4dab
请自行接成一行
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.187.14.39