diff options
author | Alexander Barkov <bar@mnogosearch.org> | 2013-10-02 15:04:07 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mnogosearch.org> | 2013-10-02 15:04:07 +0400 |
commit | 0b6c4bb34f99b8f4023fd0bef25a1b714f96b699 (patch) | |
tree | 87e5f83097f30c9fb7e30928800bcc92690f6bbd /strings/xml.c | |
parent | 9538bbfce9055f99529adb461d101b7b236eb5a3 (diff) | |
download | mariadb-git-0b6c4bb34f99b8f4023fd0bef25a1b714f96b699.tar.gz |
MDEV-4928 Merge collation customization improvements
Merging the following MySQL-5.6 changes:
- WL#5624: Collation customization improvements
http://dev.mysql.com/worklog/task/?id=5624
- WL#4013: Unicode german2 collation
http://dev.mysql.com/worklog/task/?id=4013
- Bug#62429 XML: ExtractValue, UpdateXML max arg length 127 chars
http://bugs.mysql.com/bug.php?id=62429
(required by WL#5624)
Diffstat (limited to 'strings/xml.c')
-rw-r--r-- | strings/xml.c | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/strings/xml.c b/strings/xml.c index 3b2c278f553..8073b881a47 100644 --- a/strings/xml.c +++ b/strings/xml.c @@ -15,6 +15,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "strings_def.h" +#include "m_string.h" #include "my_xml.h" @@ -207,25 +208,71 @@ static int my_xml_value(MY_XML_PARSER *st, const char *str, size_t len) } -static int my_xml_enter(MY_XML_PARSER *st, const char *str, size_t len) +/** + Ensure the attr buffer is wide enough to hold the new value + + Expand and/or allocate dynamic buffer as needed to hold the concatenated + path and the terminating zero. + + @attr st the parser instance + @attr len the length of the attribute to be added + @return state + @retval 1 failed + @retval 0 success +*/ +static int my_xml_attr_ensure_space(MY_XML_PARSER *st, size_t len) { - if ((size_t) (st->attrend-st->attr+len+1) > sizeof(st->attr)) + size_t ofs= st->attr.end - st->attr.start; + len++; // Add terminating zero. + if (ofs + len > st->attr.buffer_size) { - sprintf(st->errstr,"To deep XML"); - return MY_XML_ERROR; + st->attr.buffer_size= (SIZE_T_MAX - len) / 2 > st->attr.buffer_size ? + st->attr.buffer_size * 2 + len : SIZE_T_MAX; + + if (!st->attr.buffer) + { + st->attr.buffer= (char *) my_str_malloc(st->attr.buffer_size); + if (st->attr.buffer) + memcpy(st->attr.buffer, st->attr.static_buffer, ofs + 1 /*term. zero */); + } + else + st->attr.buffer= (char *) my_str_realloc(st->attr.buffer, + st->attr.buffer_size); + st->attr.start= st->attr.buffer; + st->attr.end= st->attr.start + ofs; + + return st->attr.buffer ? MY_XML_OK : MY_XML_ERROR; } - if (st->attrend > st->attr) + return MY_XML_OK; +} + + +/** rewind the attr buffer to initial state */ +static void my_xml_attr_rewind(MY_XML_PARSER *p) +{ + /* keep the buffer already allocated */ + p->attr.end= p->attr.start; +} + + +static int my_xml_enter(MY_XML_PARSER *st, const char *str, size_t len) +{ + if (my_xml_attr_ensure_space(st, len + 1 /* the separator char */)) + return MY_XML_ERROR; + + if (st->attr.end > st->attr.start) { - st->attrend[0]= '/'; - st->attrend++; + st->attr.end[0]= '/'; + st->attr.end++; } - memcpy(st->attrend,str,len); - st->attrend+=len; - st->attrend[0]='\0'; + memcpy(st->attr.end, str, len); + st->attr.end+= len; + st->attr.end[0]= '\0'; if (st->flags & MY_XML_FLAG_RELATIVE_NAMES) return st->enter ? st->enter(st, str, len) : MY_XML_OK; else - return st->enter ? st->enter(st,st->attr,st->attrend-st->attr) : MY_XML_OK; + return st->enter ? + st->enter(st, st->attr.start, st->attr.end - st->attr.start) : MY_XML_OK; } @@ -246,8 +293,8 @@ static int my_xml_leave(MY_XML_PARSER *p, const char *str, size_t slen) int rc; /* Find previous '/' or beginning */ - for (e=p->attrend; (e>p->attr) && (e[0] != '/') ; e--); - glen = (size_t) ((e[0] == '/') ? (p->attrend-e-1) : p->attrend-e); + for (e= p->attr.end; (e > p->attr.start) && (e[0] != '/') ; e--); + glen= (size_t) ((e[0] == '/') ? (p->attr.end - e - 1) : p->attr.end - e); if (str && (slen != glen)) { @@ -265,11 +312,12 @@ static int my_xml_leave(MY_XML_PARSER *p, const char *str, size_t slen) if (p->flags & MY_XML_FLAG_RELATIVE_NAMES) rc= p->leave_xml ? p->leave_xml(p, str, slen) : MY_XML_OK; else - rc= (p->leave_xml ? p->leave_xml(p,p->attr,p->attrend-p->attr) : + rc= (p->leave_xml ? + p->leave_xml(p, p->attr.start, p->attr.end - p->attr.start) : MY_XML_OK); *e='\0'; - p->attrend=e; + p->attr.end= e; return rc; } @@ -277,7 +325,9 @@ static int my_xml_leave(MY_XML_PARSER *p, const char *str, size_t slen) int my_xml_parse(MY_XML_PARSER *p,const char *str, size_t len) { - p->attrend=p->attr; + + my_xml_attr_rewind(p); + p->beg=str; p->cur=str; p->end=str+len; @@ -432,7 +482,7 @@ gt: } } - if (p->attr[0]) + if (p->attr.start[0]) { sprintf(p->errstr,"unexpected END-OF-INPUT"); return MY_XML_ERROR; @@ -443,12 +493,22 @@ gt: void my_xml_parser_create(MY_XML_PARSER *p) { - bzero((void*)p,sizeof(p[0])); + memset(p, 0, sizeof(p[0])); + /* + Use static buffer while it's sufficient. + */ + p->attr.start= p->attr.end= p->attr.static_buffer; + p->attr.buffer_size= sizeof(p->attr.static_buffer); } -void my_xml_parser_free(MY_XML_PARSER *p __attribute__((unused))) +void my_xml_parser_free(MY_XML_PARSER *p) { + if (p->attr.buffer) + { + my_str_free(p->attr.buffer); + p->attr.buffer= NULL; + } } |