| 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 |