Gary Benson wrote:
> Robert Lougher wrote:
> > Do you have a testcase?
> 
> If you build and run the attached testcase you ought to see only one
> checkPermission() between "Calling checkRead()" and "Done". ... In
> reality, JamVM chokes on it pretty hard.  I _think_ what is
> happening is that the System.out.println in checkPermission() is
> itself doing some initialisation which causes security checks,
> causing an infinite loop.

The initialisation in question turns out to be:

 1. Loading java.lang.StringBuffer to build the message.
 2. Loading java.io.PrintStream to print it out.
 3. Converting the message to bytes using String.getBytes(encoding).

Any one of them will trigger a security check and hence an infinite
loop.  There's an awful lot I still don't undertstand here, but I'm
a step closer...  MaƱana.

In case anyone's interested I've attached a patched testcase and a
patch for classpath which together work on JamVM.

Cheers,
Gary
import java.security.Permission;

class Test
{
  static class TestSecurityManager extends SecurityManager
  {
    public void checkPermission(Permission perm) {
      System.out.println("  checkPermission(" + perm + ")");
    }
  }
        
  public static void main(String[] args) {
    java.lang.StringBuffer XXX1 = new java.lang.StringBuffer();
    java.io.PrintStream XXX2 = new java.io.PrintStream(null);
    try {
      SecurityManager sm = new TestSecurityManager();
      System.setSecurityManager(sm);
      System.out.println("Calling checkRead()");
      sm.checkRead("/");
      System.out.println("Done");
    }
    catch (Throwable t) {
      t.printStackTrace();
    }
  }
}
Index: java/lang/String.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v
retrieving revision 1.77
diff -u -r1.77 String.java
--- java/lang/String.java       6 Dec 2005 18:52:25 -0000       1.77
+++ java/lang/String.java       12 Dec 2005 17:40:55 -0000
@@ -680,35 +680,9 @@
    */
   public byte[] getBytes(String enc) throws UnsupportedEncodingException
   {
-    try 
-      {
-       CharsetEncoder cse = Charset.forName(enc).newEncoder();
-       cse.onMalformedInput(CodingErrorAction.REPLACE);
-       cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
-       ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
-       if(bbuf.hasArray())
-         return bbuf.array();
-       
-       // Doubt this will happen. But just in case.
-       byte[] bytes = new byte[bbuf.remaining()];
-       bbuf.get(bytes);
-       return bytes;
-      } 
-    catch(IllegalCharsetNameException e)
-      {
-       throw new UnsupportedEncodingException("Encoding: " + enc
-                                              + " not found.");
-      } 
-    catch(UnsupportedCharsetException e)
-      {
-       throw new UnsupportedEncodingException("Encoding: " + enc
-                                              + " not found.");
-      } 
-    catch(CharacterCodingException e)
-      {
-       // This shouldn't ever happen.
-       throw (InternalError) new InternalError().initCause(e);
-      }          
+    byte[] bytes = new byte[length()];
+    getBytes(0, length(), bytes, 0);
+    return bytes;
   }
 
   /**
_______________________________________________
Classpath mailing list
Classpath@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath

Reply via email to