United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4697178 : REGRESSION: URL.openStream() fails if JAR exists in folder with space in name

Details
Type:
Bug
Submit Date:
2002-06-04
Status:
Resolved
Updated Date:
2002-08-14
Project Name:
JDK
Resolved Date:
2002-06-15
Component:
deploy
OS:
windows_nt,windows_2000
Sub-Component:
plugin
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.0
Fixed Versions:
1.4.0_03 (03)

Related Reports
Backport:
Duplicate:

Sub Tasks

Description

Name: gm110360			Date: 06/04/2002


FULL PRODUCT VERSION :
Java Plug-in version 1.4.0
Using JRE HotSpot Client VM version 1.4.0 build 1.4.0_b92

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [version 5.00.2195]


A DESCRIPTION OF THE PROBLEM :
If an applet is packaged into an unsigned JAR file, and the
applet is launched in a browser locally from a folder whose
name contains a space, the applet throws a
java.security.AccessControlException when using
URL.openStream() to open a file living outside the JAR
(file is in codebase directory).

For example,

MyApplet.class is in MyApplet.jar. MyApplet.class wants to
read a file in the codebase directory, using URL.openStream
(). The file is not in the JAR file.

The HTML file that loads MyApplet.jar is located
in "C:\Program Files\javaapplets" (note space in name). The
HTML file is double-clicked to open it into browser using
the Plug-in.

When MyApplet tries URL.openStream() to read the text file,
it fails with a java.security.AccessControlException,
complaining that access is denied during checkPermission()
of the file read operation.


REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create an applet that uses URL.openStream() to read a
text file (or whatever) from the codebase directory.

2. Package the applet into a JAR file, but don't include
the text file in the JAR. The JAR should be unsigned.
 
3. Create a directory on the local machine that has a space
in the name. For example, "C:\Program Files\javaapplets".

4. In the directory from step 3, create an HTML page that
has an archive attribute naming the JAR file created above.

4. Double-click the HTML page to load it into a browser
that uses the Plug-in 1.4.

EXPECTED VERSUS ACTUAL BEHAVIOR :
The applet should load from the JAR file and should have
access to the external file in the codebase directory using
URL.openStream(). Instead, a
java.security.AccessControlException is thrown, claiming
that checkPermission() failed trying to read the file.



ERROR MESSAGES/STACK TRACES THAT OCCUR :
url is: file:/G:/Program%20Files/javaapplets/testfile.txt
EXCEPTION CAUGHT!!
java.security.AccessControlException: access denied (java.io.FilePermission
G:\Program Files\javaapplets\testfile.txt read)
 	at java.security.AccessControlContext.checkPermission
(AccessControlContext.java:270)
 	at java.security.AccessController.checkPermission
(AccessController.java:401)
 	at java.lang.SecurityManager.checkPermission(SecurityManager.java:542)
 	at java.lang.SecurityManager.checkRead(SecurityManager.java:887)
 	at java.io.File.isDirectory(File.java:698)
 	at sun.net.www.protocol.file.FileURLConnection.connect
(FileURLConnection.java:65)
 	at sun.net.www.protocol.file.FileURLConnection.getInputStream
(FileURLConnection.java:148)
 	at java.net.URL.openStream(URL.java:955)
 	at TestOpenStream.start(TestOpenStream.java:14)
 	at sun.applet.AppletPanel.run(AppletPanel.java:355)
 	at java.lang.Thread.run(Thread.java:536)


This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Sample source code for the applet:

===============================================
import java.applet.*;
import java.net.*;
import java.io.*;

public class TestOpenStream extends Applet
{
	public void init() {}

	public void start()
	{
		try {
			URL url = new URL( getCodeBase(), "testfile.txt" );
			System.out.println( "url is: " + url.toString() );
			InputStream is = url.openStream();
			System.out.println( "InputStream is: " + is );
		} catch ( Exception e ) {
			System.out.println( "EXCEPTION CAUGHT!!" );
			e.printStackTrace();
		}
	}
}
========================================
The HTML page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Windows-1252">
<TITLE>Test</TITLE>
</HEAD>
<BODY>
<APPLET CODE="TestOpenStream" CODEBASE="."
	WIDTH="1" HEIGHT="1" NAME="Test" archive="Test.jar">
</APPLET>
</BODY>
</HTML>
=========================================
Jar command used to create Test.jar:

jar -cf Test.jar TestOpenStream.class

=========================================
The file called "testfile.txt" can be any file located in the codebase
directory.

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
A couple of workarounds found:

o Don't package the files into a JAR. Problem does not
appear to occur when just .class files are available.

o Change directory of installed applet to one without
spaces in the name.

o Access the HTML file using an HTTP URL. Problem only
occurs when file is accessed via a file URL.

o Use policytool to modify the java security file, giving
permission to the file being read (was suggested by another
user here with the problem; did not confirm myself).

Release Regression From : 1.3.1_03
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 146914) 
======================================================================

Name: gm110360			Date: 06/04/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

FULL OPERATING SYSTEM VERSION :Windows 2000 5.00.2195
Service Pack 2


A DESCRIPTION OF THE PROBLEM :
When running an applet and using the default toolkit's
getImage command, the Java plug-in (v1.4) cannot find the
image under a specific combination of circumstances. These
are:

1) The user is running the applet locally (i.e., launched a
web page stored on a local disk).

AND

2) The applet's class files are stored in an archive (in my
case, a ZIP file)

AND

3) The file path to the applet contains a space
(e.g., "C:/MyWeb/Test Applet/page.htm").

Under this combination of circumstances, the plug-in will
fail to find the image and will throw an Access Control
exception.

The code currently creating the problem works without issue
on the Microsoft JVM and on Sun JVMs prior to version 1.4.

REGRESSION.  Last worked in version 1.3

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Compile the enclosed source (Applet1.java)
2.Archive the resulting class file (Applet1.class ->
Applet1.zip).
3.Create a directory on a local disk whose path contains a
space (e.g., "C:/temp/imageURL test").
4. Place the archived file into the new directory.
5. Create a simple web page to run the applet (be sure to
specify archive=Applet1.zip in the <APPLET> tag).
6. Copy a gif titled "logo.gif" into the directory.
7. Launch the web page locally.


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expeced results: The applet should display the image.

Actual results: The Java plug-in throws an "Access Control"
exception and fails to load any image data.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.security.AccessControlException: access denied (java.io.FilePermission
\C:\temp\bugTest\failing case\logo.gif read)
	at java.security.AccessControlContext.checkPermission(Unknown Source)
	at java.security.AccessController.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkRead(Unknown Source)
	at sun.awt.SunToolkit.getImageFromHash(Unknown Source)
	at sun.awt.SunToolkit.getImage(Unknown Source)
	at Applet1.loadImage(Applet1.java:50)
	at Applet1.init(Applet1.java:20)
	at sun.applet.AppletPanel.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
// JAVA SOURCE //////////////////////////////////////////////////////
import java.awt.*;
import java.applet.*;
import java.net.*;

/**
 * This class reads PARAM tags from its HTML host page and sets
 * the color and label properties of the applet. Program execution
 * begins with the init() method.
 */
public class Applet1 extends Applet
{
	private Image image;
	
	/**
	 * The entry point for the applet.
	 */
	public void init()
	{
		initForm();
		this.loadImage();
		this.repaint();
	}

	/**
	 * Draw the applet.
	 */
	public void paint(Graphics gfx) {
		Rectangle bounds = this.getBounds();

		gfx.setColor(Color.black);
		gfx.fillRect(0, 0, bounds.width, bounds.height);
		gfx.drawImage(this.image, 0, 0, null);
	}
	
	/**
	 * Intializes values for the applet and its components
	 */
	void initForm()
	{
		this.setBackground(Color.lightGray);
		this.setForeground(Color.black);
	}
	
	private void loadImage() {
		URL imageURL = null;
		MediaTracker tracker;
		
        try {
			imageURL = new URL(this.getCodeBase(), "logo.gif");
			this.image = Toolkit.getDefaultToolkit().getImage
(imageURL);
                        
            try {
                tracker = new MediaTracker(this);
                tracker.addImage(this.image, 0);
                try {
                    tracker.waitForID(0);
                }
                catch (Exception e) {
                    System.out.print("Failed to track image.\n");
                }
            }
            catch (Exception e) {
                System.out.print("applet not yet initialized.\n");
            }
        }
        catch(Exception e) {
            System.out.print("Malformed URL.\n");
        }
	}
}


// HTML PAGE WHICH ALWAYS WORKS /////////////////////////////////////////////
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>

<P>&nbsp;</P>


<!-- Insert HTML here -->
	<applet
		code=Applet1.class
		name=Applet1
		width=320
		height=200 >
	</applet>

</BODY>
</HTML>

// HTML PAGE WHICH FAILS WHEN ITS PATH CONTAINS A SPACE /////////////////////
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>

<P>&nbsp;</P>


<!-- Insert HTML here -->
	<applet
                archive=Applet1.zip
		code=Applet1.class
		name=Applet1
		width=320
		height=200 >
	</applet>

</BODY>
</HTML>

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
The only current workaround involves *not* archiving the
class files or *not* placing the web page in a path that
contains spaces.
(Review ID: 147313)
======================================================================

                                    

Comments
SUGGESTED FIX


*** 29,38 ****
--- 29,39 ----
  import java.security.PrivilegedActionException;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  import sun.awt.AppContext;
  import sun.awt.SunToolkit;
+ import sun.net.www.ParseUtil;
  
  /**
   * This class defines the class loader for loading applet classes and
   * resources. It extends URLClassLoader to search the applet code base
   * for the class or resource after checking any loaded JAR files.


*** 177,186 ****
--- 178,188 ----
        URL url = codesource.getLocation();
  
        if (url.getProtocol().equals("file")) {
  
            String path = url.getFile().replace('/', File.separatorChar);
+           path = ParseUtil.decode(path);
  
            if (!path.endsWith(File.separator)) {
                int endIndex = path.lastIndexOf(File.separatorChar);
                if (endIndex != -1) {
                        path = path.substring(0, endIndex+1) + "-";


*** 200,209 ****
--- 202,213 ----
                }
            });
  
            if (base.getProtocol().equals("file")) {
                String bpath = base.getFile().replace('/', File.separatorChar);
+               bpath = ParseUtil.decode(bpath);
+ 
                if (bpath.endsWith(File.separator)) {
                    bpath += "-";
                }
                perms.add(new FilePermission(bpath, "read"));
            }
                                     
2004-06-11
EVALUATION

This bug should be addressed in hopper.

###@###.### 2002-06-06

###@###.### 2002-06-11
This is due to the special charactor for space. When we add the permission for the file to read, we still use "%20" instead of the real " " for the path, which cause the applet don't have the permission to read the file.

Solution: In src/share/classes/sun/applet/AppletClassLoader.java
	
call ParseUtil.decode(path) method before add the permission.

Dennis Gu
                                     
2004-06-11
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
1.4.0_03
hopper-rc

FIXED IN:
1.4.0_03
hopper-rc

INTEGRATED IN:
1.4.0_03
hopper-rc


                                     
2004-06-14



Hardware and Software, Engineered to Work Together