看板 java 關於我們 聯絡資訊
※ 引述《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