Skip to content
Snippets Groups Projects
Commit 6d1d6012 authored by srosse's avatar srosse
Browse files

OO-442: use jazzlib (don't break if an encoding issue happens) in the folder component

parent 69956be2
No related branches found
No related tags found
No related merge requests found
......@@ -1524,6 +1524,12 @@
<artifactId>json</artifactId>
<version>20080701</version>
</dependency>
<dependency>
<groupId>jazzlib</groupId>
<artifactId>jazzlib</artifactId>
<version>0.0.6</version> <!-- do not replace with 0.0.7 as this version is highly patched. -->
<classifier>patched</classifier>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
......
......@@ -146,7 +146,7 @@ public class CmdUnzip extends BasicController implements FolderCommand {
if(zipContainer == null) {
return Collections.emptyList();
} else if (zipContainer instanceof VFSContainer) {
return ZipUtil.checkLockedFileBeforeUnzip(vfsItem, (VFSContainer)zipContainer, identity, isAdmin);
return ZipUtil.checkLockedFileBeforeUnzipNonStrict(vfsItem, (VFSContainer)zipContainer, identity, isAdmin);
} else {
//replace a file with a folder ???
return Collections.emptyList();
......@@ -182,7 +182,7 @@ public class CmdUnzip extends BasicController implements FolderCommand {
}
}
if (!ZipUtil.unzip(vfsItem, zipContainer, ureq.getIdentity(), versioning)) {
if (!ZipUtil.unzipNonStrict(vfsItem, zipContainer, ureq.getIdentity(), versioning)) {
// operation failed - rollback
zipContainer.delete();
wControl.setError(translator.translate("failed"));
......
......@@ -232,6 +232,114 @@ public class ZipUtil {
return true;
} // unzip
/**
* Unzip a file to a directory using the versioning system of VFS and a ZIP
* library which handle encoding errors. It may results in special characters
* wrongly translated on the file system.
* @param zipLeaf The file to unzip
* @param targetDir The directory to unzip the file to
* @param the identity of who unzip the file
* @param versioning enabled or not
* @return True if successfull, false otherwise
*/
public static boolean unzipNonStrict(VFSLeaf zipLeaf, VFSContainer targetDir, Identity identity, boolean versioning) {
InputStream in = zipLeaf.getInputStream();
boolean unzipped = unzipNonStrict(in, targetDir, identity, versioning);
FileUtils.closeSafely(in);
return unzipped;
}
/**
* Unzip with jazzlib
* @param in
* @param targetDir
* @param identity
* @param versioning
* @return
*/
private static boolean unzipNonStrict(InputStream in, VFSContainer targetDir, Identity identity, boolean versioning) {
net.sf.jazzlib.ZipInputStream oZip = new net.sf.jazzlib.ZipInputStream(in);
try {
// unzip files
net.sf.jazzlib.ZipEntry oEntr = oZip.getNextEntry();
while (oEntr != null) {
if (oEntr.getName() != null && !oEntr.getName().startsWith(DIR_NAME__MACOSX)) {
if (oEntr.isDirectory()) {
// skip MacOSX specific metadata directory
// create directories
getAllSubdirs(targetDir, oEntr.getName(), identity, true);
} else {
// create file
VFSContainer createIn = targetDir;
String name = oEntr.getName();
// check if entry has directories which did not show up as
// directories above
int dirSepIndex = name.lastIndexOf('/');
if (dirSepIndex == -1) {
// try it windows style, backslash is also valid format
dirSepIndex = name.lastIndexOf('\\');
}
if (dirSepIndex > 0) {
// create subdirs
createIn = getAllSubdirs(targetDir, name.substring(0, dirSepIndex), identity, true);
if (createIn == null) {
if (log.isDebug()) log.debug("Error creating directory structure for zip entry: "
+ oEntr.getName());
return false;
}
name = name.substring(dirSepIndex + 1);
}
if(versioning) {
VFSLeaf newEntry = (VFSLeaf)createIn.resolve(name);
if(newEntry == null) {
newEntry = createIn.createChildLeaf(name);
OutputStream out = newEntry.getOutputStream(false);
if (!FileUtils.copy(oZip, out)) return false;
FileUtils.closeSafely(out);
} else if (newEntry instanceof Versionable) {
Versionable versionable = (Versionable)newEntry;
if(versionable.getVersions().isVersioned()) {
versionable.getVersions().addVersion(identity, "", oZip);
}
}
if(newEntry instanceof MetaTagged) {
MetaInfo info = ((MetaTagged)newEntry).getMetaInfo();
if(info != null) {
info.setAuthor(identity.getName());
info.write();
}
}
} else {
VFSLeaf newEntry = createIn.createChildLeaf(name);
if (newEntry != null) {
OutputStream out = newEntry.getOutputStream(false);
if (!FileUtils.copy(oZip, out)) return false;
FileUtils.closeSafely(out);
}
if(newEntry instanceof MetaTagged) {
MetaInfo info = ((MetaTagged)newEntry).getMetaInfo();
if(info != null && identity != null) {
info.setAuthor(identity.getName());
info.write();
}
}
}
}
}
oZip.closeEntry();
oEntr = oZip.getNextEntry();
}
} catch (IOException e) {
return false;
} finally {
FileUtils.closeSafely(oZip);
}
return true;
} // unzip
/**
* Check if a file in the zip is already in the path
* @param zipLeaf
......@@ -298,6 +406,73 @@ public class ZipUtil {
return lockedFiles;
}
/**
*
* @param zipLeaf
* @param targetDir
* @param identity
* @param isAdmin
* @return
*/
public static List<String> checkLockedFileBeforeUnzipNonStrict(VFSLeaf zipLeaf, VFSContainer targetDir, Identity identity, boolean isAdmin) {
List<String> lockedFiles = new ArrayList<String>();
InputStream in = zipLeaf.getInputStream();
net.sf.jazzlib.ZipInputStream oZip = new net.sf.jazzlib.ZipInputStream(in);
try {
// unzip files
net.sf.jazzlib.ZipEntry oEntr = oZip.getNextEntry();
while (oEntr != null) {
if (oEntr.getName() != null && !oEntr.getName().startsWith(DIR_NAME__MACOSX)) {
if (oEntr.isDirectory()) {
// skip MacOSX specific metadata directory
// directories aren't locked
oZip.closeEntry();
oEntr = oZip.getNextEntry();
continue;
} else {
// search file
VFSContainer createIn = targetDir;
String name = oEntr.getName();
// check if entry has directories which did not show up as
// directories above
int dirSepIndex = name.lastIndexOf('/');
if (dirSepIndex == -1) {
// try it windows style, backslash is also valid format
dirSepIndex = name.lastIndexOf('\\');
}
if (dirSepIndex > 0) {
// get subdirs
createIn = getAllSubdirs(targetDir, name.substring(0, dirSepIndex), identity, false);
if (createIn == null) {
//sub directories don't exist, and aren't locked
oZip.closeEntry();
oEntr = oZip.getNextEntry();
continue;
}
name = name.substring(dirSepIndex + 1);
}
VFSLeaf newEntry = (VFSLeaf)createIn.resolve(name);
if(MetaInfoHelper.isLocked(newEntry, identity, isAdmin)) {
lockedFiles.add(name);
}
}
}
oZip.closeEntry();
oEntr = oZip.getNextEntry();
}
} catch (IOException e) {
return null;
} finally {
FileUtils.closeSafely(oZip);
FileUtils.closeSafely(in);
}
return lockedFiles;
}
/**
* Get the whole subpath.
......
......@@ -30,7 +30,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.zip.ZipInputStream;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.meta.MetaInfo;
......@@ -166,8 +165,10 @@ public class VersionsFileManager extends VersionsManager implements Initializabl
VFSLeaf currentFile = (VFSLeaf) currentVersion;
if (addToRevisions(currentVersion, identity, comment)) {
// copy the content of the new file to the old
boolean closeInputStream = !(newFile instanceof ZipInputStream);
if (VFSManager.copyContent(newFile, currentFile, closeInputStream)) { return true; }
boolean closeInputStream = !(newFile instanceof net.sf.jazzlib.ZipInputStream || newFile instanceof java.util.zip.ZipInputStream);
if (VFSManager.copyContent(newFile, currentFile, closeInputStream)) {
return true;
}
} else {
log.error("Cannot create a version of this file: " + currentVersion);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment