| OLD | NEW |
| 1 /* | 1 /* |
| 2 * buf.c: memory buffers for libxml2 | 2 * buf.c: memory buffers for libxml2 |
| 3 * | 3 * |
| 4 * new buffer structures and entry points to simplify the maintainance | 4 * new buffer structures and entry points to simplify the maintainance |
| 5 * of libxml2 and ensure we keep good control over memory allocations | 5 * of libxml2 and ensure we keep good control over memory allocations |
| 6 * and stay 64 bits clean. | 6 * and stay 64 bits clean. |
| 7 * The new entry point use the xmlBufPtr opaque structure and | 7 * The new entry point use the xmlBufPtr opaque structure and |
| 8 * xmlBuf...() counterparts to the old xmlBuf...() functions | 8 * xmlBuf...() counterparts to the old xmlBuf...() functions |
| 9 * | 9 * |
| 10 * See Copyright for the status of this software. | 10 * See Copyright for the status of this software. |
| 11 * | 11 * |
| 12 * daniel@veillard.com | 12 * daniel@veillard.com |
| 13 */ | 13 */ |
| 14 | 14 |
| 15 #define IN_LIBXML | 15 #define IN_LIBXML |
| 16 #include "libxml.h" | 16 #include "libxml.h" |
| 17 | 17 |
| 18 #include <string.h> /* for memset() only ! */ | 18 #include <string.h> /* for memset() only ! */ |
| 19 #include <limits.h> | 19 #include <limits.h> |
| 20 #ifdef HAVE_CTYPE_H | 20 #ifdef HAVE_CTYPE_H |
| 21 #include <ctype.h> | 21 #include <ctype.h> |
| 22 #endif | 22 #endif |
| 23 #ifdef HAVE_STDLIB_H | 23 #ifdef HAVE_STDLIB_H |
| 24 #include <stdlib.h> | 24 #include <stdlib.h> |
| 25 #endif | 25 #endif |
| 26 | 26 |
| 27 #include <libxml/tree.h> | 27 #include <libxml/tree.h> |
| 28 #include <libxml/globals.h> | 28 #include <libxml/globals.h> |
| 29 #include <libxml/tree.h> | 29 #include <libxml/tree.h> |
| 30 #include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */ |
| 30 #include "buf.h" | 31 #include "buf.h" |
| 31 | 32 |
| 32 #define WITH_BUFFER_COMPAT | 33 #define WITH_BUFFER_COMPAT |
| 33 | 34 |
| 34 /** | 35 /** |
| 35 * xmlBuf: | 36 * xmlBuf: |
| 36 * | 37 * |
| 37 * A buffer structure. The base of the structure is somehow compatible | 38 * A buffer structure. The base of the structure is somehow compatible |
| 38 * with struct _xmlBuffer to limit risks on application which accessed | 39 * with struct _xmlBuffer to limit risks on application which accessed |
| 39 * directly the input->buf->buffer structures. | 40 * directly the input->buf->buffer structures. |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 "xmlBufSetAllocationScheme: buf == NULL or in error\n"); | 293 "xmlBufSetAllocationScheme: buf == NULL or in error\n"); |
| 293 #endif | 294 #endif |
| 294 return(-1); | 295 return(-1); |
| 295 } | 296 } |
| 296 if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) || | 297 if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) || |
| 297 (buf->alloc == XML_BUFFER_ALLOC_IO)) | 298 (buf->alloc == XML_BUFFER_ALLOC_IO)) |
| 298 return(-1); | 299 return(-1); |
| 299 if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) || | 300 if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) || |
| 300 (scheme == XML_BUFFER_ALLOC_EXACT) || | 301 (scheme == XML_BUFFER_ALLOC_EXACT) || |
| 301 (scheme == XML_BUFFER_ALLOC_HYBRID) || | 302 (scheme == XML_BUFFER_ALLOC_HYBRID) || |
| 302 (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) { | 303 (scheme == XML_BUFFER_ALLOC_IMMUTABLE) || |
| 304 » (scheme == XML_BUFFER_ALLOC_BOUNDED)) { |
| 303 buf->alloc = scheme; | 305 buf->alloc = scheme; |
| 304 if (buf->buffer) | 306 if (buf->buffer) |
| 305 buf->buffer->alloc = scheme; | 307 buf->buffer->alloc = scheme; |
| 306 return(0); | 308 return(0); |
| 307 } | 309 } |
| 308 /* | 310 /* |
| 309 * Switching a buffer ALLOC_IO has the side effect of initializing | 311 * Switching a buffer ALLOC_IO has the side effect of initializing |
| 310 * the contentIO field with the current content | 312 * the contentIO field with the current content |
| 311 */ | 313 */ |
| 312 if (scheme == XML_BUFFER_ALLOC_IO) { | 314 if (scheme == XML_BUFFER_ALLOC_IO) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 */ | 453 */ |
| 452 #if 1 | 454 #if 1 |
| 453 if (buf->size > (size_t) len) | 455 if (buf->size > (size_t) len) |
| 454 size = buf->size * 2; | 456 size = buf->size * 2; |
| 455 else | 457 else |
| 456 size = buf->use + len + 100; | 458 size = buf->use + len + 100; |
| 457 #else | 459 #else |
| 458 size = buf->use + len + 100; | 460 size = buf->use + len + 100; |
| 459 #endif | 461 #endif |
| 460 | 462 |
| 463 if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { |
| 464 /* |
| 465 * Used to provide parsing limits |
| 466 */ |
| 467 if ((buf->use + len >= XML_MAX_TEXT_LENGTH) || |
| 468 (buf->size >= XML_MAX_TEXT_LENGTH)) { |
| 469 xmlBufMemoryError(buf, "buffer error: text too long\n"); |
| 470 return(0); |
| 471 } |
| 472 if (size >= XML_MAX_TEXT_LENGTH) |
| 473 size = XML_MAX_TEXT_LENGTH; |
| 474 } |
| 461 if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { | 475 if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { |
| 462 size_t start_buf = buf->content - buf->contentIO; | 476 size_t start_buf = buf->content - buf->contentIO; |
| 463 | 477 |
| 464 newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size); | 478 newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size); |
| 465 if (newbuf == NULL) { | 479 if (newbuf == NULL) { |
| 466 xmlBufMemoryError(buf, "growing buffer"); | 480 xmlBufMemoryError(buf, "growing buffer"); |
| 467 return(0); | 481 return(0); |
| 468 } | 482 } |
| 469 buf->contentIO = newbuf; | 483 buf->contentIO = newbuf; |
| 470 buf->content = newbuf + start_buf; | 484 buf->content = newbuf + start_buf; |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 { | 746 { |
| 733 unsigned int newSize; | 747 unsigned int newSize; |
| 734 xmlChar* rebuf = NULL; | 748 xmlChar* rebuf = NULL; |
| 735 size_t start_buf; | 749 size_t start_buf; |
| 736 | 750 |
| 737 if ((buf == NULL) || (buf->error)) | 751 if ((buf == NULL) || (buf->error)) |
| 738 return(0); | 752 return(0); |
| 739 CHECK_COMPAT(buf) | 753 CHECK_COMPAT(buf) |
| 740 | 754 |
| 741 if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); | 755 if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); |
| 756 if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { |
| 757 /* |
| 758 * Used to provide parsing limits |
| 759 */ |
| 760 if (size >= XML_MAX_TEXT_LENGTH) { |
| 761 xmlBufMemoryError(buf, "buffer error: text too long\n"); |
| 762 return(0); |
| 763 } |
| 764 } |
| 742 | 765 |
| 743 /* Don't resize if we don't have to */ | 766 /* Don't resize if we don't have to */ |
| 744 if (size < buf->size) | 767 if (size < buf->size) |
| 745 return 1; | 768 return 1; |
| 746 | 769 |
| 747 /* figure out new size */ | 770 /* figure out new size */ |
| 748 switch (buf->alloc){ | 771 switch (buf->alloc){ |
| 749 case XML_BUFFER_ALLOC_IO: | 772 case XML_BUFFER_ALLOC_IO: |
| 750 case XML_BUFFER_ALLOC_DOUBLEIT: | 773 case XML_BUFFER_ALLOC_DOUBLEIT: |
| 751 /*take care of empty case*/ | 774 /*take care of empty case*/ |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 if (len == 0) return 0; | 883 if (len == 0) return 0; |
| 861 | 884 |
| 862 if (len < 0) | 885 if (len < 0) |
| 863 len = xmlStrlen(str); | 886 len = xmlStrlen(str); |
| 864 | 887 |
| 865 if (len < 0) return -1; | 888 if (len < 0) return -1; |
| 866 if (len == 0) return 0; | 889 if (len == 0) return 0; |
| 867 | 890 |
| 868 needSize = buf->use + len + 2; | 891 needSize = buf->use + len + 2; |
| 869 if (needSize > buf->size){ | 892 if (needSize > buf->size){ |
| 893 if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { |
| 894 /* |
| 895 * Used to provide parsing limits |
| 896 */ |
| 897 if (needSize >= XML_MAX_TEXT_LENGTH) { |
| 898 xmlBufMemoryError(buf, "buffer error: text too long\n"); |
| 899 return(-1); |
| 900 } |
| 901 } |
| 870 if (!xmlBufResize(buf, needSize)){ | 902 if (!xmlBufResize(buf, needSize)){ |
| 871 xmlBufMemoryError(buf, "growing buffer"); | 903 xmlBufMemoryError(buf, "growing buffer"); |
| 872 return XML_ERR_NO_MEMORY; | 904 return XML_ERR_NO_MEMORY; |
| 873 } | 905 } |
| 874 } | 906 } |
| 875 | 907 |
| 876 memmove(&buf->content[buf->use], str, len*sizeof(xmlChar)); | 908 memmove(&buf->content[buf->use], str, len*sizeof(xmlChar)); |
| 877 buf->use += len; | 909 buf->use += len; |
| 878 buf->content[buf->use] = 0; | 910 buf->content[buf->use] = 0; |
| 879 UPDATE_COMPAT(buf) | 911 UPDATE_COMPAT(buf) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 buf->content -= len; | 963 buf->content -= len; |
| 932 memmove(&buf->content[0], str, len); | 964 memmove(&buf->content[0], str, len); |
| 933 buf->use += len; | 965 buf->use += len; |
| 934 buf->size += len; | 966 buf->size += len; |
| 935 UPDATE_COMPAT(buf) | 967 UPDATE_COMPAT(buf) |
| 936 return(0); | 968 return(0); |
| 937 } | 969 } |
| 938 } | 970 } |
| 939 needSize = buf->use + len + 2; | 971 needSize = buf->use + len + 2; |
| 940 if (needSize > buf->size){ | 972 if (needSize > buf->size){ |
| 973 if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { |
| 974 /* |
| 975 * Used to provide parsing limits |
| 976 */ |
| 977 if (needSize >= XML_MAX_TEXT_LENGTH) { |
| 978 xmlBufMemoryError(buf, "buffer error: text too long\n"); |
| 979 return(-1); |
| 980 } |
| 981 } |
| 941 if (!xmlBufResize(buf, needSize)){ | 982 if (!xmlBufResize(buf, needSize)){ |
| 942 xmlBufMemoryError(buf, "growing buffer"); | 983 xmlBufMemoryError(buf, "growing buffer"); |
| 943 return XML_ERR_NO_MEMORY; | 984 return XML_ERR_NO_MEMORY; |
| 944 } | 985 } |
| 945 } | 986 } |
| 946 | 987 |
| 947 memmove(&buf->content[len], &buf->content[0], buf->use); | 988 memmove(&buf->content[len], &buf->content[0], buf->use); |
| 948 memmove(&buf->content[0], str, len); | 989 memmove(&buf->content[0], str, len); |
| 949 buf->use += len; | 990 buf->use += len; |
| 950 buf->content[buf->use] = 0; | 991 buf->content[buf->use] = 0; |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1295 return(-1); | 1336 return(-1); |
| 1296 CHECK_COMPAT(buf) | 1337 CHECK_COMPAT(buf) |
| 1297 input->base = &buf->content[base]; | 1338 input->base = &buf->content[base]; |
| 1298 input->cur = input->base + cur; | 1339 input->cur = input->base + cur; |
| 1299 input->end = &buf->content[buf->use]; | 1340 input->end = &buf->content[buf->use]; |
| 1300 return(0); | 1341 return(0); |
| 1301 } | 1342 } |
| 1302 | 1343 |
| 1303 #define bottom_buf | 1344 #define bottom_buf |
| 1304 #include "elfgcchack.h" | 1345 #include "elfgcchack.h" |
| OLD | NEW |