IcedTea-Web icon indicating copy to clipboard operation
IcedTea-Web copied to clipboard

Writing to a file via CreateRestrictedFile/

Open shinalpala opened this issue 3 years ago • 1 comments

Writing to a file fails if the file does not already exist on Windows - not an issue on Linux. Here is the stack trace of the error I get when writing preferences to a non-existent file:

at com.sun.proxy.$Proxy7.saveFileDialog(Unknown Source)
at net.sourceforge.jnlp.services.ServiceUtil$PrivilegedHandler.invoke(ServiceUtil.java:206)
at java.security.AccessController.doPrivileged(Native Method)
at net.sourceforge.jnlp.services.ServiceUtil$PrivilegedHandler$1.run(ServiceUtil.java:201)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at net.sourceforge.jnlp.services.XFileSaveService.saveFileDialog(XFileSaveService.java:70)
at net.sourceforge.jnlp.services.XFileSaveService.writeToFile(XFileSaveService.java:120)
at net.adoptopenjdk.icedteaweb.io.FileUtils.createRestrictedFile(FileUtils.java:182)
at net.adoptopenjdk.icedteaweb.io.FileUtils.createRestrictedFile(FileUtils.java:345)

java.io.IOException: Cannot rename C:\Temp\ppp.temp to C:\Temp\ppp

One workaround is to create an empty text file first then write to it - the file MUST exist for it to be written to. This is not ideal.

Upon close inspection/debugging I found in method writeTofile in class XFileSaveService.class:

/**

Writes actual file to disk. */ private void writeToFile(InputStream stream, File file) throws IOException { if (!file.createNewFile()) { //file exists boolean replace = (JOptionPane.showConfirmDialog(null, file.getAbsolutePath() + " already exists.\n" + "Do you want to replace it?", "Warning - File Exists", JOptionPane.YES_NO_OPTION) == 0); if (!replace) return; } else

{ RestrictedFileUtils.createRestrictedFile(file); } if (file.canWrite())

{ FileOutputStream out = new FileOutputStream(file); byte[] b = new byte[256]; int read = 0; while ((read = stream.read(b)) > 0) out.write(b, 0, read); out.flush(); out.close(); } else

{ throw new IOException("Unable to open file for writing"); } } } This method uses !file.createNewFile() in an if to check if the file exists - this causes a file to be created such that when a rename attempt is made the file already exists so can not be created. A rewrite of the open source code is being attempted as a way to remedy this issue.

Is this an actual problem - has anyone else experienced this on Windows (or even linux). I took a copy of the writeToFile method and replaced the (!file.createNewFile()) with file.exists() and this sorted the problem out.

Please enlighten me.

Thanks, Shinal

shinalpala avatar Mar 09 '22 12:03 shinalpala

I am also experiencing this issue on Windows; Not sure whether this helps clarify:

the XFileSaveService implementation (of FileSaveService) method saveFileDialog calls writeToFile. writeToFile tests to see whether the chosen file already exists by trying to create it.

If the file creation works, RestrictedFileUtils.createRestrictedFile creates a temporary file and an attempt is made to rename the file to the just created file. This does not work if the file already exists (and the consequential exception prevents writeToFile from completing), presumably WinNTFileSystem_md.c Java_java_io_WinNTFileSystem_rename0 cannot rename to an existing file?

I would expect this to be simple to recreate and affect any attempt to use FileSaveService saveFileDialog in a windows environment.

Robert9y avatar Nov 15 '22 17:11 Robert9y