Example #1
0
  /* Wrapper for xsltApplyStylesheet */
xmlDocPtr mxslt_doc_xml_apply_stylesheet(mxslt_doc_t * mxslt_doc, xsltStylesheetPtr style, 
					 xmlDocPtr doc, const char ** params) {
  xmlDocPtr retval;
  xsltTransformContextPtr userCtxt;

  userCtxt=xsltNewTransformContext(style, doc);
  if(userCtxt == NULL)
    return NULL;

  xsltSetCtxtParseOptions(userCtxt, MXSLT_XSLT_OPTIONS);

    /* XXX I don't like this much :| ... I consider this an hack */
  /* userCtxt->_private=(void *)mxslt_doc; */
  userCtxt->outputFile=mxslt_doc->localfile;

#ifndef MXSLT_DISABLE_EXTENSIONS
  xsltRegisterExtElement(userCtxt, (xmlChar *)"header-set",
                         (xmlChar *)MXSLT_NS_URI, mxslt_transform_header);
  xsltRegisterExtElement(userCtxt, (xmlChar *)"value-of",
                         (xmlChar *)MXSLT_NS_URI, mxslt_transform_value_of);

  xsltRegisterExtElement(userCtxt, (xmlChar *)"header-set",
                         (xmlChar *)MXSLT_OBSOLETE_NS_URI, mxslt_transform_header);
  xsltRegisterExtElement(userCtxt, (xmlChar *)"value-of",
                         (xmlChar *)MXSLT_OBSOLETE_NS_URI, mxslt_transform_value_of);
#endif

  retval=xsltApplyStylesheetUser(style, doc, params, NULL, NULL, userCtxt);

  xsltFreeTransformContext(userCtxt);

  return retval;
}
Example #2
0
QString XSLTransformer::transform(const QString &xml, QHash<QString, QString> const &params) const
{
    // Read XML data intro an xmlDoc.
    QByteArray xmlData(xml.toUtf8());
    QScopedPointer<xmlDoc, XmlDocDeleter> doc(
        xmlReadMemory(xmlData.constData(), xmlData.size(), 0, 0, 0));

    if (!doc)
        throw std::runtime_error("XSLTransformer::transform: Could not open XML data");

    // Hmpf, data conversions.
    char const **cParams = new char const *[params.size() * 2 + 1];
    int i = 0;
    for (QHash<QString, QString>::const_iterator iter = params.constBegin();
        iter != params.constEnd(); ++iter)
    {
        QByteArray keyData(iter.key().toUtf8());
        QByteArray valueData(iter.value().toUtf8());

        char const *cKey = strdup(keyData.constData());
        char const *cValue = strdup(valueData.constData());

        cParams[i] = cKey;
        cParams[i + 1] = cValue;

        i += 2;
    }

    cParams[params.size() * 2] = 0; // Terminator

    QScopedPointer<xsltTransformContext, XsltTransformContextDeleter> ctx(
        xsltNewTransformContext(d_xslPtr.data(), doc.data()));
    xsltSetCtxtParseOptions(ctx.data(), XSLT_PARSE_OPTIONS);

    // Transform...
    QScopedPointer<xmlDoc, XmlDocDeleter> res(
        xsltApplyStylesheetUser(d_xslPtr.data(), doc.data(), cParams, NULL, NULL, ctx.data()));

    if (!res)
        throw std::runtime_error("XSLTransformer::transform: Could not apply transformation!");
    else if (ctx->state != XSLT_STATE_OK)
        throw std::runtime_error("XSLTransformer::transform: Transformation error, check your query!");

    xmlChar *outputBare = 0;
    int outputLen = -1;
    xsltSaveResultToString(&outputBare, &outputLen, res.data(), d_xslPtr.data());
    QScopedPointer<xmlChar, XmlDeleter> output(outputBare);

    if (!output)
        throw std::runtime_error("Could not apply stylesheet!");

    QString result(QString::fromUtf8(reinterpret_cast<char const *>(output.data())));

    // Deallocate parameter memory
    for (int i = 0; i < params.size() * 2; ++i)
        free(const_cast<char *>(cParams[i]));
    delete[] cParams;

    return result;
}
Example #3
0
bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String& resultString, String& resultEncoding)
{
    RefPtr<Document> ownerDocument = sourceNode->document();

    setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->docLoader());
    xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get());
    if (!sheet) {
        setXSLTLoadCallBack(0, 0, 0);
        return false;
    }
    m_stylesheet->clearDocuments();

    xmlChar* origMethod = sheet->method;
    if (!origMethod && mimeType == "text/html")
        sheet->method = (xmlChar*)"html";

    bool success = false;
    bool shouldFreeSourceDoc = false;
    if (xmlDocPtr sourceDoc = xmlDocPtrFromNode(sourceNode, shouldFreeSourceDoc)) {
        // The XML declaration would prevent parsing the result as a fragment, and it's not needed even for documents,
        // as the result of this function is always immediately parsed.
        sheet->omitXmlDeclaration = true;

        xsltTransformContextPtr transformContext = xsltNewTransformContext(sheet, sourceDoc);
        registerXSLTExtensions(transformContext);

        // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor <xsl:sort> algorithm only compares by code point.
        xsltSetCtxtSortFunc(transformContext, xsltUnicodeSortFunction);

        // This is a workaround for a bug in libxslt.
        // The bug has been fixed in version 1.1.13, so once we ship that this can be removed.
        if (!transformContext->globalVars)
           transformContext->globalVars = xmlHashCreate(20);

        const char** params = xsltParamArrayFromParameterMap(m_parameters);
        xsltQuoteUserParams(transformContext, params);
        xmlDocPtr resultDoc = xsltApplyStylesheetUser(sheet, sourceDoc, 0, 0, 0, transformContext);

        xsltFreeTransformContext(transformContext);
        freeXsltParamArray(params);

        if (shouldFreeSourceDoc)
            xmlFreeDoc(sourceDoc);

        if ((success = saveResultToString(resultDoc, sheet, resultString))) {
            mimeType = resultMIMEType(resultDoc, sheet);
            resultEncoding = (char*)resultDoc->encoding;
        }
        xmlFreeDoc(resultDoc);
    }

    sheet->method = origMethod;
    setXSLTLoadCallBack(0, 0, 0);
    xsltFreeStylesheet(sheet);
    m_stylesheet = 0;

    return success;
}
Example #4
0
static VXdoc& _transform(Request& r, const String* stylesheet_source, 
						   VXdoc& vdoc, xsltStylesheetPtr stylesheet, const xmlChar** transform_params) 
{
	xmlDoc& xmldoc=vdoc.get_xmldoc();

	xsltTransformContext_auto_ptr transformContext(
		xsltNewTransformContext(stylesheet, &xmldoc));
	// make params literal
	if (transformContext->globalVars == NULL) // strangly not initialized by xsltNewTransformContext
		transformContext->globalVars = xmlHashCreate(20);
	xsltQuoteUserParams(transformContext.get(), (const char**)transform_params);
	// do transform
	xmlDoc *transformed=xsltApplyStylesheetUser(
		stylesheet,
		&xmldoc,
		0/*already quoted-inserted  transform_params*/,
		0/*const char* output*/,
		0/*FILE *profile*/,
		transformContext.get());
	if(!transformed || xmlHaveGenericErrors())
		throw XmlException(stylesheet_source, r);

	//gdome_xml_doc_mkref dislikes XML_HTML_DOCUMENT_NODE  type, fixing
	transformed->type=XML_DOCUMENT_NODE;
	// constructing result
	VXdoc& result=*new VXdoc(r.charsets, *transformed);
	/* grabbing options

		<xsl:output
		!method = "xml" | "html" | "text"
			X| qname-but-not-ncname 
		!version = nmtoken 
		!encoding = string 
		!omit-xml-declaration = "yes" | "no"
		!standalone = "yes" | "no"
		!doctype-public = string 
		!doctype-system = string 
		Xcdata-section-elements = qnames 
		!indent = "yes" | "no"
		!media-type = string /> 
	*/
	XDocOutputOptions& oo=result.output_options;

	oo.method=stylesheet->method?&r.transcode(stylesheet->method):0;
	oo.encoding=stylesheet->encoding?&r.transcode(stylesheet->encoding):0;
	oo.mediaType=stylesheet->mediaType?&r.transcode(stylesheet->mediaType):0;
	oo.indent=stylesheet->indent;
	oo.version=stylesheet->version?&r.transcode(stylesheet->version):0;
	oo.standalone=stylesheet->standalone;
	oo.omitXmlDeclaration=stylesheet->omitXmlDeclaration;

	// return
	return result;
}
Example #5
0
void
yelp_transform_start (YelpTransform *transform,
		      xmlDocPtr      document,
		      gchar        **params)
{
    transform->inputDoc = document;

    transform->context = xsltNewTransformContext (transform->stylesheet,
						  transform->inputDoc);
    if (!transform->context) {
	YelpError *error = 
	    yelp_error_new (_("Broken Transformation"),
			    _("An unknown error occurred while attempting to "
			      "transform the document."));
	transform_set_error (transform, error);
	return;
    }

    transform->params = g_strdupv (params);

    transform->context->_private = transform;
    if (!exslt_registered) {
	exsltRegisterAll ();
	exslt_registered = TRUE;
    }
    xsltRegisterExtElement (transform->context,
			    BAD_CAST "document",
			    BAD_CAST YELP_NAMESPACE,
			    (xsltTransformFunction) xslt_yelp_document);
    xsltRegisterExtElement (transform->context,
			    BAD_CAST "cache",
			    BAD_CAST YELP_NAMESPACE,
			    (xsltTransformFunction) xslt_yelp_cache);
    xsltRegisterExtFunction (transform->context,
			     BAD_CAST "input",
			     BAD_CAST YELP_NAMESPACE,
			     (xmlXPathFunction) xslt_yelp_input);

    transform->mutex = g_mutex_new ();
    g_mutex_lock (transform->mutex);
    transform->running = TRUE;
    transform->thread = g_thread_create ((GThreadFunc) transform_run,
					 transform, FALSE, NULL);
    g_mutex_unlock (transform->mutex);
}
Example #6
0
static int create_xslt_parser( struct xslt_info *info, xmlNodePtr node, const xmlChar *str )
{
    if(!node) return 1;

    info->sheet = xsltNewStylesheet();
    if (!info->sheet)
        return 0;

    info->ctxt = xsltNewTransformContext( info->sheet, node->doc );
    if (!info->ctxt)
        return 0;

    info->pattern = xsltCompilePattern( str, node->doc,
                                        node, info->sheet, info->ctxt );
    if (!info->pattern)
        return 0;
    return 1;
}
Example #7
0
// Processes input XML file (e.g., instance metadata) into output XML file or string (e.g., for libvirt)
// using XSL-T specification file (e.g., libvirt.xsl)
static int apply_xslt_stylesheet (const char * xsltStylesheetPath, const char * inputXmlPath, const char * outputXmlPath, char * outputXmlBuffer, int outputXmlBufferSize)
{
        int err = OK;

        INIT();
        xsltStylesheetPtr cur = xsltParseStylesheetFile ((const xmlChar *)xsltStylesheetPath);
        if (cur) {
                xmlDocPtr doc = xmlParseFile (inputXmlPath);
                if (doc) {
                        xsltTransformContextPtr ctxt = xsltNewTransformContext (cur, doc); // need context to get result
                        xsltSetCtxtParseOptions (ctxt, 0); // TODO: do we want any XSL-T parsing options?
                        xmlDocPtr res = xsltApplyStylesheetUser (cur, doc, NULL, NULL, NULL, ctxt); // applies XSLT to XML
                        int applied_ok = ctxt->state==XSLT_STATE_OK; // errors are communicated via ctxt->state
                        xsltFreeTransformContext (ctxt);
                        
                        if (res && applied_ok) {

                            // save to a file, if path was provied
                            if (outputXmlPath!=NULL) {
                                FILE * fp = fopen (outputXmlPath, "w");
                                if (fp) {
                                    int bytes = xsltSaveResultToFile (fp, res, cur);
                                    if (bytes==-1) {
                                        logprintfl (EUCAERROR, "ERROR: failed to save XML document to %s\n", outputXmlPath);
                                        err = ERROR;
                                    }
                                    fclose (fp);
                                } else {
                                    logprintfl (EUCAERROR, "ERROR: failed to create file %s\n", outputXmlPath);
                                    err = ERROR;
                                }                                
                            }

                            // convert to an ASCII buffer, if such was provided
                            if (err==OK && outputXmlBuffer!=NULL && outputXmlBufferSize > 0) {
                                xmlChar * buf;
                                int buf_size;
                                if (xsltSaveResultToString (&buf, &buf_size, res, cur)==0) { // success
                                    if (buf_size < outputXmlBufferSize) {
                                        bzero (outputXmlBuffer, outputXmlBufferSize);
                                        for (int i=0, j=0; i<buf_size; i++) {
                                            char c = (char) buf [i];
                                            if (c != '\n') // remove newlines
                                                outputXmlBuffer [j++] = c;
                                        }
                                    } else {
                                        logprintfl (EUCAERROR, "ERROR: XML string buffer is too small (%d > %d)\n", buf_size, outputXmlBufferSize);
                                        err = ERROR;
                                    }
                                    xmlFree (buf);
                                } else {
                                    logprintfl (EUCAERROR, "ERROR: failed to save XML document to a string\n");
                                    err = ERROR;
                                }
                            }
                        } else {
                            logprintfl (EUCAERROR, "ERROR: failed to apply stylesheet %s to %s\n", xsltStylesheetPath, inputXmlPath);
                            err = ERROR;
                        }
                        if (res!=NULL) xmlFreeDoc(res);
                        xmlFreeDoc(doc);
                } else {
                        logprintfl (EUCAERROR, "ERROR: failed to parse XML document %s\n", inputXmlPath);
                        err = ERROR;
                }
                xsltFreeStylesheet(cur);
        } else {
                logprintfl (EUCAERROR, "ERROR: failed to open and parse XSL-T stylesheet file %s\n", xsltStylesheetPath);
                err = ERROR;
        }

        return err;
}
static ngx_buf_t *
ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
    ngx_http_xslt_filter_ctx_t *ctx)
{
    int                               len, rc, doc_type;
    u_char                           *type, *encoding;
    ngx_buf_t                        *b;
    ngx_uint_t                        i;
    xmlChar                          *buf;
    xmlDocPtr                         doc, res;
    ngx_http_xslt_sheet_t            *sheet;
    ngx_http_xslt_filter_loc_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
    sheet = conf->sheets.elts;
    doc = ctx->doc;

    /* preallocate array for 4 params */

    if (ngx_array_init(&ctx->params, r->pool, 4 * 2 + 1, sizeof(char *))
        != NGX_OK)
    {
        xmlFreeDoc(doc);
        return NULL;
    }

    for (i = 0; i < conf->sheets.nelts; i++) {

        ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc);
        if (ctx->transform == NULL) {
            xmlFreeDoc(doc);
            return NULL;
        }

        if (conf->params
            && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK)
        {
            xsltFreeTransformContext(ctx->transform);
            xmlFreeDoc(doc);
            return NULL;
        }

        if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) {
            xsltFreeTransformContext(ctx->transform);
            xmlFreeDoc(doc);
            return NULL;
        }

        res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc,
                                      ctx->params.elts, NULL, NULL,
                                      ctx->transform);

        xsltFreeTransformContext(ctx->transform);
        xmlFreeDoc(doc);

        if (res == NULL) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "xsltApplyStylesheet() failed");
            return NULL;
        }

        doc = res;

        /* reset array elements */
        ctx->params.nelts = 0;
    }

    /* there must be at least one stylesheet */

    if (r == r->main) {
        type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);

    } else {
        type = NULL;
    }

    encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet);
    doc_type = doc->type;

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "xslt filter type: %d t:%s e:%s",
                   doc_type, type ? type : (u_char *) "(null)",
                   encoding ? encoding : (u_char *) "(null)");

    rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet);

    xmlFreeDoc(doc);

    if (rc != 0) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xsltSaveResultToString() failed");
        return NULL;
    }

    if (len == 0) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xsltSaveResultToString() returned zero-length result");
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        ngx_free(buf);
        return NULL;
    }

    b->pos = buf;
    b->last = buf + len;
    b->memory = 1;

    if (encoding) {
        r->headers_out.charset.len = ngx_strlen(encoding);
        r->headers_out.charset.data = encoding;
    }

    if (r != r->main) {
        return b;
    }

    b->last_buf = 1;

    if (type) {
        len = ngx_strlen(type);

        r->headers_out.content_type_len = len;
        r->headers_out.content_type.len = len;
        r->headers_out.content_type.data = type;

    } else if (doc_type == XML_HTML_DOCUMENT_NODE) {

        r->headers_out.content_type_len = sizeof("text/html") - 1;
        ngx_str_set(&r->headers_out.content_type, "text/html");
    }

    r->headers_out.content_type_lowcase = NULL;

    return b;
}
Example #9
0
static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp) /* {{{ */
{
	xmlDocPtr newdocp = NULL;
	xmlDocPtr doc = NULL;
	xmlNodePtr node = NULL;
	xsltTransformContextPtr ctxt;
	php_libxml_node_object *object;
	char **params = NULL;
	int clone;
	zval *doXInclude, member, rv;
	zend_object_handlers *std_hnd;
	FILE *f;
	int secPrefsError = 0;
	int secPrefsValue;
	xsltSecurityPrefsPtr secPrefs = NULL;

	node = php_libxml_import_node(docp);

	if (node) {
		doc = node->doc;
	}
	if (doc == NULL) {
		php_error_docref(NULL, E_WARNING, "Invalid Document");
		return NULL;
	}

	if (style == NULL) {
		php_error_docref(NULL, E_WARNING, "No stylesheet associated to this object");
		return NULL;
	}

	if (intern->profiling) {
		if (php_check_open_basedir(intern->profiling)) {
			f = NULL;
		} else {
			f = VCWD_FOPEN(intern->profiling, "w");
		}
	} else {
		f = NULL;
	}

	if (intern->parameter) {
		params = php_xsl_xslt_make_params(intern->parameter, 0);
	}

	intern->doc = emalloc(sizeof(php_libxml_node_object));
	memset(intern->doc, 0, sizeof(php_libxml_node_object));

	if (intern->hasKeys == 1) {
		doc = xmlCopyDoc(doc, 1);
	} else {
		object = Z_LIBXML_NODE_P(docp);
		intern->doc->document = object->document;
	}

	php_libxml_increment_doc_ref(intern->doc, doc);

	ctxt = xsltNewTransformContext(style, doc);
	ctxt->_private = (void *) intern;

	std_hnd = zend_get_std_object_handlers();

	ZVAL_STRING(&member, "doXInclude");
	doXInclude = std_hnd->read_property(id, &member, BP_VAR_IS, NULL, &rv);
	if (Z_TYPE_P(doXInclude) != IS_NULL) {
		convert_to_long(doXInclude);
		ctxt->xinclude = Z_LVAL_P(doXInclude);
	}
	zval_ptr_dtor(&member);

	secPrefsValue = intern->securityPrefs;

	/* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */
	if (secPrefsValue != XSL_SECPREF_NONE) {
		secPrefs = xsltNewSecurityPrefs();
		if (secPrefsValue & XSL_SECPREF_READ_FILE ) {
			if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) {
				secPrefsError = 1;
			}
		}
		if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) {
			if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) {
				secPrefsError = 1;
			}
		}
		if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) {
			if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) {
				secPrefsError = 1;
			}
		}
		if (secPrefsValue & XSL_SECPREF_READ_NETWORK) {
			if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) {
				secPrefsError = 1;
			}
		}
		if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) {
			if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) {
				secPrefsError = 1;
			}
		}

		if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) {
			secPrefsError = 1;
		}
	}

	if (secPrefsError == 1) {
		php_error_docref(NULL, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons");
	} else {
		newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params,  NULL, f, ctxt);
	}
	if (f) {
		fclose(f);
	}

	xsltFreeTransformContext(ctxt);
	if (secPrefs) {
		xsltFreeSecurityPrefs(secPrefs);
	}

	if (intern->node_list != NULL) {
		zend_hash_destroy(intern->node_list);
		FREE_HASHTABLE(intern->node_list);
		intern->node_list = NULL;
	}

	php_libxml_decrement_doc_ref(intern->doc);
	efree(intern->doc);
	intern->doc = NULL;

	if (params) {
		clone = 0;
		while(params[clone]) {
			efree(params[clone++]);
		}
		efree(params);
	}

	return newdocp;

}
Example #10
0
            <xsl:template match=\"text()[(following-sibling::* or preceding-sibling::*) and normalize-space(.) != '']\"> \
                <sg_wrap><xsl:value-of select=\".\" /></sg_wrap> \
            </xsl:template> \
            <xsl:template match=\"@*|node()\"> \
                <xsl:copy> \
                    <xsl:apply-templates select=\"@*|node()\"/> \
                </xsl:copy> \
            </xsl:template> \
        </xsl:stylesheet>";

        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
        xmlDocPtr xml = xmlCtxtReadMemory(ctxt, sheet, strlen(sheet), NULL, NULL, 0);
        span_wrap_sheet = xsltParseStylesheetDoc(xml);
    }

    xsltTransformContextPtr ctxt = xsltNewTransformContext(span_wrap_sheet, doc);
    xmlSetGenericErrorFunc(ctxt, parsleyXsltError);
    xmlDocPtr out = xsltApplyStylesheetUser(span_wrap_sheet, doc, NULL, NULL, NULL, ctxt);
    xsltFreeTransformContext(ctxt);
    return out;
}

void _parsley_set_user_agent(char *agent)
{
    if (parsley_user_agent_header != NULL)
    {
        free(parsley_user_agent_header);
    }

    if (agent == NULL)
    {
Example #11
0
xmlDocPtr c_XSLTProcessor::apply_stylesheet() {
  SYNC_VM_REGS_SCOPED();

  if (m_stylesheet == nullptr || m_doc == nullptr) {
    raise_error("Unable to apply stylesheet");
    return nullptr;
  }

  xsltTransformContextPtr ctxt = xsltNewTransformContext (m_stylesheet, m_doc);
  if (ctxt == nullptr) {
    raise_error("Unable to apply stylesheet");
    return nullptr;
  }

  ctxt->_private = this;

  xsltSecurityPrefsPtr prefs = nullptr;
  if (m_secprefs != k_XSL_SECPREF_NONE) {
    prefs = xsltNewSecurityPrefs();
    int error = 0;

    if (m_secprefs & k_XSL_SECPREF_READ_FILE) {
      if (xsltSetSecurityPrefs(prefs,
                               XSLT_SECPREF_READ_FILE,
                               xsltSecurityForbid) != 0) {
        error = 1;
      }
    }

    if (m_secprefs & k_XSL_SECPREF_WRITE_FILE) {
      if (xsltSetSecurityPrefs(prefs,
                               XSLT_SECPREF_WRITE_FILE,
                               xsltSecurityForbid) != 0) {
        error = 1;
      }
    }

    if (m_secprefs & k_XSL_SECPREF_CREATE_DIRECTORY) {
      if (xsltSetSecurityPrefs(prefs,
                               XSLT_SECPREF_CREATE_DIRECTORY,
                               xsltSecurityForbid) != 0) {
        error = 1;
      }
    }

    if (m_secprefs & k_XSL_SECPREF_READ_NETWORK) {
      if (xsltSetSecurityPrefs(prefs,
                               XSLT_SECPREF_READ_NETWORK,
                               xsltSecurityForbid) != 0) {
        error = 1;
      }
    }

    if (m_secprefs & k_XSL_SECPREF_WRITE_NETWORK) {
      if (xsltSetSecurityPrefs(prefs,
                               XSLT_SECPREF_WRITE_NETWORK,
                               xsltSecurityForbid) != 0) {
        error = 1;
      }
    }

    if (xsltSetCtxtSecurityPrefs(prefs, ctxt) != 0) {
      error = 1;
    }

    if (error == 1) {
      raise_error("Can't set libxslt security properties, not doing "
                  "transformation for security reasons");
      return nullptr;
    }
  }

  xsltRegisterExtFunction(ctxt,
    (const xmlChar*) "functionString",
    (const xmlChar*) "http://php.net/xsl",
    xslt_ext_function_string_php
  );

  xsltRegisterExtFunction(ctxt,
    (const xmlChar*) "function",
    (const xmlChar*) "http://php.net/xsl",
    xslt_ext_function_object_php
  );

  for (ArrayIter iter(m_params); iter; ++iter) {
    assert(iter.first().isString());
    assert(iter.second().isString());

    xmlChar *value = xslt_string_to_xpathexpr(iter.second().toString().c_str());
    if (value) {
      xsltEvalOneUserParam(ctxt,
        (const xmlChar*)iter.first().toString().c_str(),
        (const xmlChar*)value
      );

      xmlFree(value);
    }
  }

  FILE *profile = nullptr;
  if (m_profile) {
    profile = fopen(m_profile.data(), "w");
  }

  xmlDocPtr res = xsltApplyStylesheetUser(m_stylesheet,
                                          m_doc,
                                          nullptr,
                                          nullptr,
                                          profile,
                                          ctxt);

  if (profile) {
    fclose(profile);
  }

  xsltFreeTransformContext(ctxt);

  if (prefs) {
    xsltFreeSecurityPrefs(prefs);
  }

  return res;
}
Example #12
0
static void
transform_run (YelpTransform *transform)
{
    YelpTransformPrivate *priv = GET_PRIV (transform);

    debug_print (DB_FUNCTION, "entering\n");

    priv->stylesheet = xsltParseStylesheetFile (BAD_CAST (priv->stylesheet_file));
    if (priv->stylesheet == NULL) {
        g_mutex_lock (&priv->mutex);
        if (priv->error)
            g_error_free (priv->error);
        priv->error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING,
                                   _("The XSLT stylesheet ā€˜%sā€™ is either missing or not valid."),
                                   priv->stylesheet_file);
        g_object_ref (transform);
        g_idle_add ((GSourceFunc) transform_error, transform);
        g_mutex_unlock (&priv->mutex);
        return;
    }

    priv->context = xsltNewTransformContext (priv->stylesheet,
                                             priv->input);
    if (priv->context == NULL) {
        g_mutex_lock (&priv->mutex);
        if (priv->error)
            g_error_free (priv->error);
        priv->error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING,
                                   _("The XSLT stylesheet ā€˜%sā€™ is either missing or not valid."),
                                   priv->stylesheet_file);
        g_object_ref (transform);
        g_idle_add ((GSourceFunc) transform_error, transform);
        g_mutex_unlock (&priv->mutex);
        return;
    }

    priv->context->_private = transform;
    xsltRegisterExtElement (priv->context,
                            BAD_CAST "document",
                            BAD_CAST YELP_NAMESPACE,
                            (xsltTransformFunction) xslt_yelp_document);
    xsltRegisterExtElement (priv->context,
                            BAD_CAST "cache",
                            BAD_CAST YELP_NAMESPACE,
                            (xsltTransformFunction) xslt_yelp_cache);
    xsltRegisterExtFunction (priv->context,
                             BAD_CAST "input",
                             BAD_CAST YELP_NAMESPACE,
                             (xmlXPathFunction) xslt_yelp_aux);

    priv->output = xsltApplyStylesheetUser (priv->stylesheet,
                                            priv->input,
                                            (const char **) priv->params,
                                            NULL, NULL,
                                            priv->context);
    g_mutex_lock (&priv->mutex);
    priv->running = FALSE;
    if (!priv->cancelled) {
        g_idle_add ((GSourceFunc) transform_final, transform);
        g_mutex_unlock (&priv->mutex);
    }
    else {
        g_mutex_unlock (&priv->mutex);
        g_object_unref (transform);
    }
}