2002/07/01 21:03:52
[org.ibex.core.git] / src / org / xwt / Platform.java
index 8efe59a..4fee620 100644 (file)
@@ -73,7 +73,7 @@ public class Platform {
 
             if (platform_class == null) {
                 if (Log.on) Log.log(Platform.class, "Unable to detect JVM");
-                System.exit(-1);
+                new Platform().criticalAbort("Unable to detect JVM");
             }
 
             if (Log.on) Log.log(Platform.class, "                  platform = " + platform.getDescriptiveName());
@@ -82,7 +82,7 @@ public class Platform {
         } catch (Exception e) {
             if (Log.on) Log.log(Platform.class, "Exception while trying to detect JVM");
             if (Log.on) Log.log(Platform.class, e);
-            System.exit(-1);
+            new Platform().criticalAbort("Unable to detect JVM");
         }
 
     }
@@ -106,7 +106,9 @@ public class Platform {
 
     /** creates a socket object */
     protected Socket _getSocket(String host, int port, boolean ssl, boolean negotiate) throws IOException {
-        return ssl ? new TinySSL(host, port, negotiate) : new Socket(java.net.InetAddress.getByName(host), port);
+        Socket ret = ssl ? new TinySSL(host, port, negotiate) : new Socket(java.net.InetAddress.getByName(host), port);
+        ret.setTcpNoDelay(true);
+        return ret;
     }
 
     /** creates and returns a picture */
@@ -156,10 +158,18 @@ public class Platform {
     }
     
     /** quits XWT */
-    protected void _exit() { System.exit(0); }
+    protected void _exit() {
+        if (Main.applet == null) {
+            System.exit(0);
+        } else {
+            // just block ourselves forever
+            // FIXME: implement this with an exit variable for MessageQueue and plat.*.eventThread
+            new Semaphore().block();
+        }
+    }
 
     /** used to notify the user of very serious failures; usually used when logging is not working or unavailable */
-    protected void _criticalAbort(String message) { System.exit(-1); }
+    protected void _criticalAbort(String message) { _exit(); }
 
     /** used to notify the user of very serious failures; usually used when logging is not working or unavailable */
     protected String _getDefaultFont() { return "sansserif10"; }
@@ -178,7 +188,7 @@ public class Platform {
     /** Returns null if XWT should always use direct connection; otherwise returns a ProxyInfo object with proxy settings */
     protected synchronized HTTP.ProxyInfo _detectProxy() { return null; }
 
-    /** displays a platform-specific "open file" dialog and returns the chosen filename */
+    /** displays a platform-specific "open file" dialog and returns the chosen filename, or null if the user hit cancel */
     protected String _fileDialog(String suggestedFileName, boolean write) { return null; }
 
     /** returns true iff the platform has a case-sensitive filesystem */
@@ -249,25 +259,13 @@ public class Platform {
     /** returns true iff the platform has a case-sensitive filesystem */
     public static boolean isCaseSensitive() { return platform._isCaseSensitive(); }
 
-    /** displays a platform-specific "open file" dialog and returns the chosen filename */
+    /** displays a platform-specific "open file" dialog and returns the chosen filename, or null if the user hit cancel */
     public static String fileDialog(String suggestedFileName, boolean write) {
-        // put ourselves in the background
-        Thread thread = Thread.currentThread();
-        if (!(thread instanceof ThreadMessage)) {
-            if (Log.on) Log.log(Platform.class, "xwt.openFile may only be called from background threads");
-            return null;
-        }
-        ThreadMessage mythread = (ThreadMessage)thread;
-        mythread.setPriority(Thread.MIN_PRIORITY);
-        mythread.done.release();
-
+        if (!ThreadMessage.suspendThread()) return null;
         try {
             return platform._fileDialog(suggestedFileName, write);
         } finally {
-            // okay, let ourselves be brought to the foreground
-            MessageQueue.add(mythread);
-            mythread.setPriority(Thread.NORM_PRIORITY);
-            mythread.go.block();
+            ThreadMessage.resumeThread();
         }
     }
 
@@ -277,6 +275,17 @@ public class Platform {
             if (Log.on) Log.log(Platform.class, "xwt.newBrowserWindow() only supports http and https urls");
             return;
         }
+
+        // check the URL for well-formedness, as a defense against buffer overflow attacks
+        try {
+            String u = url;
+            if (u.startsWith("https")) u = "http" + u.substring(5);
+            new URL(u);
+        } catch (MalformedURLException e) {
+            if (Log.on) Log.log(Platform.class, "URL " + url + " is not well-formed");
+            if (Log.on) Log.log(Platform.class, e);
+        }
+
         if (Log.on) Log.log(Platform.class, "newBrowserWindow, url = " + url);
         platform._newBrowserWindow(url);
     }
@@ -301,8 +310,8 @@ public class Platform {
     public static Surface createSurface(Box b, boolean framed, boolean refreshable) {
         Surface ret = platform._createSurface(b, framed);
         ret.setInvisible(b.invisible);
-        b.set(Box.size, 0, ret.width);
-        b.set(Box.size, 1, ret.height);
+        b.set(Box.size, 0, b.size(0) == 0 ? 10 : b.size(0));
+        b.set(Box.size, 1, b.size(1) == 0 ? 10 : b.size(1));
 
         Object titlebar = b.get("titlebar", null, true);
         if (titlebar != null) ret.setTitleBarText(titlebar.toString());