※ 引述《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