Return to minixml.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / miniupnpc / src |
1.1 ! misho 1: /* $Id: minixml.c,v 1.12 2017/12/12 11:17:40 nanard Exp $ */ ! 2: /* vim: tabstop=4 shiftwidth=4 noexpandtab ! 3: * minixml.c : the minimum size a xml parser can be ! */ ! 4: /* Project : miniupnp ! 5: * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ ! 6: * Author : Thomas Bernard ! 7: ! 8: Copyright (c) 2005-2017, Thomas BERNARD ! 9: All rights reserved. ! 10: ! 11: Redistribution and use in source and binary forms, with or without ! 12: modification, are permitted provided that the following conditions are met: ! 13: ! 14: * Redistributions of source code must retain the above copyright notice, ! 15: this list of conditions and the following disclaimer. ! 16: * Redistributions in binary form must reproduce the above copyright notice, ! 17: this list of conditions and the following disclaimer in the documentation ! 18: and/or other materials provided with the distribution. ! 19: * The name of the author may not be used to endorse or promote products ! 20: derived from this software without specific prior written permission. ! 21: ! 22: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ! 23: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 24: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 25: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ! 26: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ! 27: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ! 28: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ! 29: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ! 30: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! 31: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 32: POSSIBILITY OF SUCH DAMAGE. ! 33: */ ! 34: #include <string.h> ! 35: #include "minixml.h" ! 36: ! 37: /* parseatt : used to parse the argument list ! 38: * return 0 (false) in case of success and -1 (true) if the end ! 39: * of the xmlbuffer is reached. */ ! 40: static int parseatt(struct xmlparser * p) ! 41: { ! 42: const char * attname; ! 43: int attnamelen; ! 44: const char * attvalue; ! 45: int attvaluelen; ! 46: while(p->xml < p->xmlend) ! 47: { ! 48: if(*p->xml=='/' || *p->xml=='>') ! 49: return 0; ! 50: if( !IS_WHITE_SPACE(*p->xml) ) ! 51: { ! 52: char sep; ! 53: attname = p->xml; ! 54: attnamelen = 0; ! 55: while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) ! 56: { ! 57: attnamelen++; p->xml++; ! 58: if(p->xml >= p->xmlend) ! 59: return -1; ! 60: } ! 61: while(*(p->xml++) != '=') ! 62: { ! 63: if(p->xml >= p->xmlend) ! 64: return -1; ! 65: } ! 66: while(IS_WHITE_SPACE(*p->xml)) ! 67: { ! 68: p->xml++; ! 69: if(p->xml >= p->xmlend) ! 70: return -1; ! 71: } ! 72: sep = *p->xml; ! 73: if(sep=='\'' || sep=='\"') ! 74: { ! 75: p->xml++; ! 76: if(p->xml >= p->xmlend) ! 77: return -1; ! 78: attvalue = p->xml; ! 79: attvaluelen = 0; ! 80: while(*p->xml != sep) ! 81: { ! 82: attvaluelen++; p->xml++; ! 83: if(p->xml >= p->xmlend) ! 84: return -1; ! 85: } ! 86: } ! 87: else ! 88: { ! 89: attvalue = p->xml; ! 90: attvaluelen = 0; ! 91: while( !IS_WHITE_SPACE(*p->xml) ! 92: && *p->xml != '>' && *p->xml != '/') ! 93: { ! 94: attvaluelen++; p->xml++; ! 95: if(p->xml >= p->xmlend) ! 96: return -1; ! 97: } ! 98: } ! 99: /*printf("%.*s='%.*s'\n", ! 100: attnamelen, attname, attvaluelen, attvalue);*/ ! 101: if(p->attfunc) ! 102: p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); ! 103: } ! 104: p->xml++; ! 105: } ! 106: return -1; ! 107: } ! 108: ! 109: /* parseelt parse the xml stream and ! 110: * call the callback functions when needed... */ ! 111: static void parseelt(struct xmlparser * p) ! 112: { ! 113: int i; ! 114: const char * elementname; ! 115: while(p->xml < (p->xmlend - 1)) ! 116: { ! 117: if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4))) ! 118: { ! 119: p->xml += 3; ! 120: /* ignore comments */ ! 121: do ! 122: { ! 123: p->xml++; ! 124: if ((p->xml + 3) >= p->xmlend) ! 125: return; ! 126: } ! 127: while(memcmp(p->xml, "-->", 3) != 0); ! 128: p->xml += 3; ! 129: } ! 130: else if((p->xml)[0]=='<' && (p->xml)[1]!='?') ! 131: { ! 132: i = 0; elementname = ++p->xml; ! 133: while( !IS_WHITE_SPACE(*p->xml) ! 134: && (*p->xml!='>') && (*p->xml!='/') ! 135: ) ! 136: { ! 137: i++; p->xml++; ! 138: if (p->xml >= p->xmlend) ! 139: return; ! 140: /* to ignore namespace : */ ! 141: if(*p->xml==':') ! 142: { ! 143: i = 0; ! 144: elementname = ++p->xml; ! 145: } ! 146: } ! 147: if(i>0) ! 148: { ! 149: if(p->starteltfunc) ! 150: p->starteltfunc(p->data, elementname, i); ! 151: if(parseatt(p)) ! 152: return; ! 153: if(*p->xml!='/') ! 154: { ! 155: const char * data; ! 156: i = 0; data = ++p->xml; ! 157: if (p->xml >= p->xmlend) ! 158: return; ! 159: while( IS_WHITE_SPACE(*p->xml) ) ! 160: { ! 161: i++; p->xml++; ! 162: if (p->xml >= p->xmlend) ! 163: return; ! 164: } ! 165: /* CDATA are at least 9 + 3 characters long : <![CDATA[ ]]> */ ! 166: if((p->xmlend >= (p->xml + (9 + 3))) && (memcmp(p->xml, "<![CDATA[", 9) == 0)) ! 167: { ! 168: /* CDATA handling */ ! 169: p->xml += 9; ! 170: data = p->xml; ! 171: i = 0; ! 172: while(memcmp(p->xml, "]]>", 3) != 0) ! 173: { ! 174: i++; p->xml++; ! 175: if ((p->xml + 3) >= p->xmlend) ! 176: return; ! 177: } ! 178: if(i>0 && p->datafunc) ! 179: p->datafunc(p->data, data, i); ! 180: while(*p->xml!='<') ! 181: { ! 182: p->xml++; ! 183: if (p->xml >= p->xmlend) ! 184: return; ! 185: } ! 186: } ! 187: else ! 188: { ! 189: while(*p->xml!='<') ! 190: { ! 191: i++; p->xml++; ! 192: if ((p->xml + 1) >= p->xmlend) ! 193: return; ! 194: } ! 195: if(i>0 && p->datafunc && *(p->xml + 1) == '/') ! 196: p->datafunc(p->data, data, i); ! 197: } ! 198: } ! 199: } ! 200: else if(*p->xml == '/') ! 201: { ! 202: i = 0; elementname = ++p->xml; ! 203: if (p->xml >= p->xmlend) ! 204: return; ! 205: while((*p->xml != '>')) ! 206: { ! 207: i++; p->xml++; ! 208: if (p->xml >= p->xmlend) ! 209: return; ! 210: } ! 211: if(p->endeltfunc) ! 212: p->endeltfunc(p->data, elementname, i); ! 213: p->xml++; ! 214: } ! 215: } ! 216: else ! 217: { ! 218: p->xml++; ! 219: } ! 220: } ! 221: } ! 222: ! 223: /* the parser must be initialized before calling this function */ ! 224: void parsexml(struct xmlparser * parser) ! 225: { ! 226: parser->xml = parser->xmlstart; ! 227: parser->xmlend = parser->xmlstart + parser->xmlsize; ! 228: parseelt(parser); ! 229: } ! 230: ! 231: