aboutsummaryrefslogtreecommitdiff
blob: 16ea5c192703a24d8dd17b130fd482d1cc463d51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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