--- psiconv/trunk/lib/psiconv/parse_common.c 2000/12/13 16:30:21 63 +++ psiconv/trunk/lib/psiconv/parse_common.c 2000/12/15 00:21:51 64 @@ -41,10 +41,13 @@ psiconv_u32 temp; psiconv_progress(lev+1,off+len,"Going to read the header section"); - (*result) = malloc(sizeof(**result)); + if (!((*result) = malloc(sizeof(**result)))) + goto ERROR1; psiconv_progress(lev+2,off+len,"Going to read UID1 to UID3"); - (*result)->uid1 = psiconv_read_u32(buf,lev+2,off+len); + (*result)->uid1 = psiconv_read_u32(buf,lev+2,off+len,&res); + if (!res) + goto ERROR2; psiconv_debug(lev+2,off+len,"UID1: %08x",(*result)->uid1); if ((*result)->uid1 == PSICONV_ID_CLIPART) { /* That's all folks... */ @@ -59,13 +62,18 @@ if ((*result)->uid1 != PSICONV_ID_PSION5) { psiconv_warn(lev+2,off+len,"UID1 has unknown value. This is probably " "not a (parsable) Psion 5 file"); - res = -1; + res = -PSICONV_E_PARSE; + goto ERROR2; } len += 4; - (*result)->uid2 = psiconv_read_u32(buf,lev+2,off+len); + (*result)->uid2 = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"UID2: %08x",(*result)->uid2); len += 4; - (*result)->uid3 = psiconv_read_u32(buf,lev+2,off+len); + (*result)->uid3 = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"UID3: %08x",(*result)->uid3); len += 4; @@ -95,7 +103,9 @@ } psiconv_progress(lev+2,off+len,"Checking UID4"); - temp = psiconv_read_u32(buf,lev+2,off+len); + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; if (temp == psiconv_checkuid((*result)->uid1,(*result)->uid2, (*result)->uid3)) psiconv_debug(lev+2,off+len,"Checksum %08x is correct",temp); @@ -104,7 +114,8 @@ psiconv_debug(lev+2,off+len,"Expected checksum %08x, found %08x", psiconv_checkuid((*result)->uid1,(*result)->uid2, (*result)->uid3),temp); - res = -1; + res = -PSICONV_E_PARSE; + goto ERROR2; } len += 4; @@ -116,6 +127,17 @@ "End of Header Section (total length: %08x)",len); return res; + +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Header Section failed"); + if (length) + *length = 0; + if (res == 0) + return -PSICONV_E_NOMEM; + else + return res; } int psiconv_parse_section_table_section(const psiconv_buffer buf, int lev, @@ -130,28 +152,35 @@ psiconv_u8 nr; psiconv_progress(lev+1,off+len,"Going to read the section table section"); - *result = psiconv_list_new(sizeof(*entry)); + if (!(*result = psiconv_list_new(sizeof(*entry)))) + goto ERROR1; psiconv_progress(lev+2,off+len,"Going to read the section table length"); - nr = psiconv_read_u8(buf,lev+2,off+len); + nr = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"Length: %08x",nr); if (nr & 0x01) { psiconv_warn(lev+2,off+len, "Section table length odd - ignoring last entry"); - res = -1; } len ++; psiconv_progress(lev+2,off+len,"Going to read the section table entries"); entry = malloc(sizeof(*entry)); for (i = 0; i < nr / 2; i++) { - entry->id = psiconv_read_u32(buf,lev+2,off + len); + entry->id = psiconv_read_u32(buf,lev+2,off + len,&res); + if (res) + goto ERROR3; psiconv_debug(lev+2,off + len,"Entry %d: ID = %08x",i,entry->id); len += 0x04; - entry->offset = psiconv_read_u32(buf,lev+2,off + len); + entry->offset = psiconv_read_u32(buf,lev+2,off + len,&res); + if (res) + goto ERROR3; psiconv_debug(lev+2,off +len,"Entry %d: Offset = %08x",i,entry->offset); len += 0x04; - psiconv_list_add(*result,entry); + if ((res=psiconv_list_add(*result,entry))) + goto ERROR3; } free(entry); @@ -162,7 +191,19 @@ psiconv_progress(lev+1,off+len-1,"End of section table section " "(total length: %08x)", len); - return res; + return 0; +ERROR3: + free(entry); +ERROR2: + psiconv_list_free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Section Table Section failed"); + if (length) + *length = 0; + if (res == 0) + return -PSICONV_E_NOMEM; + else + return res; } int psiconv_parse_application_id_section(const psiconv_buffer buf, int lev, @@ -174,15 +215,20 @@ int leng; psiconv_progress(lev+1,off,"Going to read the application id section"); - (*result) = malloc(sizeof(**result)); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; psiconv_progress(lev+2,off+len,"Going to read the type identifier"); - (*result)->id = psiconv_read_u32(buf,lev+2,off+len); + (*result)->id = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"Identifier: %08x",(*result)->id); len += 4; psiconv_progress(lev+2,off+len,"Going to read the application id string"); - (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng); + (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; len += leng; if (length) @@ -192,6 +238,16 @@ "(total length: %08x", len); return res; +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Application ID Section failed"); + if (length) + *length = 0; + if (res == 0) + return -PSICONV_E_NOMEM; + else + return res; } int psiconv_parse_text_section(const psiconv_buffer buf,int lev,psiconv_u32 off, @@ -205,31 +261,46 @@ psiconv_paragraph para; int nr; - int i,j,start,leng; + int i,j,start,leng,temp; char *str_copy; psiconv_progress(lev+1,off,"Going to parse the text section"); psiconv_progress(lev+2,off,"Reading the text length"); - text_len = psiconv_read_X(buf,lev+2,off,&leng); + + if(!(*result = psiconv_list_new(sizeof(*para)))) + goto ERROR1; + if (!(para = malloc(sizeof(*para)))) + goto ERROR2; + + text_len = psiconv_read_X(buf,lev+2,off,&leng,&res); + if (!res) + goto ERROR3; psiconv_debug(lev+2,off,"Length: %08x",text_len); len += leng; - *result = psiconv_list_new(sizeof(*para)); - para = malloc(sizeof(*para)); - psiconv_progress(lev+2,off+len,"Going to read all paragraph text"); nr = 0; start = 0; - for (i = 0; i < text_len; i++) - if (psiconv_read_u8(buf,lev+2,off+len+i) == 0x06) { - para->text = malloc(i - start + 1); - for (j = 0; j < i - start; j++) - para->text[j] = psiconv_read_u8(buf,lev+1,off + len + start + j); + for (i = 0; i < text_len; i++) { + temp = psiconv_read_u8(buf,lev+2,off+len+i,&res); + if (res) + goto ERROR3; + if (temp == 0x06) { + if (!(para->text = malloc(i - start + 1))) + goto ERROR3; + for (j = 0; j < i - start; j++) { + temp = psiconv_read_u8(buf,lev+1,off + len + start + j,&res); + if (res) + goto ERROR4; + para->text[j] = temp; + } para->text[j] = 0; - psiconv_list_add(*result,para); + if ((res = psiconv_list_add(*result,para))) + goto ERROR4; - str_copy = psiconv_make_printable(para->text); + if (!(str_copy = psiconv_make_printable(para->text))) + goto ERROR3; psiconv_debug(lev+2,off+i+len,"Line %d: %d characters",nr, strlen(str_copy) +1); psiconv_debug(lev+2,off+i+len,"Line %d: `%s'",nr,str_copy); @@ -238,17 +309,24 @@ start = i + 1; nr ++; } + } if (start != text_len) { - res = -1; psiconv_warn(lev+2,off+start+len, "Last line does not end on EOL (%d characters left)", len - start); - para->text = malloc(text_len - start + 1); - for (j = 0; j < text_len - start; j++) - para->text[j] = psiconv_read_u8(buf,lev+2,off + start + j + len); + if (!(para->text = malloc(text_len - start + 1))) + goto ERROR3; + for (j = 0; j < text_len - start; j++) { + temp = psiconv_read_u8(buf,lev+2,off + start + j + len, &res); + if (res) + goto ERROR4; + para->text[j] = temp; + } para->text[text_len - start] = 0; - psiconv_list_add(*result,para); - str_copy = psiconv_make_printable(para->text); + if ((res = psiconv_list_add(*result,para))) + goto ERROR4; + if (!(str_copy = psiconv_make_printable(para->text))) + goto ERROR3; psiconv_debug(lev+2,off+start+len,"Last line: %d characters",nr, strlen(str_copy)+1); psiconv_debug(lev+2,off+start+len,"Last line: `%s'",str_copy); @@ -259,12 +337,21 @@ /* Initialize the remaining parts of each paragraph */ for (i = 0; i < psiconv_list_length(*result); i ++) { - para = psiconv_list_get(*result,i); - para->in_lines = psiconv_list_new(sizeof(struct psiconv_in_line_layout_s)); - para->replacements = psiconv_list_new(sizeof(struct psiconv_replacement_s)); + if (!(para = psiconv_list_get(*result,i))) { + psiconv_warn(lev+2,off+len,"Massive memory corruption"); + goto ERROR2_0; + } + if (!(para->in_lines = psiconv_list_new(sizeof( + struct psiconv_in_line_layout_s)))) + goto ERROR2_0; + if (!(para->replacements = psiconv_list_new(sizeof( + struct psiconv_replacement_s)))) + goto ERROR2_1; + if (!(para->base_character = psiconv_basic_character_layout())) + goto ERROR2_2; + if (!(para->base_paragraph = psiconv_basic_paragraph_layout())) + goto ERROR2_3; para->base_style = 0; - para->base_character = psiconv_basic_character_layout(); - para->base_paragraph = psiconv_basic_paragraph_layout(); } @@ -277,6 +364,47 @@ len); return res; + +ERROR2_3: + psiconv_free_character_layout(para->base_character); +ERROR2_2: + psiconv_list_free(para->replacements); +ERROR2_1: + psiconv_list_free(para->in_lines); +ERROR2_0: + for (j = 0; j < i; j++) { + if (!(para = psiconv_list_get(*result,j))) { + psiconv_warn(lev+1,off,"Massive memory corruption..."); + break; + } + psiconv_list_free(para->in_lines); + psiconv_list_free(para->replacements); + psiconv_free_character_layout(para->base_character); + psiconv_free_paragraph_layout(para->base_paragraph); + } + goto ERROR2; + +ERROR4: + free(para->text); +ERROR3: + free(para); +ERROR2: + for (i = 0; i < psiconv_list_length(*result);i++) { + if (!(para = psiconv_list_get(*result,i))) { + psiconv_warn(lev+1,off,"Massive memory corruption..."); + break; + } + free(para->text); + } + psiconv_list_free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Text Section failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } /* First do a parse_text_section, or you will get into trouble here */ @@ -306,6 +434,9 @@ struct anon_style_s anon; anon_style anon_ptr=NULL; + psiconv_character_layout temp_char; + psiconv_paragraph_layout temp_para; + psiconv_word_style temp_style; psiconv_paragraph para; struct psiconv_in_line_layout_s in_line; @@ -315,30 +446,32 @@ psiconv_progress(lev+1,off,"Going to read the layout section"); psiconv_progress(lev+2,off,"Going to read the section type"); - temp = psiconv_read_u16(buf,lev+2,off+len); + temp = psiconv_read_u16(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; psiconv_debug(lev+2,off+len,"Type: %02x",temp); parse_styles = with_styles; if ((temp == 0x0001) && !with_styles) { psiconv_warn(lev+2,off+len,"Styleless layout section expected, " "but styled section found!"); parse_styles = 1; - res = -1; } else if ((temp == 0x0000) && (with_styles)) { psiconv_warn(lev+2,off+len,"Styled layout section expected, " "but styleless section found!"); parse_styles = 0; - res = -1; } else if ((temp != 0x0000) && (temp != 0x0001)) { psiconv_warn(lev+2,off+len, "Layout section type indicator has unknown value!"); - res = -1; } len += 0x02; psiconv_progress(lev+2,off+len,"Going to read paragraph type list"); - anon_styles = psiconv_list_new(sizeof(anon)); + if (!(anon_styles = psiconv_list_new(sizeof(anon)))) + goto ERROR1; psiconv_progress(lev+3,off+len,"Going to read paragraph type list length"); - nr = psiconv_read_u8(buf,lev+3,off+len); + nr = psiconv_read_u8(buf,lev+3,off+len,&res); + if (res) + goto ERROR2; psiconv_debug(lev+3,off+len,"Length: %02x",nr); len ++; @@ -346,41 +479,60 @@ "Going to read the paragraph type list elements"); for (i = 0; i < nr; i ++) { psiconv_progress(lev+3,off+len,"Element %d",i); - anon.nr = psiconv_read_u32(buf,lev+4,off+len); + anon.nr = psiconv_read_u32(buf,lev+4,off+len,&res); + if (res) + goto ERROR3; psiconv_debug(lev+4,off+len,"Number: %08x",anon.nr); len += 0x04; psiconv_progress(lev+4,off,"Going to determine the base style"); if (parse_styles) { - anon.base_style = psiconv_read_u8(buf,lev+3, - off+len+4+psiconv_read_u32(buf,lev+4, - off+len)); - psiconv_debug(lev+4,off+len+psiconv_read_u32(buf,lev+4,off+len), + temp = psiconv_read_u32(buf,lev+4, off+len,&res); + if (res) + goto ERROR3; + anon.base_style = psiconv_read_u8(buf,lev+3, off+len+4+temp,&res); + if (res) + goto ERROR3; + psiconv_debug(lev+4,off+len+temp, "Style indicator: %02x",anon.base_style); } else anon.base_style = 0; - anon.paragraph = psiconv_clone_paragraph_layout(psiconv_get_style - (styles,anon.base_style)->paragraph); - anon.character = psiconv_clone_character_layout(psiconv_get_style - (styles,anon.base_style)->character); + if (!(temp_style = psiconv_get_style(styles,anon.base_style))) { + psiconv_warn(lev+4,off,"Unknown Style referenced"); + if (!(temp_style = psiconv_get_style(styles,anon.base_style))) { + psiconv_warn(lev+4,off,"Base style unknown"); + goto ERROR3; + } + } + if (!(anon.paragraph = psiconv_clone_paragraph_layout + (temp_style->paragraph))) + goto ERROR3; + if (!(anon.character = psiconv_clone_character_layout + (temp_style->character))) + goto ERROR3_1; psiconv_progress(lev+4,off+len,"Going to read the paragraph layout"); - res |= psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng, - anon.paragraph); + if ((res = psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng, + anon.paragraph))) + goto ERROR3_2; len += leng; if (parse_styles) len ++; psiconv_progress(lev+4,off+len,"Going to read the character layout"); - res |= psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, - anon.character); + if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, + anon.character))) + goto ERROR3_2; len += leng; - psiconv_list_add(anon_styles,&anon); + if ((res = psiconv_list_add(anon_styles,&anon))) + goto ERROR3_2; } psiconv_progress(lev+2,off+len,"Going to parse the paragraph element list"); psiconv_progress(lev+3,off+len,"Going to read the number of paragraphs"); - nr = psiconv_read_u32(buf,lev+3,off+len); + nr = psiconv_read_u32(buf,lev+3,off+len,&res); + if (res) + goto ERROR3; if (nr != psiconv_list_length(result)) { psiconv_warn(lev+3,off+len, "Number of text paragraphs and paragraph elements does not match"); @@ -390,26 +542,36 @@ } psiconv_debug(lev+3,off+len,"Number of paragraphs: %d",nr); len += 4; - inline_count = malloc(nr * sizeof(*inline_count)); + if (!(inline_count = malloc(nr * sizeof(*inline_count)))) + goto ERROR3; psiconv_progress(lev+3,off+len,"Going to read the paragraph elements"); for (i = 0; i < nr; i ++) { psiconv_progress(lev+3,off+len,"Element %d",i); if (i >= psiconv_list_length(result)) { psiconv_debug(lev+4,off+len,"Going to allocate a new element"); - para = malloc(sizeof(*para)); - para->in_lines = psiconv_list_new(sizeof(struct psiconv_in_line_layout_s)); + if (!(para = malloc(sizeof(*para)))) + goto ERROR4; + if (!(para->in_lines = psiconv_list_new(sizeof( + struct psiconv_in_line_layout_s)))) + goto ERROR4_1; para->base_style = 0; - para->base_character = psiconv_basic_character_layout(); - para->base_paragraph = psiconv_basic_paragraph_layout(); + if (!(para->base_character = psiconv_basic_character_layout())) + goto ERROR4_2; + if (!(para->base_paragraph = psiconv_basic_paragraph_layout())) + goto ERROR4_3; + if ((res = psiconv_list_add(result,para))) + goto ERROR4_4; free(para); } - para = psiconv_list_get(result,i); + if (!(para = psiconv_list_get(result,i))) + goto ERROR4; psiconv_progress(lev+4,off+len,"Going to read the paragraph length"); - temp = psiconv_read_u32(buf,lev+4,off+len); + temp = psiconv_read_u32(buf,lev+4,off+len,&res); + if (!res) + goto ERROR4; if (temp != strlen(para->text)+1) { - res = -1; psiconv_warn(lev+4,off+len, "Disagreement of the length of paragraph in layout section"); psiconv_debug(lev+4,off+len, @@ -420,11 +582,16 @@ len += 4; psiconv_progress(lev+4,off+len,"Going to read the paragraph type"); - temp = psiconv_read_u8(buf,lev+4,off+len); + temp = psiconv_read_u8(buf,lev+4,off+len,&res); + if (!res) + goto ERROR4; if (temp != 0x00) { psiconv_debug(lev+4,off+len,"Type: %02x",temp); for (j = 0; j < psiconv_list_length(anon_styles); j++) { - anon_ptr = psiconv_list_get(anon_styles,j); + if (!(anon_ptr = psiconv_list_get(anon_styles,j))) { + psiconv_warn(lev+4,off+len,"Massive memory curruption"); + goto ERROR4; + } if (temp == anon_ptr->nr) break; } @@ -432,20 +599,32 @@ psiconv_warn(lev+4,off+len,"Layout section paragraph type unknown"); psiconv_debug(lev+4,off+len,"Unknown type - using base styles instead"); para->base_style = 0; + if (!(temp_style = psiconv_get_style(styles,0))) { + psiconv_warn(lev+4,off,"Base style unknown"); + goto ERROR4; + } + if (!(temp_para = psiconv_clone_paragraph_layout + (temp_style->paragraph))) + goto ERROR4; psiconv_free_paragraph_layout(para->base_paragraph); + para->base_paragraph = temp_para; + + if (!(temp_char = psiconv_clone_character_layout + (temp_style->character))) + goto ERROR4; psiconv_free_character_layout(para->base_character); - para->base_paragraph = psiconv_clone_paragraph_layout(psiconv_get_style - (styles,0)->paragraph); - para->base_character = psiconv_clone_character_layout(psiconv_get_style - (styles,0)->character); + para->base_character = temp_char; } else { para->base_style = anon_ptr->base_style; + if (!(temp_para = psiconv_clone_paragraph_layout (anon_ptr->paragraph))) + goto ERROR4; psiconv_free_paragraph_layout(para->base_paragraph); + para->base_paragraph = temp_para; + + if (!(temp_char = psiconv_clone_character_layout (anon_ptr->character))) + goto ERROR4; psiconv_free_character_layout(para->base_character); - para->base_paragraph = psiconv_clone_paragraph_layout - (anon_ptr->paragraph); - para->base_character = psiconv_clone_character_layout - (anon_ptr->character); + para->base_character = temp_char; } inline_count[i] = 0; len += 0x01; @@ -454,30 +633,49 @@ ,temp); len += 0x01; if (parse_styles) { - psiconv_progress(lev+4,off+len+psiconv_read_u32(buf,lev+4,off+len)+4, + temp = psiconv_read_u32(buf,lev+4,off+len,&res); + if (res) + goto ERROR4; + psiconv_progress(lev+4,off+len+temp+4, "Going to read the paragraph element base style"); - temp = psiconv_read_u8(buf,lev+4, - off+len+psiconv_read_u32(buf,lev+4,off+len)+4); - psiconv_debug(lev+4,off+len+psiconv_read_u32(buf,lev+4,off+len)+4, - "Style: %02x",temp); + temp = psiconv_read_u8(buf,lev+4, off+len+temp+4,&res); + if (res) + goto ERROR4; + psiconv_debug(lev+4,off+len+temp+4, "Style: %02x",temp); } else temp = 0x00; + + if (!(temp_style = psiconv_get_style (styles,temp))) { + psiconv_warn(lev+4,off,"Unknown Style referenced"); + if (!(temp_style = psiconv_get_style(styles,0))) { + psiconv_warn(lev+4,off,"Base style unknown"); + goto ERROR4; + } + } + + if (!(temp_para = psiconv_clone_paragraph_layout(temp_style->paragraph))) + goto ERROR4; psiconv_free_paragraph_layout(para->base_paragraph); + para->base_paragraph = temp_para; + + if (!(temp_char = psiconv_clone_character_layout(temp_style->character))) + goto ERROR4; psiconv_free_character_layout(para->base_character); - para->base_paragraph = psiconv_clone_paragraph_layout(psiconv_get_style - (styles,temp)->paragraph); - para->base_character = psiconv_clone_character_layout(psiconv_get_style - (styles,temp)->character); + para->base_character = temp_char; + para->base_style = temp; psiconv_progress(lev+4,off+len,"Going to read paragraph layout"); - psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng, - para->base_paragraph); + if (!(psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng, + para->base_paragraph))) + goto ERROR4; len += leng; if (parse_styles) len += 1; psiconv_progress(lev+4,off+len,"Going to read number of in-line " "layout elements"); - inline_count[i] = psiconv_read_u32(buf,lev+4,off+len); + inline_count[i] = psiconv_read_u32(buf,lev+4,off+len,&res); + if (res) + goto ERROR4; psiconv_debug(lev+4,off+len,"Nr: %08x",inline_count[i]); len += 4; } @@ -486,7 +684,9 @@ psiconv_progress(lev+2,off+len,"Going to read the text layout inline list"); psiconv_progress(lev+3,off+len,"Going to read the number of elements"); - nr = psiconv_read_u32(buf,lev+3,off+len); + nr = psiconv_read_u32(buf,lev+3,off+len,&res); + if (res) + goto ERROR4; psiconv_debug(lev+3,off,"Elements: %08x",nr); len += 0x04; @@ -494,7 +694,10 @@ "Going to read the text layout inline elements"); total = 0; for (i = 0; i < psiconv_list_length(result); i++) { - para = psiconv_list_get(result,i); + if (!(para = psiconv_list_get(result,i))) { + psiconv_warn(lev+3,off+len,"Massive memory corruption"); + goto ERROR4; + } line_length = -1; for (j = 0; j < inline_count[i]; j++) { psiconv_progress(lev+3,off+len,"Element %d: Paragraph %d, element %d", @@ -502,23 +705,29 @@ if (total >= nr) { psiconv_warn(lev+3,off+len, "Layout section inlines: not enough element"); - res = -1; psiconv_debug(lev+3,off+len,"Can't read element!"); } else { total ++; - in_line.layout = psiconv_clone_character_layout(para->base_character); + if (!(in_line.layout = psiconv_clone_character_layout + (para->base_character))) + goto ERROR4; psiconv_progress(lev+4,off+len,"Going to read the element type"); - temp = psiconv_read_u8(buf,lev+4,len+off); + temp = psiconv_read_u8(buf,lev+4,len+off,&res); + if (res) + goto ERROR4; len += 1; psiconv_debug(lev+4,off,"Type: %02x",temp); psiconv_progress(lev+4,off, - "Going to read the number of characters it applies to"); - in_line.length = psiconv_read_u32(buf,lev+4,len+off); + "Going to read the number of characters it applies to"); + in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res); + if (res) + goto ERROR4; psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length); len += 4; psiconv_progress(lev+4,off+len,"Going to read the character layout"); - res |= psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, - in_line.layout); + if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, + in_line.layout))) + goto ERROR4; len += leng; if (temp == 0x01) { @@ -526,7 +735,6 @@ len += 0x10; } else if (temp != 0x00) { psiconv_warn(lev+4,off+len,"Layout section unknown inline type"); - res = -1; } if (line_length + in_line.length > strlen(para->text)) { psiconv_warn(lev+4,off+len, @@ -535,7 +743,8 @@ in_line.length = strlen(para->text) - line_length; } line_length += in_line.length; - psiconv_list_add(para->in_lines,&in_line); + if ((res = psiconv_list_add(para->in_lines,&in_line))) + goto ERROR4; } } } @@ -548,7 +757,10 @@ free(inline_count); for (i = 0 ; i < psiconv_list_length(anon_styles); i ++) { - anon_ptr = psiconv_list_get(anon_styles,i); + if (!(anon_ptr = psiconv_list_get(anon_styles,i))) { + psiconv_warn(lev+4,off+len,"Massive memory corruption"); + goto ERROR2; + } psiconv_free_character_layout(anon_ptr->character); psiconv_free_paragraph_layout(anon_ptr->paragraph); } @@ -560,7 +772,46 @@ psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x", len); - return res; + return 0; + +ERROR4_4: + psiconv_free_paragraph_layout(para->base_paragraph); +ERROR4_3: + psiconv_free_character_layout(para->base_character); +ERROR4_2: + psiconv_list_free(para->in_lines); +ERROR4_1: + free(para); + goto ERROR4; + +ERROR3_2: + psiconv_free_character_layout(anon.character); +ERROR3_1: + psiconv_free_paragraph_layout(anon.paragraph); + goto ERROR3; + +ERROR4: + free(inline_count); +ERROR3: + for (i = 0; i < psiconv_list_length(anon_styles); i++) { + if (!(anon_ptr = psiconv_list_get(anon_styles,i))) { + psiconv_warn(lev+1,off,"Massive memory corruption"); + break; + } + psiconv_free_paragraph_layout(anon_ptr->paragraph); + psiconv_free_character_layout(anon_ptr->character); + } + +ERROR2: + psiconv_list_free(anon_styles); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Layout Section failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } int psiconv_parse_styled_layout_section(const psiconv_buffer buf, @@ -579,21 +830,49 @@ psiconv_character_layout base_char, psiconv_paragraph_layout base_para) { - int res; + int res = 0; psiconv_word_styles_section styles_section; - styles_section = malloc(sizeof(*styles_section)); - styles_section->normal = malloc(sizeof(*styles_section->normal)); - styles_section->normal->character = psiconv_clone_character_layout(base_char); - styles_section->normal->paragraph = psiconv_clone_paragraph_layout(base_para); + if (!(styles_section = malloc(sizeof(*styles_section)))) + goto ERROR1; + if (!(styles_section->normal = malloc(sizeof(*styles_section->normal)))) + goto ERROR2; + if (!(styles_section->normal->character = + psiconv_clone_character_layout(base_char))) + goto ERROR3; + if (!(styles_section->normal->paragraph = + psiconv_clone_paragraph_layout(base_para))) + goto ERROR4; styles_section->normal->hotkey = 0; - styles_section->normal->name = strdup(""); - styles_section->styles = psiconv_list_new(sizeof(struct psiconv_word_style_s)); + if (!(styles_section->normal->name = strdup(""))) + goto ERROR5; + if (!(styles_section->styles = psiconv_list_new(sizeof( + struct psiconv_word_style_s)))) + goto ERROR6; res = psiconv_parse_layout_section(buf,lev,off,length,result, styles_section,0); psiconv_free_word_styles_section(styles_section); return res; + +ERROR6: + free(styles_section->normal->name); +ERROR5: + psiconv_free_paragraph_layout(styles_section->normal->paragraph); +ERROR4: + psiconv_free_character_layout(styles_section->normal->character); +ERROR3: + free(styles_section->normal); +ERROR2: + free(styles_section); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Styleless Layout Section failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; }