Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write.xlsx() creates an unlocked, accessible file before the password argument protects it #209

Open
Bysmuth opened this issue Aug 19, 2024 · 2 comments
Labels

Comments

@Bysmuth
Copy link

Bysmuth commented Aug 19, 2024

I wanted to write a password-protected .xlsx file without storing the password in my code. So, I called the write.xlsx() function, with the password argument set to the {rstudioapi} function askForPassword("Enter a password to protect this file:"). Run in RStudio, this prompts the user for a password, which then protects the file.

However, I had an OS window open to show the directory where the file was created, and noticed that the file was created – without password protection – at the same time that the password prompt was launched. Prior to entering a password at the prompt, the .xlsx file was unprotected and could be opened without a password. After a password was entered, the .xlsx file became locked and could only be opened with the password.

This can be easily recreated on a Mac running RStudio; e.g. by running these two lines of code...

data(mtcars)
write.xlsx(x=mtcars, file="cars.xlsx", password=askForPassword("Enter a password to protect this file:"))

...and then opening the file prior to completing the prompt.

I recognize that this may not be unintended behavior (or even avoidable behavior), and that in practice the lag between file creation and password protection (if a password is directly entered into a script) is likely to be so quick that it wouldn't matter. Just wanted to bring it to the devs' attention.

Hardware/software versions: Mac Sonoma 14.3.1, R version 4.2.3, RStudio version 2023.03.2+454, rstudioapi 0.15.0, xlsx 0.6.5

@colearendt
Copy link
Owner

Thanks so much for reporting this @Bysmuth ! I think you're exactly right. And as far as it looks... it looks like this is totally superfluous (we don't need to write it twice AFAICT).

xlsx/R/Workbook.R

Lines 114 to 136 in 4ed1d01

wb$write(fh)
# close the filehandle
.jcall(fh, "V", "close")
if ( !is.null(password) ) {
fs <- .jnew("org/apache/poi/poifs/filesystem/POIFSFileSystem")
encMode <- J("org/apache/poi/poifs/crypt/EncryptionMode", "valueOf", "agile")
info <- .jnew("org/apache/poi/poifs/crypt/EncryptionInfo", fs, encMode)
enc <- info$getEncryptor()
enc$confirmPassword(password)
access <- J("org.apache.poi.openxml4j.opc.PackageAccess", "valueOf", "READ_WRITE")
opc <- J("org.apache.poi.openxml4j.opc.OPCPackage", "open", jFile, access)
outputStream <- enc$getDataStream(fs)
opc$save(outputStream)
opc$close()
fos <- .jnew("java/io/FileOutputStream", nfile)
fs$writeFilesystem(fos)
fos$close()
}

@colearendt colearendt added the bug label Aug 27, 2024
@Bysmuth
Copy link
Author

Bysmuth commented Aug 27, 2024

Always nice when the fix looks like an easy one. Thanks for the quick reply, and for developing/maintaining this useful package!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants