fixed memory leaks.

comments in !DOCTYPE
This commit is contained in:
Ryu Sawada
2005-10-09 14:38:14 +00:00
parent 83e8ff05be
commit 4b7bbae2fc
2 changed files with 144 additions and 214 deletions
+141 -211
View File
@@ -1397,9 +1397,9 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error_size) int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
/* parse !ENTYTY entries of XML files and replace with references. Return NULL /* parse !ENTYTY entries of XML files and replace with references. Return 0
in case of error, return error description. Optional file_name is used in case of no errors, return error description. Optional file_name is used
for error reporting if called from mxml_parse_file() */ for error reporting if called from mxml_parse_file() */
{ {
char *p; char *p;
@@ -1425,22 +1425,37 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
line_number = 1; line_number = 1;
nentity = -1; nentity = -1;
strcpy(directoryname, mxml_dirname(file_name)); if (!buf || !(*buf) || !strlen(*buf))
return 0;
strcpy(directoryname, file_name);
mxml_dirname(directoryname);
/* copy string to temporary space */ /* copy string to temporary space */
buffer = (char *) malloc(strlen(*buf) + 1); buffer = (char *) malloc(strlen(*buf) + 1);
if (buffer == NULL) { if (buffer == NULL) {
return read_error(HERE, "Cannot allocate memory."); read_error(HERE, "Cannot allocate memory.");
return 1;
} }
strcpy(buffer, *buf); strcpy(buffer, *buf);
p = strstr(buffer, "!DOCTYPE"); p = strstr(buffer, "!DOCTYPE");
if (p == NULL) /* no entities */ if (p == NULL) { /* no entities */
return root; mxml_free_tree(root);
free(buffer);
for (ip = 0; ip < MXML_MAX_ENTITY; ip++)
free(entity_value[ip]);
return 0;
}
pv = strstr(p, "["); pv = strstr(p, "[");
if (pv == NULL) /* no entities */ if (pv == NULL) { /* no entities */
return root; mxml_free_tree(root);
free(buffer);
for (ip = 0; ip < MXML_MAX_ENTITY; ip++)
free(entity_value[ip]);
return 0;
}
free(*buf); free(*buf);
p = pv + 1; p = pv + 1;
@@ -1460,25 +1475,32 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
p++; p++;
} }
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (strncmp(p, "!ENTITY", 7) == 0) { if (strncmp(p, "!--", 3) == 0) {
/* found comment */
p += 3;
if (strstr(p, "-->") == NULL) {
read_error(HERE, "Unterminated comment");
return 1;
}
while (strncmp(p, "-->", 3) != 0) {
if (*p == '\n')
line_number++;
p++;
}
p += 3;
}
else if (strncmp(p, "!ENTITY", 7) == 0) {
/* found entity */ /* found entity */
nentity++; nentity++;
if (nentity >= MXML_MAX_ENTITY) { if (nentity >= MXML_MAX_ENTITY) {
/* read_error(HERE, "Too much entities");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Too much entities");
} }
pv = p + 7; pv = p + 7;
@@ -1494,20 +1516,12 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
p++; p++;
} }
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*p == '<' || *p == '>') { if (*p == '<' || *p == '>') {
/* read_error(HERE, "Unexpected \'%c\' inside !ENTITY", *p);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'%c\' inside !ENTITY", *p);
} }
pv = p; pv = p;
@@ -1515,21 +1529,12 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
pv++; pv++;
if (!*pv) { if (!*pv) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*pv == '<' || *pv == '>') { if (*pv == '<' || *pv == '>') {
/* read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv,
&entity_name[nentity][1]);
} }
len = (size_t) pv - (size_t) p; len = (size_t) pv - (size_t) p;
@@ -1543,20 +1548,12 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
entity_name[nentity][i] = 0; entity_name[nentity][i] = 0;
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*p == '<') { if (*p == '<') {
/* read_error(HERE, "Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]);
} }
/* extract replacement or SYSTEM */ /* extract replacement or SYSTEM */
@@ -1566,20 +1563,12 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
p++; p++;
} }
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*p == '>') { if (*p == '>') {
/* read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
} }
/* check if SYSTEM */ /* check if SYSTEM */
@@ -1597,72 +1586,42 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
p++; p++;
} }
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*p == '>') { if (*p == '>') {
/* read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
} }
if (*p != '\"' && *p != '\'') { if (*p != '\"' && *p != '\'') {
/* read_error(HERE, "Replacement was not found for entity \"%s\"", &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Replacement was not found for entity \"%s\"",
&entity_name[nentity][1]);
} }
delimiter = *p; delimiter = *p;
p++; p++;
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
pv = p; pv = p;
while (*pv && *pv != delimiter) while (*pv && *pv != delimiter)
pv++; pv++;
if (!*pv) { if (!*pv) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
if (*pv == '<') { if (*pv == '<') {
/* read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv,
&entity_name[nentity][1]);
} }
len = (size_t) pv - (size_t) p; len = (size_t) pv - (size_t) p;
replacement = (char *) malloc(len + 1); replacement = (char *) malloc(len + 1);
if (replacement == NULL) { if (replacement == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
memcpy(replacement, p, len); memcpy(replacement, p, len);
@@ -1674,12 +1633,8 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
} else { } else {
entity_value[nentity] = (char *) malloc(strlen(replacement)); entity_value[nentity] = (char *) malloc(strlen(replacement));
if (entity_value[nentity] == NULL) { if (entity_value[nentity] == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
strcpy(entity_value[nentity], replacement); strcpy(entity_value[nentity], replacement);
} }
@@ -1692,12 +1647,8 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
p++; p++;
} }
if (!*p) { if (!*p) {
/* read_error(HERE, "Unexpected end of file");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Unexpected end of file");
} }
} }
} }
@@ -1721,12 +1672,8 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
entity_value[i] = entity_value[i] =
(char *) malloc(strlen(entity_reference_name[i]) + strlen("<!-- is missing -->") + 1); (char *) malloc(strlen(entity_reference_name[i]) + strlen("<!-- is missing -->") + 1);
if (entity_value[i] == NULL) { if (entity_value[i] == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
sprintf(entity_value[i], "<!-- %s is missing -->", entity_reference_name[i]); sprintf(entity_value[i], "<!-- %s is missing -->", entity_reference_name[i]);
} else { } else {
@@ -1735,23 +1682,15 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
if (length == 0) { if (length == 0) {
entity_value[i] = (char *) malloc(1); entity_value[i] = (char *) malloc(1);
if (entity_value[i] == NULL) { if (entity_value[i] == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
entity_value[i][0] = 0; entity_value[i][0] = 0;
} else { } else {
entity_value[i] = (char *) malloc(length); entity_value[i] = (char *) malloc(length);
if (entity_value[i] == NULL) { if (entity_value[i] == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
/* read complete file at once */ /* read complete file at once */
@@ -1760,14 +1699,9 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
close(fh); close(fh);
/* recursive parse */ /* recursive parse */
root = mxml_parse_entity(&entity_value[i], filename, error, error_size); if (mxml_parse_entity(&entity_value[i], filename, error, error_size) != 0) {
if (root == NULL) { mxml_free_tree(root);
/* return 1;
free(buffer);
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return root;
} }
} }
} }
@@ -1792,12 +1726,8 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
/* allocate memory */ /* allocate memory */
*buf = (char *) malloc(length + 1); *buf = (char *) malloc(length + 1);
if (*buf == NULL) { if (*buf == NULL) {
/* read_error(HERE, "Cannot allocate memory.");
free(buffer); return 1;
for(ip=0;ip<MXML_MAX_ENTITY;ip++)
free(entity_value[ip]);
*/
return read_error(HERE, "Cannot allocate memory.");
} }
/* replace entities */ /* replace entities */
@@ -1823,7 +1753,8 @@ PMXML_NODE mxml_parse_entity(char **buf, char *file_name, char *error, int error
for (ip = 0; ip < MXML_MAX_ENTITY; ip++) for (ip = 0; ip < MXML_MAX_ENTITY; ip++)
free(entity_value[ip]); free(entity_value[ip]);
return root; mxml_free_tree(root);
return 0;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@@ -1864,10 +1795,9 @@ PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size)
buf[length] = 0; buf[length] = 0;
close(fh); close(fh);
root = mxml_parse_entity(&buf, file_name, error, error_size); if (mxml_parse_entity(&buf, file_name, error, error_size) != 0) {
if (root == NULL) {
free(buf); free(buf);
return root; return NULL;
} }
root = mxml_parse_buffer(buf, error, error_size); root = mxml_parse_buffer(buf, error, error_size);
@@ -2051,76 +1981,76 @@ void mxml_test()
*/ */
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* mxml_basename deletes any prefix ending with the last slash '/' character
present in path. mxml_dirname deletes the filename portion, beginning with
the last slash '/' character to the end of path. Followings are examples
from these functions
char* mxml_basename(char *path) path dirname basename
"/" "/" ""
"." "." "."
"" "" ""
"/test.txt" "/" "test.txt"
"path/to/test.txt" "path/to" "test.txt"
"test.txt "." "test.txt"
Under Windows, '\\' and ':' are recognized ad separator too. */
void mxml_basename(char *path)
{ {
char *p = path; char str[FILENAME_MAX];
char *name = path; char *p;
char *name;
if (path){ if (path) {
while(1){ strcpy(str, path);
switch(*p) { p = str;
case 0: return name; name = str;
case '/': while (1) {
if (*p == 0)
break;
if (*p == '/'
#ifdef _MSC_VER #ifdef _MSC_VER
case ':': || *p == ':' || *p == '\\'
case '\\':
#endif #endif
name = p + 1; )
} name = p + 1;
p++; p++;
} }
strcpy(path, name);
} }
return name;
return;
} }
/*------------------------------------------------------------------*/ void mxml_dirname(char *path)
char* mxml_dirname(char* path)
{ {
char *newpath;
char *p; char *p;
#ifdef _MSC_VER #ifdef _MSC_VER
char *pv; char *pv;
#endif #endif
int length;
p = strrchr (path, '/'); if (!path || strlen(path) == 0)
return;
p = strrchr(path, '/');
#ifdef _MSC_VER #ifdef _MSC_VER
pv = strrchr (path, ':'); pv = strrchr(path, ':');
if( pv > p ) if (pv > p)
p = pv; p = pv;
pv = strrchr (path, '\\'); pv = strrchr(path, '\\');
if( pv > p ) if (pv > p)
p = pv; p = pv;
#endif #endif
if (p == 0) if (p == 0) /* current directory */
{ strcpy(path, ".");
newpath = (char *) malloc(2); else if (p == path) /* root directory */
if (newpath == 0) sprintf(path, "%c", *p);
return NULL;
newpath[0] = '.';
newpath[1] = 0;
}
else if(p == path){ /* root directory */
newpath = (char *) malloc(2);
if (newpath == 0)
return NULL;
newpath[0] = *p;
newpath[1] = 0;
}
else else
{ *p = 0;
p--;
length = p - path + 1; return;
newpath = (char *) malloc(length + 1);
if (newpath == 0)
return NULL;
strncpy (newpath, path, length);
newpath[length] = 0;
}
return newpath;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
+3 -3
View File
@@ -94,11 +94,11 @@ int mxml_delete_attribute(PMXML_NODE, char *attrib_name);
PMXML_NODE mxml_create_root_node(); PMXML_NODE mxml_create_root_node();
PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size); PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size);
PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size); PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size);
PMXML_NODE mxml_parse_entity(char **buf, char* file_name, char *error, int error_size); int mxml_parse_entity(char **buf, char* file_name, char *error, int error_size);
int mxml_write_tree(char *file_name, PMXML_NODE tree); int mxml_write_tree(char *file_name, PMXML_NODE tree);
void mxml_debug_tree(PMXML_NODE tree, int level); void mxml_debug_tree(PMXML_NODE tree, int level);
void mxml_free_tree(PMXML_NODE tree); void mxml_free_tree(PMXML_NODE tree);
char* mxml_dirname(char* path); void mxml_dirname(char* path);
char* mxml_basename(char *path); void mxml_basename(char *path);
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/