Skip to content

Commit 542ea61

Browse files
committed
[bugfix] Make sure Zip Method is correctly propagated across functions
1 parent b1b14f6 commit 542ea61

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

extensions/modules/compression/src/main/java/org/exist/xquery/modules/compression/AbstractCompressFunction.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public abstract class AbstractCompressFunction extends BasicFunction
104104
protected final static SequenceType STRIP_PREFIX_PARAM = new FunctionParameterSequenceType("strip-prefix", Type.STRING, Cardinality.EXACTLY_ONE, "This prefix is stripped from the Entrys name");
105105
protected final static SequenceType ENCODING_PARAM = new FunctionParameterSequenceType("encoding", Type.STRING, Cardinality.EXACTLY_ONE, "This encoding to be used for filenames inside the compressed file");
106106

107+
private enum ZipMethod {
108+
DEFLATE,
109+
STORE
110+
}
111+
107112

108113
public AbstractCompressFunction(final XQueryContext context, final FunctionSignature signature) {
109114
super(context, signature);
@@ -160,7 +165,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
160165
Element element = (Element) item;
161166
compressElement(os, element, useHierarchy, stripOffset, sbWriter);
162167
} else {
163-
compressFromUri(os, ((AnyURIValue) item).toURI(), useHierarchy, stripOffset, "", null, sbWriter);
168+
compressFromUri(os, ((AnyURIValue) item).toURI(), useHierarchy, stripOffset, ZipMethod.DEFLATE, null, sbWriter);
164169
}
165170
}
166171

@@ -177,7 +182,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
177182
}
178183
}
179184

180-
private void compressFromUri(final OutputStream os, final URI uri, final boolean useHierarchy, final String stripOffset, final String method, final String resourceName, final StringBuilderWriter sbWriter) throws XPathException
185+
private void compressFromUri(final OutputStream os, final URI uri, final boolean useHierarchy, final String stripOffset, final ZipMethod method, final String resourceName, final StringBuilderWriter sbWriter) throws XPathException
181186
{
182187
try {
183188
if ("file".equals(uri.getScheme())) {
@@ -199,7 +204,7 @@ private void compressFromUri(final OutputStream os, final URI uri, final boolean
199204
// try for a collection
200205
try (final Collection collection = context.getBroker().openCollection(xmldburi, LockMode.READ_LOCK)) {
201206
if(collection != null) {
202-
compressCollection(os, collection, useHierarchy, stripOffset, sbWriter);
207+
compressCollection(os, collection, useHierarchy, stripOffset, method, sbWriter);
203208
return;
204209
}
205210
} catch (final PermissionDeniedException | LockException | SAXException | IOException pde) {
@@ -246,7 +251,7 @@ private void compressFromUri(final OutputStream os, final URI uri, final boolean
246251
* @param method the Zip method.
247252
* @param name the name of the entry.
248253
*/
249-
private void compressFile(final OutputStream os, final Path file, final boolean useHierarchy, final String stripOffset, final String method, final String name) throws IOException {
254+
private void compressFile(final OutputStream os, final Path file, final boolean useHierarchy, final String stripOffset, final ZipMethod method, final String name) throws IOException {
250255

251256
if (!Files.isDirectory(file)) {
252257

@@ -263,9 +268,7 @@ private void compressFile(final OutputStream os, final Path file, final boolean
263268
final byte[] value = Files.readAllBytes(file);
264269

265270
// close the entry
266-
final CRC32 chksum = new CRC32();
267-
if (entry instanceof ZipEntry &&
268-
"store".equals(method)) {
271+
if (entry instanceof ZipEntry && method == ZipMethod.STORE) {
269272
((ZipEntry) entry).setMethod(ZipOutputStream.STORED);
270273
chksum.update(value);
271274
((ZipEntry) entry).setCrc(chksum.getValue());
@@ -312,13 +315,19 @@ private void compressElement(final OutputStream os, final Element element, final
312315
// throw new XPathException(this, "Entry must have name attribute.");
313316

314317
final String type = element.getAttribute("type");
318+
ZipMethod method;
319+
try {
320+
method = ZipMethod.valueOf(element.getAttribute("method").toUpperCase());
321+
} catch (final IllegalArgumentException e) {
322+
method = ZipMethod.DEFLATE;
323+
}
315324

316325
if ("uri".equals(type)) {
317326
@Nullable final String uri = element.getFirstChild().getNodeValue();
318327
if (isNullOrEmpty(uri)) {
319328
throw new XPathException(this, "Entry with type uri must contain a URI.");
320329
}
321-
compressFromUri(os, URI.create(uri), useHierarchy, stripOffset, element.getAttribute("method"), name, sbWriter);
330+
compressFromUri(os, URI.create(uri), useHierarchy, stripOffset, method, name, sbWriter);
322331
return;
323332
}
324333

@@ -369,8 +378,7 @@ private void compressElement(final OutputStream os, final Element element, final
369378
}
370379
}
371380

372-
if (entry instanceof ZipEntry &&
373-
"store".equals(element.getAttribute("method"))) {
381+
if (entry instanceof ZipEntry && method == ZipMethod.STORE) {
374382
((ZipEntry) entry).setMethod(ZipOutputStream.STORED);
375383
chksum.update(value);
376384
((ZipEntry) entry).setCrc(chksum.getValue());
@@ -416,7 +424,7 @@ private void getDynamicSerializerOptions(final Serializer serializer) throws SAX
416424
* @param name the name of the entry.
417425
* @param sbWriter a StringBuilderWriter to reuse
418426
*/
419-
private void compressResource(final OutputStream os, final DocumentImpl doc, final boolean useHierarchy, final String stripOffset, final String method, final String name, final StringBuilderWriter sbWriter) throws IOException, SAXException {
427+
private void compressResource(final OutputStream os, final DocumentImpl doc, final boolean useHierarchy, final String stripOffset, final ZipMethod method, final String name, final StringBuilderWriter sbWriter) throws IOException, SAXException {
420428
// create an entry in the Tar for the document
421429
final Object entry;
422430
if (name != null) {
@@ -457,8 +465,7 @@ private void compressResource(final OutputStream os, final DocumentImpl doc, fin
457465

458466
// close the entry
459467
final CRC32 chksum = new CRC32();
460-
if (entry instanceof ZipEntry &&
461-
"store".equals(method)) {
468+
if (entry instanceof ZipEntry && method == ZipMethod.STORE) {
462469
((ZipEntry) entry).setMethod(ZipOutputStream.STORED);
463470
chksum.update(value);
464471
((ZipEntry) entry).setCrc(chksum.getValue());
@@ -477,18 +484,19 @@ private void compressResource(final OutputStream os, final DocumentImpl doc, fin
477484
* @param col The Collection to add to the archive.
478485
* @param useHierarchy Whether to use a folder hierarchy in the archive file that reflects the collection hierarchy.
479486
* @param stripOffset a string that should be stripped from the start of the entry name.
487+
* @param method the Zip method.
480488
* @param sbWriter a StringBuilderWriter to reuse
481489
*/
482-
private void compressCollection(final OutputStream os, final Collection col, final boolean useHierarchy, final String stripOffset, final StringBuilderWriter sbWriter) throws IOException, SAXException, LockException, PermissionDeniedException {
490+
private void compressCollection(final OutputStream os, final Collection col, final boolean useHierarchy, final String stripOffset, final ZipMethod method, final StringBuilderWriter sbWriter) throws IOException, SAXException, LockException, PermissionDeniedException {
483491
// iterate over child documents
484492
final DBBroker broker = context.getBroker();
485493
final LockManager lockManager = broker.getBrokerPool().getLockManager();
486494
final MutableDocumentSet childDocs = new DefaultDocumentSet();
487495
col.getDocuments(broker, childDocs);
488496
for (final Iterator<DocumentImpl> itChildDocs = childDocs.getDocumentIterator(); itChildDocs.hasNext();) {
489-
final DocumentImpl childDoc = itChildDocs.next();
497+
final DocumentImpl childDoc = itChildDocs.next();
490498
try (final ManagedDocumentLock updateLock = lockManager.acquireDocumentReadLock(childDoc.getURI())) {
491-
compressResource(os, childDoc, useHierarchy, stripOffset, "", null, sbWriter);
499+
compressResource(os, childDoc, useHierarchy, stripOffset, method, null, sbWriter);
492500
}
493501
}
494502
// iterate over child collections
@@ -497,7 +505,7 @@ private void compressCollection(final OutputStream os, final Collection col, fin
497505
final XmldbURI childColURI = itChildCols.next();
498506
final Collection childCol = broker.getCollection(col.getURI().append(childColURI));
499507
// recurse
500-
compressCollection(os, childCol, useHierarchy, stripOffset, sbWriter);
508+
compressCollection(os, childCol, useHierarchy, stripOffset, method, sbWriter);
501509
}
502510
}
503511

0 commit comments

Comments
 (0)