📄 c14n.c
字号:
* @doc: the XML document for canonization
* @is_visible_callback:the function to use to determine is node visible
* or not
* @user_data: the first parameter for @is_visible_callback function
* (in most cases, it is nodes set)
* @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
* otherwise - exclusive canonicalization)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
* canonicalization, ignored otherwise)
* @with_comments: include comments in the result (!=0) or not (==0)
* @buf: the output buffer to store canonical XML; this
* buffer MUST have encoder==NULL because C14N requires
* UTF-8 output
*
* Dumps the canonized image of given XML document into the provided buffer.
* For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
* "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
*
* Returns non-negative value on success or a negative value on fail
*/
int
xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
void* user_data, int exclusive, xmlChar **inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
xmlC14NCtxPtr ctx;
int ret;
if ((buf == NULL) || (doc == NULL)) {
xmlC14NErrParam("executing c14n");
return (-1);
}
/*
* Validate the encoding output buffer encoding
*/
if (buf->encoder != NULL) {
xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
"xmlC14NExecute: output buffer encoder != NULL but C14N requires UTF8 output\n");
return (-1);
}
ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
exclusive, inclusive_ns_prefixes,
with_comments, buf);
if (ctx == NULL) {
xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
"xmlC14NExecute: unable to create C14N context\n");
return (-1);
}
/*
* Root Node
* The root node is the parent of the top-level document element. The
* result of processing each of its child nodes that is in the node-set
* in document order. The root node does not generate a byte order mark,
* XML declaration, nor anything from within the document type
* declaration.
*/
if (doc->children != NULL) {
ret = xmlC14NProcessNodeList(ctx, doc->children);
if (ret < 0) {
xmlC14NErrInternal("processing docs children list");
xmlC14NFreeCtx(ctx);
return (-1);
}
}
/*
* Flush buffer to get number of bytes written
*/
ret = xmlOutputBufferFlush(buf);
if (ret < 0) {
xmlC14NErrInternal("flushing output buffer");
xmlC14NFreeCtx(ctx);
return (-1);
}
/*
* Cleanup
*/
xmlC14NFreeCtx(ctx);
return (ret);
}
/**
* xmlC14NDocSaveTo:
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
* @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
* otherwise - exclusive canonicalization)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
* canonicalization, ignored otherwise)
* @with_comments: include comments in the result (!=0) or not (==0)
* @buf: the output buffer to store canonical XML; this
* buffer MUST have encoder==NULL because C14N requires
* UTF-8 output
*
* Dumps the canonized image of given XML document into the provided buffer.
* For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
* "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
*
* Returns non-negative value on success or a negative value on fail
*/
int
xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
int exclusive, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
return(xmlC14NExecute(doc,
(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
nodes,
exclusive,
inclusive_ns_prefixes,
with_comments,
buf));
}
/**
* xmlC14NDocDumpMemory:
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
* @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
* otherwise - exclusive canonicalization)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
* canonicalization, ignored otherwise)
* @with_comments: include comments in the result (!=0) or not (==0)
* @doc_txt_ptr: the memory pointer for allocated canonical XML text;
* the caller of this functions is responsible for calling
* xmlFree() to free allocated memory
*
* Dumps the canonized image of given XML document into memory.
* For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
* "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
*
* Returns the number of bytes written on success or a negative value on fail
*/
int
xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
int exclusive, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlChar ** doc_txt_ptr)
{
int ret;
xmlOutputBufferPtr buf;
if (doc_txt_ptr == NULL) {
xmlC14NErrParam("dumping doc to memory");
return (-1);
}
*doc_txt_ptr = NULL;
/*
* create memory buffer with UTF8 (default) encoding
*/
buf = xmlAllocOutputBuffer(NULL);
if (buf == NULL) {
xmlC14NErrMemory("creating output buffer");
return (-1);
}
/*
* canonize document and write to buffer
*/
ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("saving doc to output buffer");
(void) xmlOutputBufferClose(buf);
return (-1);
}
ret = buf->buffer->use;
if (ret > 0) {
*doc_txt_ptr = xmlStrndup(buf->buffer->content, ret);
}
(void) xmlOutputBufferClose(buf);
if ((*doc_txt_ptr == NULL) && (ret > 0)) {
xmlC14NErrMemory("coping canonicanized document");
return (-1);
}
return (ret);
}
/**
* xmlC14NDocSave:
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
* @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
* otherwise - exclusive canonicalization)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
* canonicalization, ignored otherwise)
* @with_comments: include comments in the result (!=0) or not (==0)
* @filename: the filename to store canonical XML image
* @compression: the compression level (zlib requred):
* -1 - libxml default,
* 0 - uncompressed,
* >0 - compression level
*
* Dumps the canonized image of given XML document into the file.
* For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
* "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
*
* Returns the number of bytes written success or a negative value on fail
*/
int
xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
int exclusive, xmlChar ** inclusive_ns_prefixes,
int with_comments, const char *filename, int compression)
{
xmlOutputBufferPtr buf;
int ret;
if (filename == NULL) {
xmlC14NErrParam("saving doc");
return (-1);
}
#ifdef HAVE_ZLIB_H
if (compression < 0)
compression = xmlGetCompressMode();
#endif
/*
* save the content to a temp buffer, use default UTF8 encoding.
*/
buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
if (buf == NULL) {
xmlC14NErrInternal("creating temporary filename");
return (-1);
}
/*
* canonize document and write to buffer
*/
ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("cannicanize document to buffer");
(void) xmlOutputBufferClose(buf);
return (-1);
}
/*
* get the numbers of bytes written
*/
ret = xmlOutputBufferClose(buf);
return (ret);
}
/*
* Macro used to grow the current buffer.
*/
#define growBufferReentrant() { \
buffer_size *= 2; \
buffer = (xmlChar *) \
xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
if (buffer == NULL) { \
xmlC14NErrMemory("growing buffer"); \
return(NULL); \
} \
}
/**
* xmlC11NNormalizeString:
* @input: the input string
* @mode: the normalization mode (attribute, comment, PI or text)
*
* Converts a string to a canonical (normalized) format. The code is stolen
* from xmlEncodeEntitiesReentrant(). Added normalization of \x09, \x0a, \x0A
* and the @mode parameter
*
* Returns a normalized string (caller is responsible for calling xmlFree())
* or NULL if an error occurs
*/
static xmlChar *
xmlC11NNormalizeString(const xmlChar * input,
xmlC14NNormalizationMode mode)
{
const xmlChar *cur = input;
xmlChar *buffer = NULL;
xmlChar *out = NULL;
int buffer_size = 0;
if (input == NULL)
return (NULL);
/*
* allocate an translation buffer.
*/
buffer_size = 1000;
buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
if (buffer == NULL) {
xmlC14NErrMemory("allocating buffer");
return (NULL);
}
out = buffer;
while (*cur != '\0') {
if ((out - buffer) > (buffer_size - 10)) {
int indx = out - buffer;
growBufferReentrant();
out = &buffer[indx];
}
if ((*cur == '<') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
(mode == XMLC14N_NORMALIZE_TEXT))) {
*out++ = '&';
*out++ = 'l';
*out++ = 't';
*out++ = ';';
} else if ((*cur == '>') && (mode == XMLC14N_NORMALIZE_TEXT)) {
*out++ = '&';
*out++ = 'g';
*out++ = 't';
*out++ = ';';
} else if ((*cur == '&') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
(mode == XMLC14N_NORMALIZE_TEXT))) {
*out++ = '&';
*out++ = 'a';
*out++ = 'm';
*out++ = 'p';
*out++ = ';';
} else if ((*cur == '"') && (mode == XMLC14N_NORMALIZE_ATTR)) {
*out++ = '&';
*out++ = 'q';
*out++ = 'u';
*out++ = 'o';
*out++ = 't';
*out++ = ';';
} else if ((*cur == '\x09') && (mode == XMLC14N_NORMALIZE_ATTR)) {
*out++ = '&';
*out++ = '#';
*out++ = 'x';
*out++ = '9';
*out++ = ';';
} else if ((*cur == '\x0A') && (mode == XMLC14N_NORMALIZE_ATTR)) {
*out++ = '&';
*out++ = '#';
*out++ = 'x';
*out++ = 'A';
*out++ = ';';
} else if ((*cur == '\x0D') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
(mode == XMLC14N_NORMALIZE_TEXT) ||
(mode == XMLC14N_NORMALIZE_COMMENT) ||
(mode == XMLC14N_NORMALIZE_PI))) {
*out++ = '&';
*out++ = '#';
*out++ = 'x';
*out++ = 'D';
*out++ = ';';
} else {
/*
* Works because on UTF-8, all extended sequences cannot
* result in bytes in the ASCII range.
*/
*out++ = *cur;
}
cur++;
}
*out++ = 0;
return (buffer);
}
#endif /* LIBXML_OUTPUT_ENABLED */
#define bottom_c14n
#include "elfgcchack.h"
#endif /* LIBXML_C14N_ENABLED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -