--- psiconv/trunk/lib/psiconv/parse_layout.c 1999/11/01 12:35:16 27 +++ psiconv/trunk/lib/psiconv/parse_layout.c 2004/01/06 20:15:01 184 @@ -1,6 +1,6 @@ /* parse_layout.c - Part of psiconv, a PSION 5 file formats converter - Copyright (c) 1999 Frodo Looijaard + Copyright (c) 1999, 2000 Frodo Looijaard This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,68 +18,122 @@ */ #include "config.h" +#include "compat.h" + #include #include -#include "data.h" #include "parse_routines.h" +#include "error.h" + +#ifdef DMALLOC +#include +#endif + -int psiconv_parse_color(const psiconv_buffer buf, int lev, psiconv_u32 off, +int psiconv_parse_color(const psiconv_config config, + const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_color *result) { int res = 0; int len = 0; - psiconv_progress(lev+1,off,"Going to parse color"); - *result = malloc(sizeof(**result)); - - (*result)->red = psiconv_read_u8(buf,lev+2,off+len); - (*result)->green = psiconv_read_u8(buf,lev+2,off+len+1); - (*result)->blue = psiconv_read_u8(buf,lev+2,off+len+2); + psiconv_progress(config,lev+1,off,"Going to parse color"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + (*result)->red = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + (*result)->green = psiconv_read_u8(config,buf,lev+2,off+len+1,&res); + if (res) + goto ERROR2; + (*result)->blue = psiconv_read_u8(config,buf,lev+2,off+len+2,&res); + if (res) + goto ERROR2; len += 3; - psiconv_debug(lev+2,off,"Color: red %02x, green %02x, blue %02x", + psiconv_debug(config,lev+2,off,"Color: red %02x, green %02x, blue %02x", (*result)->red, (*result)->green, (*result)->blue); if (length) *length = len; - psiconv_progress(lev+1,off+len-1,"End of color (total length: %08x)",len); - return res; + psiconv_progress(config,lev+1,off+len-1,"End of color (total length: %08x)",len); + return 0; + +ERROR2: + free(*result); +ERROR1: + psiconv_error(config,lev+1,off,"Reading of Color failed"); + if (length) + *length = 0; + if (res == 0) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_font(const psiconv_buffer buf, int lev, psiconv_u32 off, +int psiconv_parse_font(const psiconv_config config, + const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_font *result) { int res = 0; - int strlength,i; char *str_copy; - int len; + int len=0; + int fontlen; - psiconv_progress(lev+1,off,"Going to parse font"); - *result = malloc(sizeof(**result)); + psiconv_progress(config,lev+1,off,"Going to parse font"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + fontlen = psiconv_read_u8(config,buf,lev+2,off,&res); + if (res) + goto ERROR2; + len = 1; + + (*result)->name = psiconv_read_charlist(config,buf,lev+2,off, fontlen-1,&res); + if (res) + goto ERROR2; + len += fontlen - 1; + + (*result)->screenfont = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR3; - strlength = psiconv_read_u8(buf,lev+2,off); - (*result)->name = malloc(strlength); - for (i = 0; i < strlength-1; i++) - (*result)->name[i] = psiconv_read_u8(buf,lev+2,off + 1 + i); - (*result)->name[strlength-1] = 0; - (*result)->screenfont = psiconv_read_u8(buf,lev+2,off + strlength); + if (!(str_copy = psiconv_make_printable(config,(*result)->name))) + goto ERROR3; - str_copy = psiconv_make_printable((*result)->name); - psiconv_debug(lev+2,off+1,"Found font `%s', displayed with screen font %02x", + psiconv_debug(config,lev+2,off+len, + "Found font `%s', displayed with screen font %02x", str_copy,(*result)->screenfont); free(str_copy); - len = strlength + 1; + len ++; + if (length) *length = len; - psiconv_progress(lev+1,off + len - 1,"End of font (total length: %08x)",len); - return res; + psiconv_progress(config,lev+1,off + len - 1, + "End of font (total length: %08x)",len); + return 0; + +ERROR3: + free ((*result)->name); +ERROR2: + free (*result); +ERROR1: + psiconv_error(config,lev+1,off,"Reading of Font failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_border(const psiconv_buffer buf,int lev,psiconv_u32 off, +int psiconv_parse_border(const psiconv_config config, + const psiconv_buffer buf,int lev,psiconv_u32 off, int *length, psiconv_border *result) { int res = 0; @@ -87,11 +141,15 @@ psiconv_u32 temp; int leng; - psiconv_progress(lev+1,off,"Going to parse border data"); - *result = malloc(sizeof(**result)); + psiconv_progress(config,lev+1,off,"Going to parse border data"); + if (!(*result = malloc(sizeof(**result)))) { + goto ERROR1; + } - psiconv_progress(lev+2,off+len,"Going to read border kind"); - temp = psiconv_read_u8(buf,lev+2,off+len); + psiconv_progress(config,lev+2,off+len,"Going to read border kind"); + temp = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR2; if (temp == 0x00) (*result)->kind = psiconv_border_none; else if (temp == 0x01) @@ -101,111 +159,155 @@ else if (temp == 0x03) (*result)->kind = psiconv_border_dotted; else if (temp == 0x04) - (*result)->kind = psiconv_border_striped; + (*result)->kind = psiconv_border_dashed; else if (temp == 0x05) - (*result)->kind = psiconv_border_dotstripe; + (*result)->kind = psiconv_border_dotdashed; else if (temp == 0x06) - (*result)->kind = psiconv_border_dotdotstripe; + (*result)->kind = psiconv_border_dotdotdashed; else { - psiconv_warn(lev+2,off,"Unknown border kind (defaults to `none')"); + psiconv_warn(config,lev+2,off,"Unknown border kind (defaults to `none')"); (*result)->kind = psiconv_border_none; - res = -1; } - psiconv_debug(lev+2,off+len,"Kind: %02x",temp); + psiconv_debug(config,lev+2,off+len,"Kind: %02x",temp); len ++; - psiconv_progress(lev+2,off+len,"Going to read border thickness"); - (*result)->thickness = psiconv_read_size(buf,lev+2,off+len,&leng); + psiconv_progress(config,lev+2,off+len,"Going to read border thickness"); + (*result)->thickness = psiconv_read_size(config,buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; +#if 0 + /* This seems no longer necessary to test? */ if (((*result)->kind != psiconv_border_solid) && ((*result)->kind != psiconv_border_double) && ((*result)->thickness != 0.0) && (fabs((*result)->thickness - 1/20) >= 1/1000)) { - psiconv_warn(lev+2,off, + psiconv_warn(config,lev+2,off, "Border thickness specified for unlikely border type"); - res = -1; } - psiconv_debug(lev+2,off+len,"Thickness: %f",(*result)->thickness); +#endif + psiconv_debug(config,lev+2,off+len,"Thickness: %f",(*result)->thickness); len += leng; - psiconv_progress(lev+2,off+len,"Going to read the border color"); - res |= psiconv_parse_color(buf,lev+2,off+len,&leng,&(*result)->color); + psiconv_progress(config,lev+2,off+len,"Going to read the border color"); + if ((psiconv_parse_color(config,buf,lev+2,off+len,&leng,&(*result)->color))) + goto ERROR2; len += leng; - psiconv_progress(lev+2,off+len,"Going to read the final unknown byte " - "(0x01 expected)"); - temp = psiconv_read_u8(buf,lev+2,off + len); - if (temp != 0x01) { - psiconv_warn(lev+2,off,"Unknown last byte in border specification"); - psiconv_debug(lev+2,off+len, "Last byte: read %02x, expected %02x", - temp,0x01); - res = -1; + psiconv_progress(config,lev+2,off+len,"Going to read the final unknown byte " + "(0x00 or 0x01 expected)"); + temp = psiconv_read_u8(config,buf,lev+2,off + len,&res); + if (res) + goto ERROR3; + if ((temp != 0x01) && (temp != 0x00)) { + psiconv_warn(config,lev+2,off,"Unknown last byte in border specification"); + psiconv_debug(config,lev+2,off+len, "Last byte: read %02x, expected %02x or %02x", + temp,0x00,0x01); } len ++; if (length) *length = len; - psiconv_progress(lev+1,off + len - 1, + psiconv_progress(config,lev+1,off + len - 1, "End of border (total length: %08x)",len); - return res; + return 0; + +ERROR3: + psiconv_free_color((*result)->color); +ERROR2: + free (result); +ERROR1: + psiconv_error(config,lev+1,off,"Reading of Border failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_bullet(const psiconv_buffer buf,int lev,psiconv_u32 off, +int psiconv_parse_bullet(const psiconv_config config, + const psiconv_buffer buf,int lev,psiconv_u32 off, int *length, psiconv_bullet *result) { int res = 0; int len = 0; int leng; int bullet_length; + psiconv_u8 temp; - *result = malloc(sizeof(**result)); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; (*result)->on = psiconv_bool_true; - psiconv_progress(lev+1,off,"Going to parse bullet data"); - psiconv_progress(lev+2,off+len,"Going to read bullet length"); - bullet_length = psiconv_read_u8(buf,lev+2,off+len); - psiconv_debug(lev+2,off+len,"Length: %02x",bullet_length); + psiconv_progress(config,lev+1,off,"Going to parse bullet data"); + psiconv_progress(config,lev+2,off+len,"Going to read bullet length"); + bullet_length = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + psiconv_debug(config,lev+2,off+len,"Length: %02x",bullet_length); len ++; - psiconv_progress(lev+2,off+len,"Going to read bullet font size"); - (*result)->font_size = psiconv_read_size(buf,lev+2,off+len, &leng); + psiconv_progress(config,lev+2,off+len,"Going to read bullet font size"); + (*result)->font_size = psiconv_read_size(config,buf,lev+2,off+len, &leng,&res); + if (res) + goto ERROR2; len +=leng; - psiconv_progress(lev+2,off+len,"Going to read bullet character"); - (*result)->character = psiconv_read_u8(buf,lev+2,off+len); - psiconv_debug(lev+2,off+len,"Character: %02x",(*result)->character); + psiconv_progress(config,lev+2,off+len,"Going to read bullet character"); + temp = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + (*result)->character = psiconv_unicode_from_char(config,temp); + psiconv_debug(config,lev+2,off+len,"Character: %02x",(*result)->character); len ++; - psiconv_progress(lev+2,off+len,"Going to read indent on/off"); - res |= psiconv_parse_bool(buf,lev+2,off+len,&leng,&(*result)->indent); - psiconv_debug(lev+2,off+len,"Indent on: %02x",(*result)->indent); + psiconv_progress(config,lev+2,off+len,"Going to read indent on/off"); + if ((res = psiconv_parse_bool(config,buf,lev+2,off+len,&leng,&(*result)->indent))) + goto ERROR2; + psiconv_debug(config,lev+2,off+len,"Indent on: %02x",(*result)->indent); len += leng; - psiconv_progress(lev+2,off+len,"Going to read bullet color"); - res |= psiconv_parse_color(buf,lev+2,off+len,&leng,&(*result)->color); + psiconv_progress(config,lev+2,off+len,"Going to read bullet color"); + if ((res = psiconv_parse_color(config,buf,lev+2,off+len,&leng,&(*result)->color))) + goto ERROR2; len += leng; - psiconv_progress(lev+2,off+len,"Going to read bullet font"); - res |= psiconv_parse_font(buf,lev+2,off+len,&leng,&(*result)->font); + psiconv_progress(config,lev+2,off+len,"Going to read bullet font"); + if ((res = psiconv_parse_font(config,buf,lev+2,off+len,&leng,&(*result)->font))) + goto ERROR3; len += leng; if (len != bullet_length + 1) { - psiconv_warn(lev+2,off,"Bullet data structure length mismatch"); - psiconv_debug(lev+2,off,"Length: specified %02x, found %02x", + psiconv_warn(config,lev+2,off,"Bullet data structure length mismatch"); + psiconv_debug(config,lev+2,off,"Length: specified %02x, found %02x", bullet_length,len-1); - res = -1; } - psiconv_progress(lev+1,off + len - 1, + psiconv_progress(config,lev+1,off + len - 1, "End of bullet data (total length: %08x)",len); if (length) *length = len; - return res; + return 0; + +ERROR3: + psiconv_free_color((*result)->color); +ERROR2: + free (result); +ERROR1: + psiconv_error(config,lev+1,off,"Reading of Bullet failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_tab(const psiconv_buffer buf, int lev, psiconv_u32 off, +int psiconv_parse_tab(const psiconv_config config, + const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_tab *result) { int res = 0; @@ -213,15 +315,20 @@ int leng; psiconv_u8 temp; - psiconv_progress(lev+1,off,"Going to parse tab"); - *result = malloc(sizeof(**result)); - - psiconv_progress(lev+2,off,"Going to read tab location"); - (*result)->location = psiconv_read_length(buf,lev+2,off+len,&leng); + psiconv_progress(config,lev+1,off,"Going to parse tab"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(config,lev+2,off,"Going to read tab location"); + (*result)->location = psiconv_read_length(config,buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; len += leng; - psiconv_progress(lev+2,off+len,"Going to read the tab kind"); - temp = psiconv_read_u8(buf,lev+2,off+len); + psiconv_progress(config,lev+2,off+len,"Going to read the tab kind"); + temp = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR2; if (temp == 1) (*result)->kind = psiconv_tab_left; else if (temp == 2) @@ -229,24 +336,34 @@ else if (temp == 3) (*result)->kind = psiconv_tab_right; else { - res = -1; - psiconv_warn(lev+2,off+len,"Unknown tab kind argument"); - psiconv_debug(lev+2,off+len,"Kind found: %02x (defaulted to left tab)", + psiconv_warn(config,lev+2,off+len,"Unknown tab kind argument"); + psiconv_debug(config,lev+2,off+len,"Kind found: %02x (defaulted to left tab)", temp); (*result)->kind = psiconv_tab_left; } - psiconv_debug(lev+2,off+len,"Kind: %02x",temp); + psiconv_debug(config,lev+2,off+len,"Kind: %02x",temp); len ++; if (length) *length = len; - psiconv_progress(lev+1,off+len-1,"End of tab (total length: %08x)",len); - return res; + psiconv_progress(config,lev+1,off+len-1,"End of tab (total length: %08x)",len); + return 0; +ERROR2: + free (result); +ERROR1: + psiconv_error(config,lev+1,off,"Reading of Tab failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_paragraph_layout_list(const psiconv_buffer buf, int lev, +int psiconv_parse_paragraph_layout_list(const psiconv_config config, + const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_paragraph_layout result) { @@ -255,48 +372,66 @@ int list_length,leng,nr; psiconv_u8 id; psiconv_u32 temp; - psiconv_tab tab; - - psiconv_progress(lev+1,off,"Going to read paragraph layout list"); - - psiconv_progress(lev+2,off,"Going to read the list length"); - list_length = psiconv_read_u32(buf,lev+2,off + len); - psiconv_debug(lev+2,off,"Length in bytes: %08x",list_length); + psiconv_tab temp_tab; + psiconv_color temp_color; + psiconv_border temp_border; + psiconv_bullet temp_bullet; + + psiconv_progress(config,lev+1,off,"Going to read paragraph layout list"); + + psiconv_progress(config,lev+2,off,"Going to read the list length"); + list_length = psiconv_read_u32(config,buf,lev+2,off + len,&res); + if (res) + goto ERROR1; + psiconv_debug(config,lev+2,off,"Length in bytes: %08x",list_length); len += 4; nr = 0; while(len - 4 < list_length) { - psiconv_progress(lev+2,off+len,"Going to read element %d",nr); - psiconv_progress(lev+3,off+len,"Going to read the element id"); - id = psiconv_read_u8(buf,lev+2,off+len); - psiconv_debug(lev+3,off+len,"Id: %02x",id); + psiconv_progress(config,lev+2,off+len,"Going to read element %d",nr); + psiconv_progress(config,lev+3,off+len,"Going to read the element id"); + id = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + psiconv_debug(config,lev+3,off+len,"Id: %02x",id); len ++; switch(id) { case 0x01: - psiconv_progress(lev+3,off+len,"Going to read background color"); + psiconv_progress(config,lev+3,off+len,"Going to read background color"); + if ((res = psiconv_parse_color(config,buf,lev+3,off+len,&leng,&temp_color))) + goto ERROR1; psiconv_free_color(result->back_color); - res |= psiconv_parse_color(buf,lev+3,off+len,&leng, - &result->back_color); + result->back_color = temp_color; len += leng; break; case 0x02: - psiconv_progress(lev+3,off+len ,"Going to read indent left"); - result->indent_left = psiconv_read_length(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len ,"Going to read indent left"); + result->indent_left = psiconv_read_length(config,buf,lev+3,off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x03: - psiconv_progress(lev+3,off+len,"Going to read indent right"); - result->indent_right = psiconv_read_length(buf,lev+2,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read indent right"); + result->indent_right = psiconv_read_length(config,buf,lev+2,off+len,&leng, + &res); + if (res) + goto ERROR1; len += leng; break; case 0x04: - psiconv_progress(lev+3,off+len,"Going to read indent left first line"); - result->indent_first = psiconv_read_length(buf,lev+2,off+len, &leng); + psiconv_progress(config,lev+3,off+len,"Going to read indent left first line"); + result->indent_first = psiconv_read_length(config,buf,lev+2,off+len, &leng, + &res); + if (res) + goto ERROR1; len += leng; break; case 0x05: - psiconv_progress(lev+3,off+len,"Going to read horizontal justify"); - temp = psiconv_read_u8(buf,lev+3,off+len); + psiconv_progress(config,lev+3,off+len,"Going to read horizontal justify"); + temp = psiconv_read_u8(config,buf,lev+3,off+len,&res); + if (res) + goto ERROR1; if (temp == 0x00) result->justify_hor = psiconv_justify_left; else if (temp == 0x01) @@ -306,16 +441,18 @@ else if (temp == 0x03) result->justify_hor = psiconv_justify_full; else { - res = -1; - psiconv_warn(lev+3,off+len, "Unknown horizontal justify argument " + psiconv_warn(config,lev+3,off+len, "Unknown horizontal justify argument " "in paragraph layout codes list"); + result->justify_hor = psiconv_justify_left; } - psiconv_debug(lev+3,off+len,"Justify: %02x",temp); + psiconv_debug(config,lev+3,off+len,"Justify: %02x",temp); len ++; break; case 0x06: - psiconv_progress(lev+3,off+len,"Going to read vertical justify"); - temp = psiconv_read_u8(buf,lev+3,off+len); + psiconv_progress(config,lev+3,off+len,"Going to read vertical justify"); + temp = psiconv_read_u8(config,buf,lev+3,off+len,&res); + if (res) + goto ERROR1; if (temp == 0x00) result->justify_ver = psiconv_justify_top; else if (temp == 0x01) @@ -323,139 +460,184 @@ else if (temp == 0x02) result->justify_ver = psiconv_justify_bottom; else { - res = -1; - psiconv_warn(lev+3,off+len, "Unknown vertical justify argument " + psiconv_warn(config,lev+3,off+len, "Unknown vertical justify argument " "in paragraph layout codes list"); + result->justify_ver = psiconv_justify_bottom; } - psiconv_debug(lev+3,off+len,"Justify: %02x",temp); + psiconv_debug(config,lev+3,off+len,"Justify: %02x",temp); len ++; + break; case 0x07: - psiconv_progress(lev+3,off+len,"Going to read interline distance"); - result->interline = psiconv_read_size(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read linespacing distance"); + result->linespacing = psiconv_read_size(config,buf,lev+3,off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x08: - psiconv_progress(lev+3,off+len,"Going to read interline exact"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng, - &result->interline_exact); + psiconv_progress(config,lev+3,off+len,"Going to read linespacing exact"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->linespacing_exact))) + goto ERROR1; len += leng; break; case 0x09: - psiconv_progress(lev+3,off+len,"Going to read top space"); - result->top_space = psiconv_read_size(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read top space"); + result->space_above = psiconv_read_size(config,buf,lev+3,off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x0a: - psiconv_progress(lev+3,off+len,"Going to read bottom space"); - result->bottom_space = psiconv_read_size(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read bottom space"); + result->space_below = psiconv_read_size(config,buf,lev+3,off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x0b: - psiconv_progress(lev+3,off+len,"Going to read on one page"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng, - &result->on_one_page); + psiconv_progress(config,lev+3,off+len,"Going to read on one page"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->keep_together))) + goto ERROR1; len += leng; break; case 0x0c: - psiconv_progress(lev+3,off+len,"Going to read together with"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng, - &result->together_with); + psiconv_progress(config,lev+3,off+len,"Going to read together with"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->keep_with_next))) + goto ERROR1; len += leng; break; case 0x0d: - psiconv_progress(lev+3,off+len,"Going to read on next page"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng, - &result->on_next_page); + psiconv_progress(config,lev+3,off+len,"Going to read on next page"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->on_next_page))) + goto ERROR1; len += leng; break; case 0x0e: - psiconv_progress(lev+3,off+len,"Going to read no widow protection"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng, - &result->no_widow_protection); + psiconv_progress(config,lev+3,off+len,"Going to read no widow protection"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->no_widow_protection))) + goto ERROR1; + len += leng; + break; + case 0x0f: + psiconv_progress(config,lev+3,off+len,"Going to read wrap to fit cell limits"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->wrap_to_fit_cell))) + goto ERROR1; len += leng; break; case 0x10: - psiconv_progress(lev+3,off+len,"Going to read border distance to text"); - result->border_distance = psiconv_read_length(buf,lev+3, - off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read border distance to text"); + result->border_distance = psiconv_read_length(config,buf,lev+3, + off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x11: - psiconv_progress(lev+3,off+len,"Going to read top border"); + psiconv_progress(config,lev+3,off+len,"Going to read top border"); + if ((res = psiconv_parse_border(config,buf,lev+3,off+len,&leng,&temp_border))) + goto ERROR1; psiconv_free_border(result->top_border); - res |= psiconv_parse_border(buf,lev+3,off+len,&leng, - &result->top_border); + result->top_border = temp_border; len += leng; break; case 0x12: - psiconv_progress(lev+3,off+len,"Going to read bottom border"); + psiconv_progress(config,lev+3,off+len,"Going to read bottom border"); + if ((res = psiconv_parse_border(config,buf,lev+3,off+len,&leng,&temp_border))) + goto ERROR1; psiconv_free_border(result->bottom_border); - res |= psiconv_parse_border(buf,lev+3,off+len,&leng, - &result->bottom_border); + result->bottom_border = temp_border; len += leng; break; case 0x13: - psiconv_progress(lev+3,off+len,"Going to read left border"); + psiconv_progress(config,lev+3,off+len,"Going to read left border"); + if ((res = psiconv_parse_border(config,buf,lev+3,off+len,&leng,&temp_border))) + goto ERROR1; psiconv_free_border(result->left_border); - res |= psiconv_parse_border(buf,lev+3,off+len,&leng, - &result->left_border); + result->left_border = temp_border; len += leng; break; case 0x14: - psiconv_progress(lev+3,off+len,"Going to read right border"); + psiconv_progress(config,lev+3,off+len,"Going to read right border"); + if ((res = psiconv_parse_border(config,buf,lev+3,off+len,&leng,&temp_border))) + goto ERROR1; psiconv_free_border(result->right_border); - res |= psiconv_parse_border(buf,lev+3,off+len,&leng, - &result->right_border); + result->right_border = temp_border; len += leng; break; case 0x15: - psiconv_progress(lev+3,off+len,"Going to read bullet"); + psiconv_progress(config,lev+3,off+len,"Going to read bullet"); + if ((res = psiconv_parse_bullet(config,buf,lev+3,off+len,&leng,&temp_bullet))) + goto ERROR1; psiconv_free_bullet(result->bullet); - res |= psiconv_parse_bullet(buf,lev+3,off+len,&leng, - &result->bullet); + result->bullet = temp_bullet; len += leng; break; case 0x16: - psiconv_progress(lev+3,off+len,"Going to read standard tabs"); - result->tabs->normal = psiconv_read_length(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read standard tabs"); + result->tabs->normal = psiconv_read_length(config,buf,lev+3,off+len,&leng, + &res); + if (res) + goto ERROR1; len += leng; break; case 0x17: - psiconv_progress(lev+3,off+len,"Going to read extra tab"); - res |= psiconv_parse_tab(buf,lev+3,off+len,&leng,&tab); - psiconv_list_add(result->tabs->extras,tab); + psiconv_progress(config,lev+3,off+len,"Going to read extra tab"); + if ((res = psiconv_parse_tab(config,buf,lev+3,off+len,&leng,&temp_tab))) + goto ERROR1; + if ((res = psiconv_list_add(result->tabs->extras,temp_tab))) { + psiconv_free_tab(temp_tab); + goto ERROR1; + } + psiconv_free_tab(temp_tab); len += leng; break; default: - psiconv_warn(lev+3,off+len, + psiconv_warn(config,lev+3,off+len, "Unknown code in paragraph layout codes list"); - psiconv_debug(lev+3,off+len,"Code: %02x",id); + psiconv_debug(config,lev+3,off+len,"Code: %02x",id); len ++; - res = -1; break; } nr ++; } if (len - 4 != list_length) { - psiconv_warn(lev+2,off+len, - "Read past end of paragraph layout codes list. I probably lost track" + psiconv_error(config,lev+2,off+len, + "Read past end of paragraph layout codes list. I probably lost track " "somewhere!"); - psiconv_debug(lev+2,off+len,"Read %d characters instead of %d", + psiconv_debug(config,lev+2,off+len,"Read %d characters instead of %d", len-4,list_length); + res = PSICONV_E_PARSE; + goto ERROR1; } len = list_length + 4; - psiconv_progress(lev+1,off+len, + psiconv_progress(config,lev+1,off+len, "End of paragraph layout list (total length: %08x)",len); if (length) *length = len; - return res; + return 0; + +ERROR1: + psiconv_error(config,lev+1,off,"Reading of paragraph_layout_list failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; } -int psiconv_parse_character_layout_list(const psiconv_buffer buf, int lev, +int psiconv_parse_character_layout_list(const psiconv_config config, + const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_character_layout result) { @@ -464,53 +646,76 @@ int list_length,leng,nr; psiconv_u8 id; psiconv_u32 temp; + psiconv_color temp_color; + psiconv_font temp_font; - psiconv_progress(lev+1,off,"Going to read character layout codes"); + psiconv_progress(config,lev+1,off,"Going to read character layout codes"); - psiconv_progress(lev+2,off,"Going to read the list length"); - list_length = psiconv_read_u32(buf,lev+2,off + len); - psiconv_debug(lev+2,off,"Length in bytes: %08x",list_length); + psiconv_progress(config,lev+2,off,"Going to read the list length"); + list_length = psiconv_read_u32(config,buf,lev+2,off + len,&res); + if (res) + goto ERROR1; + psiconv_debug(config,lev+2,off,"Length in bytes: %08x",list_length); len += 4; nr = 0; while(len-4 < list_length) { - psiconv_progress(lev+2,off+len,"Going to read element %d",nr); - psiconv_progress(lev+3,off+len,"Going to read the element id"); - id = psiconv_read_u8(buf,lev+2,off+len); - psiconv_debug(lev+3,off+len,"Id: %02x",id); + psiconv_progress(config,lev+2,off+len,"Going to read element %d",nr); + psiconv_progress(config,lev+3,off+len,"Going to read the element id"); + id = psiconv_read_u8(config,buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + psiconv_debug(config,lev+3,off+len,"Id: %02x",id); len ++; switch(id) { + case 0x18: + psiconv_progress(config,lev+3,off+len,"Going to skip an unknown setting"); + len ++; + break; case 0x19: - psiconv_progress(lev+3,off+len,"Going to read text color"); + psiconv_progress(config,lev+3,off+len,"Going to read text color"); + if ((res = psiconv_parse_color(config,buf,lev+3,off+len, &leng,&temp_color))) + goto ERROR1; psiconv_free_color(result->color); - res |= psiconv_parse_color(buf,lev+3,off+len, &leng,&result->color); + result->color = temp_color; len += leng; break; case 0x1a: - psiconv_progress(lev+3,off+len,"Going to read background color (?)"); + psiconv_progress(config,lev+3,off+len,"Going to read background color (?)"); + if ((res = psiconv_parse_color(config,buf,lev+2,off+len, &leng,&temp_color))) + goto ERROR1; psiconv_free_color(result->back_color); - res |= psiconv_parse_color(buf,lev+2,off+len, &leng, - &result->back_color); + result->back_color = temp_color; len += leng; break; + case 0x1b: + psiconv_progress(config,lev+3,off+len,"Going to skip an unknown setting"); + len ++; + break; case 0x1c: - psiconv_progress(lev+3,off+len,"Going to read font size"); - result->font_size = psiconv_read_size(buf,lev+3,off+len,&leng); + psiconv_progress(config,lev+3,off+len,"Going to read font size"); + result->font_size = psiconv_read_size(config,buf,lev+3,off+len,&leng,&res); + if (res) + goto ERROR1; len += leng; break; case 0x1d: - psiconv_progress(lev+3,off+len,"Going to read italic"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->italic); + psiconv_progress(config,lev+3,off+len,"Going to read italic"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng,&result->italic))) + goto ERROR1; len += leng; break; case 0x1e: - psiconv_progress(lev+3,off+len,"Going to read bold"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->bold); + psiconv_progress(config,lev+3,off+len,"Going to read bold"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng,&result->bold))) + goto ERROR1; len += leng; break; case 0x1f: - psiconv_progress(lev+3,off+len,"Going to read super_sub"); - temp = psiconv_read_u8(buf,lev+3,off+len); + psiconv_progress(config,lev+3,off+len,"Going to read super_sub"); + temp = psiconv_read_u8(config,buf,lev+3,off+len,&res); + if (res) + goto ERROR1; if (temp == 0x00) result->super_sub = psiconv_normalscript; else if (temp == 0x01) @@ -518,63 +723,84 @@ else if (temp == 0x02) result->super_sub = psiconv_subscript; else { - psiconv_warn(lev+3,off+len, + psiconv_warn(config,lev+3,off+len, "Unknown super_sub argument in character layout codes list"); - res = -1; } - psiconv_debug(lev+3,off+len,"Super_sub: %02x",temp); + psiconv_debug(config,lev+3,off+len,"Super_sub: %02x",temp); len ++; break; case 0x20: - psiconv_progress(lev+3,off+len,"Going to read underline"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->underline); + psiconv_progress(config,lev+3,off+len,"Going to read underline"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->underline))) + goto ERROR1; len += leng; break; case 0x21: - psiconv_progress(lev+3,off+len,"Going to read strike_out"); - res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->strike_out); + psiconv_progress(config,lev+3,off+len,"Going to read strikethrough"); + if ((res = psiconv_parse_bool(config,buf,lev+3,off+len,&leng, + &result->strikethrough))) + goto ERROR1; len += leng; break; case 0x22: - psiconv_progress(lev+3,off+len,"Going to read font"); + psiconv_progress(config,lev+3,off+len,"Going to read font"); + if ((res = psiconv_parse_font(config,buf,lev+3,off+len, &leng, &temp_font))) + goto ERROR1; psiconv_free_font(result->font); - res |= psiconv_parse_font(buf,lev+3,off+len, &leng, &result->font); + result->font = temp_font; len += leng; break; + case 0x23: + psiconv_progress(config,lev+3,off+len,"Going to skip an unknown setting"); + len ++; + break; case 0x24: - psiconv_progress(lev+3,off+len, + psiconv_progress(config,lev+3,off+len, "Going to read unknown code 0x24 (%02x expected)", 0); - temp = psiconv_read_u8(buf,lev+3,off+len); + temp = psiconv_read_u8(config,buf,lev+3,off+len,&res); + if (res) + goto ERROR1; if (temp != 0) { - psiconv_warn(lev+3,off+len, + psiconv_warn(config,lev+3,off+len, "Unknown code 0x24 value != 0x0 (0x%02x)", temp); } len ++; break; default: - psiconv_warn(lev+3,off+len,"Unknown code in character layout list"); - psiconv_debug(lev+3,off+len,"Code: %02x",id); + psiconv_warn(config,lev+3,off+len,"Unknown code in character layout list"); + psiconv_debug(config,lev+3,off+len,"Code: %02x",id); len ++; - res = -1; break; } nr ++; } if (len - 4 != list_length) { - psiconv_warn(lev+2,off+len, - "Read past end of character layout codes list. I probably lost track" + psiconv_error(config,lev+2,off+len, + "Read past end of character layout codes list. I probably lost track " "somewhere!"); - psiconv_debug(lev+2,off+len,"Read %d characters instead of %d", + psiconv_debug(config,lev+2,off+len,"Read %d characters instead of %d", len-4,list_length); + res = PSICONV_E_PARSE; + goto ERROR1; } len = list_length + 4; - psiconv_progress(lev+1,off+len, + psiconv_progress(config,lev+1,off+len, "End of character layout list (total length: %08x)",len); if (length) *length = len; return res; + +ERROR1: + psiconv_error(config,lev+1,off,"Reading of character_layout_list failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; }