| From 63588f476f2dc89d4c6ef70a474d7230fbf4d45e Mon Sep 17 00:00:00 2001 |
| From: Daniel Veillard <veillard@redhat.com> |
| Date: Fri, 10 May 2013 14:01:46 +0800 |
| Subject: [PATCH] Fix a regression in xmlGetDocCompressMode() |
| |
| The switch to xzlib had for consequence that the compression |
| level of the input was not gathered anymore in ctxt->input->buf, |
| then the parser compression flags was left to -1 and propagated |
| to the resulting document. |
| Fix the I/O layer to get compression detection in xzlib, |
| then carry it in the input buffer and the resulting document |
| |
| This should fix |
| https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=3456 |
| --- |
| parser.c | 4 ++++ |
| xmlIO.c | 17 +++++++++++++++++ |
| xzlib.c | 25 +++++++++++++++++++++++++ |
| xzlib.h | 1 + |
| 4 files changed, 47 insertions(+) |
| |
| diff --git a/parser.c b/parser.c |
| index 1d478c3..4a442bb 100644 |
| --- a/parser.c |
| +++ b/parser.c |
| @@ -10681,6 +10681,10 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) { |
| ctxt->sax->startDocument(ctxt->userData); |
| if (ctxt->instate == XML_PARSER_EOF) |
| return(-1); |
| + if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) && |
| + (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) { |
| + ctxt->myDoc->compression = ctxt->input->buf->compressed; |
| + } |
| |
| /* |
| * The Misc part of the Prolog |
| diff --git a/xmlIO.c b/xmlIO.c |
| index 847cb7e..fc4e111 100644 |
| --- a/xmlIO.c |
| +++ b/xmlIO.c |
| @@ -2669,6 +2669,12 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { |
| #endif |
| } |
| #endif |
| +#ifdef HAVE_LZMA_H |
| + if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) && |
| + (strcmp(URI, "-") != 0)) { |
| + ret->compressed = __libxml2_xzcompressed(context); |
| + } |
| +#endif |
| } |
| else |
| xmlInputCallbackTable[i].closecallback (context); |
| @@ -3325,6 +3331,17 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { |
| if (res < 0) { |
| return(-1); |
| } |
| + |
| + /* |
| + * try to establish compressed status of input if not done already |
| + */ |
| + if (in->compressed == -1) { |
| +#ifdef HAVE_LZMA_H |
| + if (in->readcallback == xmlXzfileRead) |
| + in->compressed = __libxml2_xzcompressed(in->context); |
| +#endif |
| + } |
| + |
| len = res; |
| if (in->encoder != NULL) { |
| unsigned int use; |
| diff --git a/xzlib.c b/xzlib.c |
| index 928bd17..150e803 100644 |
| --- a/xzlib.c |
| +++ b/xzlib.c |
| @@ -182,12 +182,37 @@ xz_open(const char *path, int fd, const char *mode ATTRIBUTE_UNUSED) |
| return (xzFile) state; |
| } |
| |
| +static int |
| +xz_compressed(xzFile f) { |
| + xz_statep state; |
| + |
| + if (f == NULL) |
| + return(-1); |
| + state = (xz_statep) f; |
| + if (state->init <= 0) |
| + return(-1); |
| + |
| + switch (state->how) { |
| + case COPY: |
| + return(0); |
| + case GZIP: |
| + case LZMA: |
| + return(1); |
| + } |
| + return(-1); |
| +} |
| + |
| xzFile |
| __libxml2_xzopen(const char *path, const char *mode) |
| { |
| return xz_open(path, -1, mode); |
| } |
| |
| +int |
| +__libxml2_xzcompressed(xzFile f) { |
| + return xz_compressed(f); |
| +} |
| + |
| xzFile |
| __libxml2_xzdopen(int fd, const char *mode) |
| { |
| diff --git a/xzlib.h b/xzlib.h |
| index 43c75e1..29ba55e 100644 |
| --- a/xzlib.h |
| +++ b/xzlib.h |
| @@ -15,4 +15,5 @@ xzFile __libxml2_xzopen(const char *path, const char *mode); |
| xzFile __libxml2_xzdopen(int fd, const char *mode); |
| int __libxml2_xzread(xzFile file, void *buf, unsigned len); |
| int __libxml2_xzclose(xzFile file); |
| +int __libxml2_xzcompressed(xzFile f); |
| #endif /* LIBXML2_XZLIB_H */ |
| -- |
| 1.8.3.2 |
| |