diff --git a/skel_common/readme_changelog.txt b/skel_common/readme_changelog.txt index cd16d35..b3e51b5 100644 --- a/skel_common/readme_changelog.txt +++ b/skel_common/readme_changelog.txt @@ -5,6 +5,8 @@ Changelog - Added a Validate warning for text files with LF line endings - Fixed data loss when decoding Windows-1252 text with accented characters - Changed catalog auto-update url from GMM's repository to SMM's +- Added tolerance for non-standard zips containing backslash paths +- Added a Validate warning for non-standard zips containing backslash paths 1.0: - Changed mod list to a table with checkboxes diff --git a/src/main/java/net/vhati/ftldat/FTLDat.java b/src/main/java/net/vhati/ftldat/FTLDat.java index 9367395..cb2eef8 100644 --- a/src/main/java/net/vhati/ftldat/FTLDat.java +++ b/src/main/java/net/vhati/ftldat/FTLDat.java @@ -414,6 +414,7 @@ public class FTLDat { * The location it represents is not guaranteed to exist. */ public File getFile( String innerPath ) { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); return new File( rootDir, innerPath ); } } @@ -672,6 +673,7 @@ public class FTLDat { @Override public void add( String innerPath, InputStream is ) throws IOException { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); if ( pathToIndexMap.containsKey( innerPath ) ) { throw new IOException( "InnerPath already exists: "+ innerPath ); } @@ -716,6 +718,7 @@ public class FTLDat { @Override public void extractTo( String innerPath, OutputStream os ) throws FileNotFoundException, IOException { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); if ( !pathToIndexMap.containsKey( innerPath ) ) { throw new FileNotFoundException( "InnerPath does not exist: "+ innerPath ); } @@ -741,6 +744,7 @@ public class FTLDat { @Override public void remove( String innerPath ) throws FileNotFoundException, IOException { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); if ( !pathToIndexMap.containsKey( innerPath ) ) { throw new FileNotFoundException( "InnerPath does not exist: "+ innerPath ); } @@ -760,11 +764,13 @@ public class FTLDat { @Override public boolean contains( String innerPath ) { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); return pathToIndexMap.containsKey( innerPath ); } @Override public InputStream getInputStream( String innerPath ) throws FileNotFoundException, IOException { + if ( innerPath.indexOf("\\") != -1 ) throw new IllegalArgumentException( "InnerPath contains backslashes: "+ innerPath ); if ( !pathToIndexMap.containsKey( innerPath ) ) { throw new FileNotFoundException( "InnerPath does not exist: "+ innerPath ); } diff --git a/src/main/java/net/vhati/modmanager/core/ModPatchThread.java b/src/main/java/net/vhati/modmanager/core/ModPatchThread.java index 4940364..b136cc9 100644 --- a/src/main/java/net/vhati/modmanager/core/ModPatchThread.java +++ b/src/main/java/net/vhati/modmanager/core/ModPatchThread.java @@ -190,9 +190,12 @@ public class ModPatchThread extends Thread { while ( (item = zis.getNextEntry()) != null ) { if ( item.isDirectory() ) continue; - Matcher m = pathPtn.matcher( item.getName() ); + String innerPath = item.getName(); + innerPath = innerPath.replace( '\\', '/' ); // Non-standard zips. + + Matcher m = pathPtn.matcher( innerPath ); if ( !m.matches() ) { - log.warn( String.format( "Unexpected innerPath: %s", item.getName() ) ); + log.warn( String.format( "Unexpected innerPath: %s", innerPath ) ); zis.closeEntry(); continue; } @@ -203,13 +206,13 @@ public class ModPatchThread extends Thread { AbstractPack ftlP = topFolderMap.get( topFolder ); if ( ftlP == null ) { - log.warn( String.format( "Unexpected innerPath: %s", item.getName() ) ); + log.warn( String.format( "Unexpected innerPath: %s", innerPath ) ); zis.closeEntry(); continue; } if ( fileName.endsWith( ".xml.append" ) || fileName.endsWith( ".append.xml" ) ) { - String innerPath = parentPath + fileName.replaceAll( "[.](?:xml[.]append|append[.]xml)$", ".xml" ); + innerPath = parentPath + fileName.replaceAll( "[.](?:xml[.]append|append[.]xml)$", ".xml" ); innerPath = checkCase( innerPath, knownPaths, knownPathsLower ); if ( !ftlP.contains( innerPath ) ) { @@ -234,7 +237,7 @@ public class ModPatchThread extends Thread { } } else if ( fileName.endsWith( ".xml" ) || fileName.endsWith( ".txt" ) ) { - String innerPath = checkCase( item.getName(), knownPaths, knownPathsLower ); + innerPath = checkCase( innerPath, knownPaths, knownPathsLower ); // Normalize line endings for other text files to CR-LF. InputStream fixedStream = ModUtilities.setLineEndings( zis, "\r\n", modFile.getName()+":"+parentPath+fileName ); @@ -249,7 +252,7 @@ public class ModPatchThread extends Thread { ftlP.add( innerPath, fixedStream ); } else { - String innerPath = checkCase( item.getName(), knownPaths, knownPathsLower ); + innerPath = checkCase( innerPath, knownPaths, knownPathsLower ); if ( !moddedItems.contains(innerPath) ) moddedItems.add( innerPath ); diff --git a/src/main/java/net/vhati/modmanager/core/ModUtilities.java b/src/main/java/net/vhati/modmanager/core/ModUtilities.java index 45d9c15..672fd96 100644 --- a/src/main/java/net/vhati/modmanager/core/ModUtilities.java +++ b/src/main/java/net/vhati/modmanager/core/ModUtilities.java @@ -223,6 +223,15 @@ public class ModUtilities { String innerPath = item.getName(); pendingMsgs.clear(); + if ( innerPath.indexOf( "\\" ) != -1 ) { + pendingMsgs.add( new ReportMessage( + ReportMessage.ERROR, + String.format( "Backslashes in path. (Non-standard zip archive)" ) + ) ); + modValid = false; + innerPath = innerPath.replace( '\\', '/' ); + } + if ( !asciiEncoder.canEncode( innerPath ) ) { pendingMsgs.add( new ReportMessage( ReportMessage.ERROR, @@ -379,9 +388,10 @@ public class ModUtilities { } if ( !pendingMsgs.isEmpty() ) { + // Prepend the original path. messages.add( new ReportMessage( ReportMessage.SUBSECTION, - innerPath + item.getName() ) ); messages.addAll( pendingMsgs ); }