--- psiconv/trunk/lib/psiconv/parse_formula.c 2001/01/31 00:57:17 104 +++ psiconv/trunk/lib/psiconv/parse_formula.c 2001/02/02 21:07:11 105 @@ -440,20 +440,20 @@ return res; } -int psiconv_parse_formula(const psiconv_buffer buf, int lev, - psiconv_u32 off, int *length, - psiconv_formula *result) +static int psiconv_parse_formula_element_list(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_formula *result, + psiconv_u32 maxlen) { int res=0; int len=0; int leng; int eof = 0; psiconv_u8 marker; - psiconv_u32 bytelen; psiconv_formula_list formula_stack; psiconv_formula formula,subformula1,subformula2,subformula3,subformula4; - psiconv_progress(lev+1,off,"Going to read a formula"); + psiconv_progress(lev+1,off,"Going to read a formula element list"); if (!(*result = malloc(sizeof(**result)))) goto ERROR1; if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) @@ -475,17 +475,7 @@ goto ERROR7; subformula4->type = psiconv_formula_unknown; - psiconv_progress(lev+2,off+len, - "Going to read the formula byte length"); - bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); - if (res) - goto ERROR8; - psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); - len += leng; - bytelen += len; - - psiconv_progress(lev+2,off+len,"Going to read the formula items"); - while (!eof && len < bytelen) { + while (!eof && len+off < maxlen) { psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); marker = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) @@ -497,9 +487,14 @@ if (formula_elements[marker].formula_type == psiconv_formula_unknown) { psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); goto ERROR8; - } else if (formula_elements[marker].formula_type == - psiconv_formula_mark_eof) { - psiconv_progress(lev+3,off+len,"End of formula"); + } else if ((formula_elements[marker].formula_type == + psiconv_formula_mark_eof) || + (formula_elements[marker].formula_type == + psiconv_formula_mark_opend) || + (formula_elements[marker].formula_type == + psiconv_formula_mark_opsep)) { + len--; + psiconv_progress(lev+3,off+len,"End of this formula list"); eof = 1; } else if (formula_elements[marker].formula_type == psiconv_formula_dat_int) { @@ -563,11 +558,7 @@ } else if ((formula_elements[marker].formula_type == psiconv_formula_dat_var) || (formula_elements[marker].formula_type == - psiconv_formula_dat_vcellblock) || - (formula_elements[marker].formula_type == - psiconv_formula_mark_opsep) || - (formula_elements[marker].formula_type == - psiconv_formula_mark_opend)) { + psiconv_formula_dat_vcellblock)) { psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); goto ERROR8; } else if (formula_elements[marker].number_of_args == -1) { @@ -608,10 +599,10 @@ subformula1->type = formula->type = psiconv_formula_unknown; } } - if ((len != bytelen) || !eof) { + if ((len+off > maxlen) || !eof) { psiconv_warn(lev+2,off+len,"Formula corrupted!"); psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", - bytelen,len); + maxlen,len+off); goto ERROR8; } if ((psiconv_list_length(formula_stack)) != 1) { @@ -629,7 +620,7 @@ *length = len; psiconv_progress(lev,off+len-1, - "End of formula (total length: %08x)", len); + "End of formula element list (total length: %08x)", len); return 0; ERROR8: @@ -647,6 +638,75 @@ ERROR2: free (*result); ERROR1: + psiconv_warn(lev+1,off,"Reading of formula element list failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + + + + +int psiconv_parse_formula(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_formula *result) +{ + int res=0; + int len=0; + int leng; + psiconv_u32 bytelen,formula_end; + psiconv_u8 temp; + + psiconv_progress(lev+1,off,"Going to read a formula"); + + psiconv_progress(lev+2,off+len, + "Going to read the formula byte length"); + bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR1; + psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); + len += leng; + bytelen += len; + formula_end = off + bytelen; + + psiconv_progress(lev+2,off+len,"Going to read the formula elements list"); + if ((res = psiconv_parse_formula_element_list(buf,lev+2,off+len,&leng, + result,formula_end))) + goto ERROR1; + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the eof marker"); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (formula_elements[temp].formula_type != psiconv_formula_mark_eof) { + psiconv_warn(lev+2,off+len,"Formula corrupted!"); + psiconv_debug(lev+2,off+len,"Expected marker: %02x, found byte: %02x", + 0x15,temp); + goto ERROR2; + } + len ++; + + if (off+len != formula_end) { + psiconv_warn(lev+2,off+len,"Formula corrupted!"); + psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", + formula_end,len+off); + goto ERROR2; + } + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of formula (total length: %08x)", len); + return 0; + +ERROR2: + psiconv_free_formula(*result); +ERROR1: psiconv_warn(lev+1,off,"Reading of formula failed"); if (length) *length = 0; @@ -656,3 +716,4 @@ return res; } +