8000 Fixed Issue #122 Infinite loop by faltiska · Pull Request #124 · psiegman/epublib · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fixed Issue #122 Infinite loop #124

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

Merged
merged 3 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
*/
public class ResourcesLoader {
private static final Logger LOG = LoggerFactory.getLogger(ResourcesLoader.class);
private static final ZipEntry ERROR_ZIP_ENTRY = new ZipEntry("<error>");


/**
* Loads the entries of the zipFile as resources.
*
Expand Down Expand Up @@ -91,12 +90,6 @@ private static boolean shouldLoadLazy(String href, Collection<MediaType> lazilyL
return lazilyLoadedMediaTypes.contains(mediaType);
}


public static Resources loadResources(InputStream in, String defaultHtmlEncoding) throws IOException {
return loadResources(new ZipInputStream(in), defaultHtmlEncoding);
}


/**
* Loads all entries from the ZipInputStream as Resources.
*
Expand All @@ -114,7 +107,7 @@ public static Resources loadResources(ZipInputStream zipInputStream, String defa
do {
// get next valid zipEntry
zipEntry = getNextZipEntry(zipInputStream);
if((zipEntry == null) || (zipEntry == ERROR_ZIP_ENTRY) || zipEntry.isDirectory()) {
if((zipEntry == null) || zipEntry.isDirectory()) {
continue;
}

Expand All @@ -131,14 +124,16 @@ public static Resources loadResources(ZipInputStream zipInputStream, String defa


private static ZipEntry getNextZipEntry(ZipInputStream zipInputStream) throws IOException {
ZipEntry result = ERROR_ZIP_ENTRY;
try {
result = zipInputStream.getNextEntry();
return zipInputStream.getNextEntry();
} catch(ZipException e) {
LOG.error(e.getMessage());
zipInputStream.closeEntry();
//see <a href="https://github.com/psiegman/epublib/issues/122">Issue #122 Infinite loop</a>.
//when reading a file that is not a real zip archive or a zero length file, zipInputStream.getNextEntry()
//throws an exception and does not advance, so loadResources enters an infinite loop
LOG.error("Invalid or damaged zip file.", e);
try { zipInputStream.closeEntry(); } catch (Exception ignored) {}
throw e;
}
return result;
}

/**
Expand All @@ -147,7 10000 +142,7 @@ private static ZipEntry getNextZipEntry(ZipInputStream zipInputStream) throws IO
* Loads the contents of all ZipEntries into memory.
* Is fast, but may lead to memory problems when reading large books on devices with small amounts of memory.
*
* @param in
* @param zipFile
* @param defaultHtmlEncoding
* @return
* @throws IOException
Expand Down
Original file line number Diff line number Diff line change
@@ -1,94 +1,91 @@
package nl.siegmann.epublib.epub;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import net.sf.jazzlib.ZipException;
import net.sf.jazzlib.ZipFile;
import net.sf.jazzlib.ZipInputStream;
import nl.siegmann.epublib.domain.LazyResource;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.Resources;
import nl.siegmann.epublib.service.MediatypeService;
import nl.siegmann.epublib.util.IOUtil;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ResourcesLoaderTest {

private static final String encoding = "UTF-8";
private static String testBookFilename;

@BeforeClass
public static void setUpClass() throws IOException {
File testbook = File.createTempFile("testbook", ".epub");
OutputStream out = new FileOutputStream(testbook);
File testBook = File.createTempFile("testBook", ".epub");
OutputStream out = new FileOutputStream(testBook);
IOUtil.copy(ResourcesLoaderTest.class.getResourceAsStream("/testbook1.epub"), out);
out.close();

ResourcesLoaderTest.testBookFilename = testbook.getAbsolutePath();
ResourcesLoaderTest.testBookFilename = testBook.getAbsolutePath();
}

@AfterClass
public static void tearDownClass() {
//noinspection ResultOfMethodCallIgnored
new File(testBookFilename).delete();
}

/**
* Loads the Resource from an InputStream
*
* @throws FileNotFoundException
* @throws IOException
* Loads the Resources from a ZipInputStream
*/
@Test
public void testLoadResources_InputStream() throws FileNotFoundException, IOException {
public void testLoadResources_ZipInputStream() throws IOException {
// given
InputStream inputStream = new FileInputStream(new File(testBookFilename));
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(new File(testBookFilename)));

// when
Resources resources = ResourcesLoader.loadResources(inputStream, encoding);
Resources resources = ResourcesLoader.loadResources(zipInputStream, encoding);

// then
verifyResources(resources);
}

/**
* Loads the Resources from a ZipInputStream
*
* @throws FileNotFoundException
* @throws IOException
* Loads the Resources from a zero length file, using ZipInputStream<br/>
* See <a href="https://github.com/psiegman/epublib/issues/122">Issue #122 Infinite loop</a>.
*/
@Test
public void testLoadResources_ZipInputStream() throws FileNotFoundException, IOException {
@Test(expected = ZipException.class)
public void testLoadResources_ZipInputStream_WithZeroLengthFile() throws IOException {
// given
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(new File(testBookFilename)));
ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getResourceAsStream("/zero_length_file.epub"));

// when
Resources resources = ResourcesLoader.loadResources(zipInputStream, encoding);

// then
verifyResources(resources);
ResourcesLoader.loadResources(zipInputStream, encoding);
}

/**
* Loads the Resources from a file that is not a valid zip, using ZipInputStream<br/>
* See <a href="https://github.com/psiegman/epublib/issues/122">Issue #122 Infinite loop</a>.
*/
@Test(expected = ZipException.class)
public void testLoadResources_ZipInputStream_WithInvalidFile() throws IOException {
// given
ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getResourceAsStream("/not_a_zip.epub"));

// when
ResourcesLoader.loadResources(zipInputStream, encoding);
}

/**
* Loads the Resources from a ZipFile
*
* @throws FileNotFoundException
* @throws IOException
*/
@Test
public void testLoadResources_ZipFile() throws FileNotFoundException, IOException {
public void testLoadResources_ZipFile() throws IOException {
// given
ZipFile zipFile = new ZipFile(testBookFilename);

Expand All @@ -101,12 +98,9 @@ public void testLoadResources_ZipFile() throws FileNotFoundException, IOExceptio

/**
* Loads all Resources lazily from a ZipFile
*
* @throws FileNotFoundException
* @throws IOException
*/
@Test
public void testLoadResources_ZipFile_lazy_all() throws FileNotFoundException, IOException {
public void testLoadResources_ZipFile_lazy_all() throws IOException {
// given
ZipFile zipFile = new ZipFile(testBookFilename);

Expand All @@ -121,17 +115,14 @@ public void testLoadResources_ZipFile_lazy_all() throws FileNotFoundException, I

/**
* Loads the Resources from a ZipFile, some of them lazily.
*
* @throws FileNotFoundException
* @throws IOException
*/
@Test
public void testLoadResources_ZipFile_partial_lazy() throws FileNotFoundException, IOException {
public void testLoadResources_ZipFile_partial_lazy() throws IOException {
// given
ZipFile zipFile = new ZipFile(testBookFilename);

// when
Resources resources = ResourcesLoader.loadResources(zipFile, encoding, Arrays.asList(MediatypeService.CSS));
Resources resources = ResourcesLoader.loadResources(zipFile, encoding, Collections.singletonList(MediatypeService.CSS));

// then
verifyResources(resources);
Expand All @@ -143,7 +134,7 @@ public void testLoadResources_ZipFile_partial_lazy() throws FileNotFoundExceptio
private void verifyResources(Resources resources) throws IOException {
Assert.assertNotNull(resources);
Assert.assertEquals(12, resources.getAll().size());
List<String> allHrefs = new ArrayList<String>(resources.getAllHrefs());
List<String> allHrefs = new ArrayList<>(resources.getAllHrefs());
Collections.sort(allHrefs);

Resource resource;
Expand All @@ -163,7 +154,7 @@ private void verifyResources(Resources resources) throws IOException {
Assert.assertEquals(MediatypeService.CSS, resource.getMediaType());
Assert.assertEquals(65, resource.getData().length);
expectedData = IOUtil.toByteArray(this.getClass().getResourceAsStream("/book1/book1.css"));
Assert.assertTrue(Arrays.equals(expectedData, resource.getData()));
Assert.assertArrayEquals(expectedData, resource.getData());


// chapter1
Expand All @@ -173,6 +164,6 @@ private void verifyResources(Resources resources) throws IOException {
Assert.assertEquals(MediatypeService.XHTML, resource.getMediaType());
Assert.assertEquals(247, resource.getData().length);
expectedData = IOUtil.toByteArray(this.getClass().getResourceAsStream("/book1/chapter1.html"));
Assert.assertTrue(Arrays.equals(expectedData, resource.getData()));
Assert.assertArrayEquals(expectedData, resource.getData());
}
}
2 changes: 2 additions & 0 deletions epublib-core/src/test/resources/not_a_zip.epub
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This is not a valid zip file.
Used for testing LoadResources.
Empty file.
0