OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the XSL implementation. | 2 * This file is part of the XSL implementation. |
3 * | 3 * |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple, Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple, Inc. All rights reserved. |
5 * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@webkit.org> | 5 * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@webkit.org> |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 level = ErrorMessageLevel; | 78 level = ErrorMessageLevel; |
79 break; | 79 break; |
80 } | 80 } |
81 | 81 |
82 console->addMessage(XMLMessageSource, level, error->message, error->file, er
ror->line); | 82 console->addMessage(XMLMessageSource, level, error->message, error->file, er
ror->line); |
83 } | 83 } |
84 | 84 |
85 // FIXME: There seems to be no way to control the ctxt pointer for loading here,
thus we have globals. | 85 // FIXME: There seems to be no way to control the ctxt pointer for loading here,
thus we have globals. |
86 static XSLTProcessor* globalProcessor = 0; | 86 static XSLTProcessor* globalProcessor = 0; |
87 static ResourceFetcher* globalResourceFetcher = 0; | 87 static ResourceFetcher* globalResourceFetcher = 0; |
88 static xmlDocPtr docLoaderFunc(const xmlChar* uri, | 88 |
89 xmlDictPtr, | 89 static xmlDocPtr docLoaderFunc( |
90 int options, | 90 const xmlChar* uri, xmlDictPtr, int options, void* ctxt, xsltLoadType type) |
91 void* ctxt, | |
92 xsltLoadType type) | |
93 { | 91 { |
94 if (!globalProcessor) | 92 if (!globalProcessor) |
95 return 0; | 93 return 0; |
96 | 94 |
97 switch (type) { | 95 switch (type) { |
98 case XSLT_LOAD_DOCUMENT: { | 96 case XSLT_LOAD_DOCUMENT: { |
99 xsltTransformContextPtr context = (xsltTransformContextPtr)ctxt; | 97 xsltTransformContextPtr context = (xsltTransformContextPtr)ctxt; |
100 xmlChar* base = xmlNodeGetBase(context->document->doc, context->node); | 98 xmlChar* base = xmlNodeGetBase(context->document->doc, context->node); |
101 KURL url(KURL(ParsedURLString, reinterpret_cast<const char*>(base)), rei
nterpret_cast<const char*>(uri)); | 99 KURL url(KURL(ParsedURLString, reinterpret_cast<const char*>(base)), rei
nterpret_cast<const char*>(uri)); |
102 xmlFree(base); | 100 xmlFree(base); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 | 170 |
173 StringBuilder resultBuilder; | 171 StringBuilder resultBuilder; |
174 outputBuf->context = &resultBuilder; | 172 outputBuf->context = &resultBuilder; |
175 outputBuf->writecallback = writeToStringBuilder; | 173 outputBuf->writecallback = writeToStringBuilder; |
176 | 174 |
177 int retval = xsltSaveResultTo(outputBuf, resultDoc, sheet); | 175 int retval = xsltSaveResultTo(outputBuf, resultDoc, sheet); |
178 xmlOutputBufferClose(outputBuf); | 176 xmlOutputBufferClose(outputBuf); |
179 if (retval < 0) | 177 if (retval < 0) |
180 return false; | 178 return false; |
181 | 179 |
182 // Workaround for <http://bugzilla.gnome.org/show_bug.cgi?id=495668>: libxsl
t appends an extra line feed to the result. | 180 // Workaround for <http://bugzilla.gnome.org/show_bug.cgi?id=495668>: |
| 181 // libxslt appends an extra line feed to the result. |
183 if (resultBuilder.length() > 0 && resultBuilder[resultBuilder.length() - 1]
== '\n') | 182 if (resultBuilder.length() > 0 && resultBuilder[resultBuilder.length() - 1]
== '\n') |
184 resultBuilder.resize(resultBuilder.length() - 1); | 183 resultBuilder.resize(resultBuilder.length() - 1); |
185 | 184 |
186 resultString = resultBuilder.toString(); | 185 resultString = resultBuilder.toString(); |
187 | 186 |
188 return true; | 187 return true; |
189 } | 188 } |
190 | 189 |
191 static const char** xsltParamArrayFromParameterMap(XSLTProcessor::ParameterMap&
parameters) | 190 static const char** xsltParamArrayFromParameterMap(XSLTProcessor::ParameterMap&
parameters) |
192 { | 191 { |
193 if (parameters.isEmpty()) | 192 if (parameters.isEmpty()) |
194 return 0; | 193 return 0; |
195 | 194 |
196 const char** parameterArray = (const char**)fastMalloc(((parameters.size() *
2) + 1) * sizeof(char*)); | 195 const char** parameterArray = static_cast<const char**>(fastMalloc(((paramet
ers.size() * 2) + 1) * sizeof(char*))); |
197 | 196 |
198 XSLTProcessor::ParameterMap::iterator end = parameters.end(); | 197 XSLTProcessor::ParameterMap::iterator end = parameters.end(); |
199 unsigned index = 0; | 198 unsigned index = 0; |
200 for (XSLTProcessor::ParameterMap::iterator it = parameters.begin(); it != en
d; ++it) { | 199 for (XSLTProcessor::ParameterMap::iterator it = parameters.begin(); it != en
d; ++it) { |
201 parameterArray[index++] = fastStrDup(it->key.utf8().data()); | 200 parameterArray[index++] = fastStrDup(it->key.utf8().data()); |
202 parameterArray[index++] = fastStrDup(it->value.utf8().data()); | 201 parameterArray[index++] = fastStrDup(it->value.utf8().data()); |
203 } | 202 } |
204 parameterArray[index] = 0; | 203 parameterArray[index] = 0; |
205 | 204 |
206 return parameterArray; | 205 return parameterArray; |
207 } | 206 } |
208 | 207 |
209 static void freeXsltParamArray(const char** params) | 208 static void freeXsltParamArray(const char** params) |
210 { | 209 { |
211 const char** temp = params; | 210 const char** temp = params; |
212 if (!params) | 211 if (!params) |
213 return; | 212 return; |
214 | 213 |
215 while (*temp) { | 214 while (*temp) { |
216 fastFree((void*)*(temp++)); | 215 fastFree(const_cast<char*>(*(temp++))); |
217 fastFree((void*)*(temp++)); | 216 fastFree(const_cast<char*>(*(temp++))); |
218 } | 217 } |
219 fastFree(params); | 218 fastFree(params); |
220 } | 219 } |
221 | 220 |
222 static xsltStylesheetPtr xsltStylesheetPointer(RefPtrWillBeMember<XSLStyleSheet>
& cachedStylesheet, Node* stylesheetRootNode) | 221 static xsltStylesheetPtr xsltStylesheetPointer(RefPtrWillBeMember<XSLStyleSheet>
& cachedStylesheet, Node* stylesheetRootNode) |
223 { | 222 { |
224 if (!cachedStylesheet && stylesheetRootNode) { | 223 if (!cachedStylesheet && stylesheetRootNode) { |
225 cachedStylesheet = XSLStyleSheet::createForXSLTProcessor(stylesheetRootN
ode->parentNode() ? stylesheetRootNode->parentNode() : stylesheetRootNode, | 224 cachedStylesheet = XSLStyleSheet::createForXSLTProcessor( |
| 225 stylesheetRootNode->parentNode() ? stylesheetRootNode->parentNode()
: stylesheetRootNode, |
226 stylesheetRootNode->document().url().string(), | 226 stylesheetRootNode->document().url().string(), |
227 stylesheetRootNode->document().url()); // FIXME: Should we use baseU
RL here? | 227 stylesheetRootNode->document().url()); // FIXME: Should we use baseU
RL here? |
228 | 228 |
229 // According to Mozilla documentation, the node must be a Document node,
an xsl:stylesheet or xsl:transform element. | 229 // According to Mozilla documentation, the node must be a Document node, |
230 // But we just use text content regardless of node type. | 230 // an xsl:stylesheet or xsl:transform element. But we just use text |
| 231 // content regardless of node type. |
231 cachedStylesheet->parseString(createMarkup(stylesheetRootNode)); | 232 cachedStylesheet->parseString(createMarkup(stylesheetRootNode)); |
232 } | 233 } |
233 | 234 |
234 if (!cachedStylesheet || !cachedStylesheet->document()) | 235 if (!cachedStylesheet || !cachedStylesheet->document()) |
235 return 0; | 236 return 0; |
236 | 237 |
237 return cachedStylesheet->compileStyleSheet(); | 238 return cachedStylesheet->compileStyleSheet(); |
238 } | 239 } |
239 | 240 |
240 static inline xmlDocPtr xmlDocPtrFromNode(Node* sourceNode, bool& shouldDelete) | 241 static inline xmlDocPtr xmlDocPtrFromNode(Node* sourceNode, bool& shouldDelete) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 286 } |
286 m_stylesheet->clearDocuments(); | 287 m_stylesheet->clearDocuments(); |
287 | 288 |
288 xmlChar* origMethod = sheet->method; | 289 xmlChar* origMethod = sheet->method; |
289 if (!origMethod && mimeType == "text/html") | 290 if (!origMethod && mimeType == "text/html") |
290 sheet->method = (xmlChar*)"html"; | 291 sheet->method = (xmlChar*)"html"; |
291 | 292 |
292 bool success = false; | 293 bool success = false; |
293 bool shouldFreeSourceDoc = false; | 294 bool shouldFreeSourceDoc = false; |
294 if (xmlDocPtr sourceDoc = xmlDocPtrFromNode(sourceNode, shouldFreeSourceDoc)
) { | 295 if (xmlDocPtr sourceDoc = xmlDocPtrFromNode(sourceNode, shouldFreeSourceDoc)
) { |
295 // The XML declaration would prevent parsing the result as a fragment, a
nd it's not needed even for documents, | 296 // The XML declaration would prevent parsing the result as a fragment, |
296 // as the result of this function is always immediately parsed. | 297 // and it's not needed even for documents, as the result of this |
| 298 // function is always immediately parsed. |
297 sheet->omitXmlDeclaration = true; | 299 sheet->omitXmlDeclaration = true; |
298 | 300 |
299 xsltTransformContextPtr transformContext = xsltNewTransformContext(sheet
, sourceDoc); | 301 xsltTransformContextPtr transformContext = xsltNewTransformContext(sheet
, sourceDoc); |
300 registerXSLTExtensions(transformContext); | 302 registerXSLTExtensions(transformContext); |
301 | 303 |
302 xsltSecurityPrefsPtr securityPrefs = xsltNewSecurityPrefs(); | 304 xsltSecurityPrefsPtr securityPrefs = xsltNewSecurityPrefs(); |
303 // Read permissions are checked by docLoaderFunc. | 305 // Read permissions are checked by docLoaderFunc. |
304 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_WRITE_FILE, xs
ltSecurityForbid)) | 306 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_WRITE_FILE, xs
ltSecurityForbid)) |
305 CRASH(); | 307 CRASH(); |
306 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_CREATE_DIRECTO
RY, xsltSecurityForbid)) | 308 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_CREATE_DIRECTO
RY, xsltSecurityForbid)) |
307 CRASH(); | 309 CRASH(); |
308 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_WRITE_NETWORK,
xsltSecurityForbid)) | 310 if (0 != xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_WRITE_NETWORK,
xsltSecurityForbid)) |
309 CRASH(); | 311 CRASH(); |
310 if (0 != xsltSetCtxtSecurityPrefs(securityPrefs, transformContext)) | 312 if (0 != xsltSetCtxtSecurityPrefs(securityPrefs, transformContext)) |
311 CRASH(); | 313 CRASH(); |
312 | 314 |
313 // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor <xsl:s
ort> algorithm only compares by code point. | 315 // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor |
| 316 // <xsl:sort> algorithm only compares by code point. |
314 xsltSetCtxtSortFunc(transformContext, xsltUnicodeSortFunction); | 317 xsltSetCtxtSortFunc(transformContext, xsltUnicodeSortFunction); |
315 | 318 |
316 // This is a workaround for a bug in libxslt. | 319 // This is a workaround for a bug in libxslt. |
317 // The bug has been fixed in version 1.1.13, so once we ship that this c
an be removed. | 320 // The bug has been fixed in version 1.1.13, so once we ship that this |
| 321 // can be removed. |
318 if (!transformContext->globalVars) | 322 if (!transformContext->globalVars) |
319 transformContext->globalVars = xmlHashCreate(20); | 323 transformContext->globalVars = xmlHashCreate(20); |
320 | 324 |
321 const char** params = xsltParamArrayFromParameterMap(m_parameters); | 325 const char** params = xsltParamArrayFromParameterMap(m_parameters); |
322 xsltQuoteUserParams(transformContext, params); | 326 xsltQuoteUserParams(transformContext, params); |
323 xmlDocPtr resultDoc = xsltApplyStylesheetUser(sheet, sourceDoc, 0, 0, 0,
transformContext); | 327 xmlDocPtr resultDoc = xsltApplyStylesheetUser(sheet, sourceDoc, 0, 0, 0,
transformContext); |
324 | 328 |
325 xsltFreeTransformContext(transformContext); | 329 xsltFreeTransformContext(transformContext); |
326 xsltFreeSecurityPrefs(securityPrefs); | 330 xsltFreeSecurityPrefs(securityPrefs); |
327 freeXsltParamArray(params); | 331 freeXsltParamArray(params); |
328 | 332 |
329 if (shouldFreeSourceDoc) | 333 if (shouldFreeSourceDoc) |
330 xmlFreeDoc(sourceDoc); | 334 xmlFreeDoc(sourceDoc); |
331 | 335 |
332 if ((success = saveResultToString(resultDoc, sheet, resultString))) { | 336 if ((success = saveResultToString(resultDoc, sheet, resultString))) { |
333 mimeType = resultMIMEType(resultDoc, sheet); | 337 mimeType = resultMIMEType(resultDoc, sheet); |
334 resultEncoding = (char*)resultDoc->encoding; | 338 resultEncoding = (char*)resultDoc->encoding; |
335 } | 339 } |
336 xmlFreeDoc(resultDoc); | 340 xmlFreeDoc(resultDoc); |
337 } | 341 } |
338 | 342 |
339 sheet->method = origMethod; | 343 sheet->method = origMethod; |
340 setXSLTLoadCallBack(0, 0, 0); | 344 setXSLTLoadCallBack(0, 0, 0); |
341 xsltFreeStylesheet(sheet); | 345 xsltFreeStylesheet(sheet); |
342 m_stylesheet = nullptr; | 346 m_stylesheet = nullptr; |
343 | 347 |
344 return success; | 348 return success; |
345 } | 349 } |
346 | 350 |
347 } // namespace WebCore | 351 } // namespace WebCore |
OLD | NEW |