Browse Source

fix ZipUtil bug

Looly 5 years ago
parent
commit
994a7a49bf

+ 2 - 0
CHANGELOG.md

@@ -13,12 +13,14 @@
 * 【crypto 】     增加判空(issue#1230@Github)
 * 【core   】     xml.setXmlStandalone(true)格式优化(pr#1234@Github)
 * 【core   】     AnnotationUtil增加setValue方法(pr#1250@Github)
+* 【core   】     ZipUtil增加get方法
 
 ### Bug修复
 * 【cron   】     修复CronTimer可能死循环的问题(issue#1224@Github)
 * 【core   】     修复Calculator.conversion单个数字越界问题(issue#1222@Github)
 * 【poi    】     修复ExcelUtil.getSaxReader使用非MarkSupport流报错问题(issue#1225@Github)
 * 【core   】     修复HexUtil.format问题(issue#I268XT@Gitee)
+* 【core   】     修复ZipUtil判断压缩文件是否位于压缩目录内的逻辑有误的问题(issue#1251@Github)
 
 -------------------------------------------------------------------------------------------------------------
 

+ 38 - 11
hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java

@@ -459,13 +459,12 @@ public class ZipUtil {
 	 * @throws IORuntimeException IO异常
 	 * @since 4.5.8
 	 */
-	@SuppressWarnings("unchecked")
 	public static File unzip(ZipFile zipFile, File outFile) throws IORuntimeException {
 		if(outFile.exists() && outFile.isFile()){
 			throw new UtilException("Target path [{}] exist!", outFile.getAbsolutePath());
 		}
 		try {
-			final Enumeration<ZipEntry> em = (Enumeration<ZipEntry>) zipFile.entries();
+			final Enumeration<? extends ZipEntry> em = zipFile.entries();
 			ZipEntry zipEntry;
 			File outItemFile;
 			while (em.hasMoreElements()) {
@@ -488,6 +487,40 @@ public class ZipUtil {
 	}
 
 	/**
+	 * 获取压缩包中的指定文件流
+	 * @param zipFile 压缩文件
+	 * @param path 需要提取文件的文件名或路径
+	 * @return 压缩文件流,如果未找到返回{@code null}
+	 * @since 5.5.2
+	 */
+	public static InputStream get(File zipFile, Charset charset, String path){
+		try {
+			return get(new ZipFile(zipFile, charset), path);
+		} catch (IOException e) {
+			throw new IORuntimeException(e);
+		}
+	}
+
+	/**
+	 * 获取压缩包中的指定文件流
+	 * @param zipFile 压缩文件
+	 * @param path 需要提取文件的文件名或路径
+	 * @return 压缩文件流,如果未找到返回{@code null}
+	 * @since 5.5.2
+	 */
+	public static InputStream get(ZipFile zipFile, String path){
+		final ZipEntry entry = zipFile.getEntry(path);
+		if(null != entry){
+			try {
+				return zipFile.getInputStream(entry);
+			} catch (IOException e) {
+				throw new IORuntimeException(e);
+			}
+		}
+		return null;
+	}
+
+	/**
 	 * 解压<br>
 	 * ZIP条目不使用高速缓冲。
 	 *
@@ -1024,15 +1057,9 @@ public class ZipUtil {
 				throw new UtilException(StrUtil.format("File [{}] not exist!", srcFile.getAbsolutePath()));
 			}
 
-			try {
-				final File parentFile = zipFile.getCanonicalFile().getParentFile();
-				// 压缩文件不能位于被压缩的目录内
-				if (srcFile.isDirectory() && parentFile.getCanonicalPath().contains(srcFile.getCanonicalPath())) {
-					throw new UtilException("Zip file path [{}] must not be the child directory of [{}] !", zipFile.getCanonicalPath(), srcFile.getCanonicalPath());
-				}
-
-			} catch (IOException e) {
-				throw new UtilException(e);
+			// 压缩文件不能位于被压缩的目录内
+			if(srcFile.isDirectory() && FileUtil.isSub(srcFile, zipFile.getParentFile())){
+				throw new UtilException("Zip file path [{}] must not be the child directory of [{}] !", zipFile.getPath(), srcFile.getPath());
 			}
 		}
 	}

+ 7 - 0
hutool-core/src/test/java/cn/hutool/core/io/FileUtilTest.java

@@ -377,4 +377,11 @@ public class FileUtilTest {
 		String mimeType = FileUtil.getMimeType("test2Write.jpg");
 		Assert.assertEquals("image/jpeg", mimeType);
 	}
+
+	@Test
+	public void isSubTest() {
+		File file = new File("d:/test");
+		File file2 = new File("d:/test2/aaa");
+		Assert.assertFalse(FileUtil.isSub(file, file2));
+	}
 }

+ 1 - 2
hutool-extra/src/main/java/cn/hutool/extra/ssh/JschUtil.java

@@ -446,8 +446,7 @@ public class JschUtil {
 	/**
 	 * 执行Shell命令
 	 * <p>
-	 * 此方法单次发送一个命令到服务端,自动读取环境变量,执行结束后自动关闭channel,不会产生阻塞。<br>
-	 * 此方法返回数据中可能
+	 * 此方法单次发送一个命令到服务端,自动读取环境变量,执行结束后自动关闭channel,不会产生阻塞。
 	 * </p>
 	 *
 	 * @param session Session会话

+ 11 - 4
hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java

@@ -20,7 +20,7 @@ public class JSONUtilTest {
 	 * 出现语法错误时报错,检查解析\x字符时是否会导致死循环异常
 	 */
 	@Test(expected = JSONException.class)
-	public void parseTest(){
+	public void parseTest() {
 		JSONArray jsonArray = JSONUtil.parseArray("[{\"a\":\"a\\x]");
 		Console.log(jsonArray);
 	}
@@ -29,7 +29,7 @@ public class JSONUtilTest {
 	 * 数字解析为JSONArray报错
 	 */
 	@Test(expected = JSONException.class)
-	public void parseNumberTest(){
+	public void parseNumberTest() {
 		JSONArray json = JSONUtil.parseArray(123L);
 		Console.log(json);
 	}
@@ -38,7 +38,7 @@ public class JSONUtilTest {
 	 * 数字解析为JSONObject忽略
 	 */
 	@Test
-	public void parseNumberTest2(){
+	public void parseNumberTest2() {
 		JSONObject json = JSONUtil.parseObj(123L);
 		Assert.assertEquals(new JSONObject(), json);
 	}
@@ -156,11 +156,18 @@ public class JSONUtilTest {
 	}
 
 	@Test
-	public void doubleTest(){
+	public void doubleTest() {
 		String json = "{\"test\": 12.00}";
 		final JSONObject jsonObject = JSONUtil.parseObj(json);
 		//noinspection BigDecimalMethodWithoutRoundingCalled
 		Assert.assertEquals("12.00", jsonObject.getBigDecimal("test").setScale(2).toString());
 	}
+
+	@Test
+	public void parseObjTest() {
+		final JSONObject jsonObject = JSONUtil.parseObj("{\n" +
+				"    \"test\": \"\\\\地库地库\",\n" +
+				"}");
+	}
 }