1 The contents of this patch taken directly from upstream: |
|
2 http://git.gnome.org/browse/libxml2/commit/?id=f5048b3e71fc30ad096970b8df6e7af073bae4cb |
|
3 via copy/paste of the code changes into the source files from which I generated new |
|
4 patch diffs. This explains the error of the missing 3 lines that are concatenated |
|
5 to the bottom of this patch. |
|
6 --- libxml2-2.7.6/xpath.c Wed Nov 30 08:31:34 2011 |
|
7 +++ libxml2-2.7.6/new.xpath.c Wed Nov 30 08:30:31 2011 |
|
8 @@ -252,6 +252,7 @@ |
|
9 "Encoding error\n", |
|
10 "Char out of XML range\n", |
|
11 "Invalid or incomplete context\n", |
|
12 + "Stack usage error\n", |
|
13 "?? Unknown error ??\n" /* Must be last in the list! */ |
|
14 }; |
|
15 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \ |
|
16 @@ -2398,6 +2399,42 @@ |
|
17 ************************************************************************/ |
|
18 |
|
19 /** |
|
20 + * xmlXPathSetFrame: |
|
21 + * @ctxt: an XPath parser context |
|
22 + * |
|
23 + * Set the callee evaluation frame |
|
24 + * |
|
25 + * Returns the previous frame value to be restored once done |
|
26 + */ |
|
27 +static int |
|
28 +xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) { |
|
29 + int ret; |
|
30 + |
|
31 + if (ctxt == NULL) |
|
32 + return(0); |
|
33 + ret = ctxt->valueFrame; |
|
34 + ctxt->valueFrame = ctxt->valueNr; |
|
35 + return(ret); |
|
36 +} |
|
37 + |
|
38 +/** |
|
39 + * xmlXPathPopFrame: |
|
40 + * @ctxt: an XPath parser context |
|
41 + * @frame: the previous frame value |
|
42 + * |
|
43 + * Remove the callee evaluation frame |
|
44 + */ |
|
45 +static void |
|
46 +xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) { |
|
47 + if (ctxt == NULL) |
|
48 + return; |
|
49 + if (ctxt->valueNr < ctxt->valueFrame) { |
|
50 + xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); |
|
51 + } |
|
52 + ctxt->valueFrame = frame; |
|
53 +} |
|
54 + |
|
55 +/** |
|
56 * valuePop: |
|
57 * @ctxt: an XPath evaluation context |
|
58 * |
|
59 @@ -2412,6 +2449,12 @@ |
|
60 |
|
61 if ((ctxt == NULL) || (ctxt->valueNr <= 0)) |
|
62 return (NULL); |
|
63 + |
|
64 + if (ctxt->valueNr <= ctxt->valueFrame) { |
|
65 + xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); |
|
66 + return (NULL); |
|
67 + } |
|
68 + |
|
69 ctxt->valueNr--; |
|
70 if (ctxt->valueNr > 0) |
|
71 ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; |
|
72 @@ -6154,6 +6197,7 @@ |
|
73 ret->valueNr = 0; |
|
74 ret->valueMax = 10; |
|
75 ret->value = NULL; |
|
76 + ret->valueFrame = 0; |
|
77 |
|
78 ret->context = ctxt; |
|
79 ret->comp = comp; |
|
80 @@ -11688,6 +11732,7 @@ |
|
81 xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; |
|
82 xmlNodePtr oldContextNode, contextNode = NULL; |
|
83 xmlXPathContextPtr xpctxt = ctxt->context; |
|
84 + int frame; |
|
85 |
|
86 #ifdef LIBXML_XPTR_ENABLED |
|
87 /* |
|
88 @@ -11707,6 +11752,8 @@ |
|
89 */ |
|
90 exprOp = &ctxt->comp->steps[op->ch2]; |
|
91 for (i = 0; i < set->nodeNr; i++) { |
|
92 + xmlXPathObjectPtr tmp; |
|
93 + |
|
94 if (set->nodeTab[i] == NULL) |
|
95 continue; |
|
96 |
|
97 @@ -11738,19 +11785,18 @@ |
|
98 res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); |
|
99 |
|
100 if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { |
|
101 - xmlXPathObjectPtr tmp; |
|
102 - /* pop the result if any */ |
|
103 - tmp = valuePop(ctxt); |
|
104 - if (tmp != contextObj) { |
|
105 + while (tmp != contextObj) { |
|
106 /* |
|
107 * Free up the result |
|
108 * then pop off contextObj, which will be freed later |
|
109 */ |
|
110 xmlXPathReleaseObject(xpctxt, tmp); |
|
111 - valuePop(ctxt); |
|
112 + tmp = valuePop(ctxt); |
|
113 } |
|
114 goto evaluation_error; |
|
115 } |
|
116 + /* push the result back onto the stack */ |
|
117 + valuePush(ctxt, tmp); |
|
118 |
|
119 if (res) |
|
120 pos++; |
|
121 @@ -13354,7 +13400,9 @@ |
|
122 xmlXPathFunction func; |
|
123 const xmlChar *oldFunc, *oldFuncURI; |
|
124 int i; |
|
125 + int frame; |
|
126 |
|
127 + frame = xmlXPathSetFrame(ctxt); |
|
128 if (op->ch1 != -1) |
|
129 total += |
|
130 xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); |
|
131 @@ -13362,15 +13410,18 @@ |
|
132 xmlGenericError(xmlGenericErrorContext, |
|
133 "xmlXPathCompOpEval: parameter error\n"); |
|
134 ctxt->error = XPATH_INVALID_OPERAND; |
|
135 + xmlXPathPopFrame(ctxt, frame); |
|
136 return (total); |
|
137 } |
|
138 - for (i = 0; i < op->value; i++) |
|
139 + for (i = 0; i < op->value; i++) { |
|
140 if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { |
|
141 xmlGenericError(xmlGenericErrorContext, |
|
142 "xmlXPathCompOpEval: parameter error\n"); |
|
143 ctxt->error = XPATH_INVALID_OPERAND; |
|
144 + xmlXPathPopFrame(ctxt, frame); |
|
145 return (total); |
|
146 } |
|
147 + } |
|
148 if (op->cache != NULL) |
|
149 XML_CAST_FPTR(func) = op->cache; |
|
150 else { |
|
151 @@ -13386,6 +13437,7 @@ |
|
152 xmlGenericError(xmlGenericErrorContext, |
|
153 "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", |
|
154 (char *)op->value4, (char *)op->value5); |
|
155 + xmlXPathPopFrame(ctxt, frame); |
|
156 return (total); |
|
157 } |
|
158 func = xmlXPathFunctionLookupNS(ctxt->context, |
|
159 @@ -13407,6 +13459,7 @@ |
|
160 func(ctxt, op->value); |
|
161 ctxt->context->function = oldFunc; |
|
162 ctxt->context->functionURI = oldFuncURI; |
|
163 + xmlXPathPopFrame(ctxt, frame); |
|
164 return (total); |
|
165 } |
|
166 case XPATH_OP_ARG: |
|
167 @@ -14310,6 +14363,7 @@ |
|
168 ctxt->valueNr = 0; |
|
169 ctxt->valueMax = 10; |
|
170 ctxt->value = NULL; |
|
171 + ctxt->valueFrame = 0; |
|
172 } |
|
173 #ifdef XPATH_STREAMING |
|
174 if (ctxt->comp->stream) { |
|
175 --- libxml2-2.7.6/include/libxml/xpath.h Thu Sep 24 08:31:59 2009 |
|
176 +++ libxml2-2.7.6/include/libxml/new.xpath.h Mon Oct 24 11:21:50 2011 |
|
177 @@ -68,7 +68,8 @@ |
|
178 XPATH_UNDEF_PREFIX_ERROR, |
|
179 XPATH_ENCODING_ERROR, |
|
180 XPATH_INVALID_CHAR_ERROR, |
|
181 - XPATH_INVALID_CTXT |
|
182 + XPATH_INVALID_CTXT, |
|
183 + XPATH_STACK_ERROR |
|
184 } xmlXPathError; |
|
185 |
|
186 /* |
|
187 @@ -380,6 +381,8 @@ |
|
188 xmlXPathCompExprPtr comp; /* the precompiled expression */ |
|
189 int xptr; /* it this an XPointer expression */ |
|
190 xmlNodePtr ancestor; /* used for walking preceding axis */ |
|
191 + |
|
192 + int valueFrame; /* used to limit Pop on the stack */ |
|
193 }; |
|
194 |
|
195 /************************************************************************ |
|
196 --- libxml2-2.7.6/xpointer.c Mon Oct 24 11:18:07 2011 |
|
197 +++ libxml2-2.7.6/new.xpointer.c Mon Oct 24 11:42:52 2011 |
|
198 @@ -1269,6 +1269,7 @@ |
|
199 ctxt->valueNr = 0; |
|
200 ctxt->valueMax = 10; |
|
201 ctxt->value = NULL; |
|
202 + ctxt->valueFrame = 0; |
|
203 } |
|
204 SKIP_BLANKS; |
|
205 if (CUR == '/') { |
|
206 |
|
207 --- libxml2-2.7.6/xpath.c Thu Jan 5 10:51:16 2012 |
|
208 +++ libxml2-2.7.6/xpath.c.new Thu Jan 5 11:00:39 2012 |
|
209 @@ -11781,8 +11781,11 @@ |
|
210 xmlXPathNodeSetAddUnique(contextObj->nodesetval, |
|
211 contextNode); |
|
212 |
|
213 + frame = xmlXPathSetFrame(ctxt); |
|
214 valuePush(ctxt, contextObj); |
|
215 res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); |
|
216 + tmp = valuePop(ctxt); |
|
217 + xmlXPathPopFrame(ctxt, frame); |
|
218 |
|
219 if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { |
|
220 while (tmp != contextObj) { |
|
221 |
|