From 18e1f1f1180c4d48ed52bf995b3c700c2cefb492 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Mon, 6 Aug 2012 10:16:41 +0800 Subject: [PATCH] Improvements for old buffer compatibility Now tree.h exports LIBXML2_NEW_BUFFER macro indicating that the API uses the new buffers, important to keep code working with both versions. * tree.h buf.h: also export xmlBufContent(), xmlBufEnd(), and xmlBufUse() to help port the old code * buf.c: make sure the compatibility counters are updated on buffer usage, to keep proper working of application compiled against the old structures, but take care of int overflow --- buf.c | 23 ++++++++++++++++++++--- buf.h | 12 ++++++------ include/libxml/tree.h | 12 +++++++++++- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/buf.c b/buf.c index 7e293e6c..530ffc7b 100644 --- a/buf.c +++ b/buf.c @@ -49,6 +49,12 @@ struct _xmlBuf { int error; /* an error code if a failure occured */ }; +#define UPDATE_COMPAT(buf) \ + if (buf->size < INT_MAX) buf->compat_size = buf->size; \ + else buf->compat_size = INT_MAX; \ + if (buf->use < INT_MAX) buf->compat_use = buf->use; \ + else buf->compat_use = INT_MAX; + /** * xmlBufMemoryError: * @extra: extra informations @@ -130,7 +136,7 @@ xmlBufCreateSize(size_t size) { return(NULL); } ret->compat_use = 0; - ret->compat_size = 0; + ret->compat_size = (int) size; ret->use = 0; ret->error = 0; ret->buffer = NULL; @@ -177,6 +183,8 @@ xmlBufDetach(xmlBufPtr buf) { buf->content = NULL; buf->size = 0; buf->use = 0; + buf->compat_use = 0; + buf->compat_size = 0; return ret; } @@ -209,8 +217,8 @@ xmlBufCreateStatic(void *mem, size_t size) { ret->compat_use = size; ret->compat_size = size; } else { - ret->compat_use = 0; - ret->compat_size = 0; + ret->compat_use = INT_MAX; + ret->compat_size = INT_MAX; } ret->use = size; ret->size = size; @@ -329,6 +337,7 @@ xmlBufEmpty(xmlBufPtr buf) { } else { buf->content[0] = 0; } + UPDATE_COMPAT(buf) } /** @@ -376,6 +385,7 @@ xmlBufShrink(xmlBufPtr buf, size_t len) { memmove(buf->content, &buf->content[len], buf->use); buf->content[buf->use] = 0; } + UPDATE_COMPAT(buf) return(len); } @@ -435,6 +445,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { buf->content = newbuf; } buf->size = size; + UPDATE_COMPAT(buf) return(buf->size - buf->use); } @@ -563,6 +574,7 @@ xmlBufAddLen(xmlBufPtr buf, size_t len) { if ((buf == NULL) || (buf->error) || (len > (buf->size - buf->use))) return(-1); buf->use += len; + UPDATE_COMPAT(buf) if (buf->size > buf->use) buf->content[buf->use] = 0; else @@ -585,6 +597,7 @@ xmlBufErase(xmlBufPtr buf, size_t len) { return(-1); buf->use -= len; buf->content[buf->use] = 0; + UPDATE_COMPAT(buf) return(0); } @@ -766,6 +779,7 @@ xmlBufResize(xmlBufPtr buf, size_t size) buf->content = rebuf; } buf->size = newSize; + UPDATE_COMPAT(buf) return 1; } @@ -816,6 +830,7 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { memmove(&buf->content[buf->use], str, len*sizeof(xmlChar)); buf->use += len; buf->content[buf->use] = 0; + UPDATE_COMPAT(buf) return 0; } @@ -885,6 +900,7 @@ xmlBufAddHead(xmlBufPtr buf, const xmlChar *str, int len) { memmove(&buf->content[0], str, len); buf->use += len; buf->content[buf->use] = 0; + UPDATE_COMPAT(buf) return 0; } @@ -941,6 +957,7 @@ xmlBufCCat(xmlBufPtr buf, const char *str) { buf->content[buf->use++] = *cur; } buf->content[buf->use] = 0; + UPDATE_COMPAT(buf) return 0; } diff --git a/buf.h b/buf.h index d1037460..22829c4d 100644 --- a/buf.h +++ b/buf.h @@ -39,15 +39,15 @@ int xmlBufWriteCHAR(xmlBufPtr buf, const xmlChar *string); int xmlBufWriteChar(xmlBufPtr buf, const char *string); int xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string); -size_t xmlBufAvail(xmlBufPtr buf); -size_t xmlBufLength(xmlBufPtr buf); -size_t xmlBufUse(xmlBufPtr buf); -int xmlBufIsEmpty(xmlBufPtr buf); +size_t xmlBufAvail(const xmlBufPtr buf); +size_t xmlBufLength(const xmlBufPtr buf); +/* size_t xmlBufUse(const xmlBufPtr buf); */ +int xmlBufIsEmpty(const xmlBufPtr buf); int xmlBufAddLen(xmlBufPtr buf, size_t len); int xmlBufErase(xmlBufPtr buf, size_t len); -xmlChar * xmlBufContent(const xmlBufPtr buf); -xmlChar * xmlBufEnd(const xmlBufPtr buf); +/* const xmlChar * xmlBufContent(const xmlBufPtr buf); */ +/* const xmlChar * xmlBufEnd(const xmlBufPtr buf); */ xmlChar * xmlBufDetach(xmlBufPtr buf); diff --git a/include/libxml/tree.h b/include/libxml/tree.h index 8f80d8d9..7562d9a5 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -112,6 +112,16 @@ typedef struct _xmlBuf xmlBuf; typedef xmlBuf *xmlBufPtr; +/* + * A few public routines for xmlBuf. As those are expected to be used + * mostly internally the bulk of the routines are internal in buf.h + */ +XMLPUBFUN xmlChar* XMLCALL xmlBufContent (const xmlBufPtr buf); +XMLPUBFUN xmlChar* XMLCALL xmlBufEnd (const xmlBufPtr buf); +XMLPUBFUN size_t XMLCALL xmlBufUse (xmlBufPtr buf); + +#define LIBXML2_NEW_BUFFER + /** * XML_XML_NAMESPACE: * @@ -667,7 +677,7 @@ XMLPUBFUN const xmlChar * XMLCALL int *len); /* - * Handling Buffers. + * Handling Buffers, the old ones see @xmlBuf for the new ones. */ XMLPUBFUN void XMLCALL