Skip to content

Commit f103e8b

Browse files
committed
[bugfix] Make sure Zip Method is correctly propagated across functions
1 parent 696112c commit f103e8b

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);
@@ -159,7 +164,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
159164
if (item instanceof Element element) {
160165
compressElement(os, element, useHierarchy, stripOffset, sbWriter);
161166
} else {
162-
compressFromUri(os, ((AnyURIValue) item).toURI(), useHierarchy, stripOffset, "", null, sbWriter);
167+
compressFromUri(os, ((AnyURIValue) item).toURI(), useHierarchy, stripOffset, ZipMethod.DEFLATE, null, sbWriter);
163168
}
164169
}
165170

@@ -176,7 +181,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
176181
}
177182
}
178183

179-
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
184+
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
180185
{
181186
try {
182187
if ("file".equals(uri.getScheme())) {
@@ -198,7 +203,7 @@ private void compressFromUri(final OutputStream os, final URI uri, final boolean
198203
// try for a collection
199204
try (final Collection collection = context.getBroker().openCollection(xmldburi, LockMode.READ_LOCK)) {
200205
if(collection != null) {
201-
compressCollection(os, collection, useHierarchy, stripOffset, sbWriter);
206+
compressCollection(os, collection, useHierarchy, stripOffset, method, sbWriter);
202207
return;
203208
}
204209
} catch (final PermissionDeniedException | LockException | SAXException | IOException pde) {
@@ -245,7 +250,7 @@ private void compressFromUri(final OutputStream os, final URI uri, final boolean
245250
* @param method the Zip method.
246251
* @param name the name of the entry.
247252
*/
248-
private void compressFile(final OutputStream os, final Path file, final boolean useHierarchy, final String stripOffset, final String method, final String name) throws IOException {
253+
private void compressFile(final OutputStream os, final Path file, final boolean useHierarchy, final String stripOffset, final ZipMethod method, final String name) throws IOException {
249254

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

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

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

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

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

@@ -368,8 +377,7 @@ private void compressElement(final OutputStream os, final Element element, final
368377
}
369378
}
370379

371-
if (entry instanceof ZipEntry &&
372-
"store".equals(element.getAttribute("method"))) {
380+
if (entry instanceof ZipEntry && method == ZipMethod.STORE) {
373381
((ZipEntry) entry).setMethod(ZipOutputStream.STORED);
374382
chksum.update(value);
375383
((ZipEntry) entry).setCrc(chksum.getValue());
@@ -415,7 +423,7 @@ private void getDynamicSerializerOptions(final Serializer serializer) throws SAX
415423
* @param name the name of the entry.
416424
* @param sbWriter a StringBuilderWriter to reuse
417425
*/
418-
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 {
426+
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 {
419427
// create an entry in the Tar for the document
420428
final Object entry;
421429
if (name != null) {
@@ -456,8 +464,7 @@ private void compressResource(final OutputStream os, final DocumentImpl doc, fin
456464

457465
// close the entry
458466
final CRC32 chksum = new CRC32();
459-
if (entry instanceof ZipEntry &&
460-
"store".equals(method)) {
467+
if (entry instanceof ZipEntry && method == ZipMethod.STORE) {
461468
((ZipEntry) entry).setMethod(ZipOutputStream.STORED);
462469
chksum.update(value);
463470
((ZipEntry) entry).setCrc(chksum.getValue());
@@ -476,18 +483,19 @@ private void compressResource(final OutputStream os, final DocumentImpl doc, fin
476483
* @param col The Collection to add to the archive.
477484
* @param useHierarchy Whether to use a folder hierarchy in the archive file that reflects the collection hierarchy.
478485
* @param stripOffset a string that should be stripped from the start of the entry name.
486+
* @param method the Zip method.
479487
* @param sbWriter a StringBuilderWriter to reuse
480488
*/
481-
private void compressCollection(final OutputStream os, final Collection col, final boolean useHierarchy, final String stripOffset, final StringBuilderWriter sbWriter) throws IOException, SAXException, LockException, PermissionDeniedException {
489+
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 {
482490
// iterate over child documents
483491
final DBBroker broker = context.getBroker();
484492
final LockManager lockManager = broker.getBrokerPool().getLockManager();
485493
final MutableDocumentSet childDocs = new DefaultDocumentSet();
486494
col.getDocuments(broker, childDocs);
487495
for (final Iterator<DocumentImpl> itChildDocs = childDocs.getDocumentIterator(); itChildDocs.hasNext();) {
488-
final DocumentImpl childDoc = itChildDocs.next();
496+
final DocumentImpl childDoc = itChildDocs.next();
489497
try (final ManagedDocumentLock updateLock = lockManager.acquireDocumentReadLock(childDoc.getURI())) {
490-
compressResource(os, childDoc, useHierarchy, stripOffset, "", null, sbWriter);
498+
compressResource(os, childDoc, useHierarchy, stripOffset, method, null, sbWriter);
491499
}
492500
}
493501
// iterate over child collections
@@ -496,7 +504,7 @@ private void compressCollection(final OutputStream os, final Collection col, fin
496504
final XmldbURI childColURI = itChildCols.next();
497505
final Collection childCol = broker.getCollection(col.getURI().append(childColURI));
498506
// recurse
499-
compressCollection(os, childCol, useHierarchy, stripOffset, sbWriter);
507+
compressCollection(os, childCol, useHierarchy, stripOffset, method, sbWriter);
500508
}
501509
}
502510

0 commit comments

Comments
 (0)