This is a combination of upstream patches. commit d74790b4bd55a3a11b56dbbd670c3baa1331e6dd CommitDate: Thu Oct 31 11:26:08 2019 +0100 lotus[wb1]: try to correct the retrieving of row references in formula... commit 39be60f9045a758178d90526ae66b0e3d24f348e CommitDate: Thu Oct 31 13:28:54 2019 +0100 wks,wk1,...: try to read correctly the row cell's references... commit 188933f0d66c77a19ccb0b5f5151a4c9f7203fbc CommitDate: Thu Oct 31 14:30:26 2019 +0100 wks,wk1: do not change the maximum number of columns... commit c1ba33b7505cff91f57d5aa7e8c6ff8706b63a21 CommitDate: Thu Oct 31 15:09:19 2019 +0100 WKS4Spreadsheet.cpp: simplify the code... diff --git a/src/lib/WKS4.cpp b/src/lib/WKS4.cpp index 2f222d3..a92eace 100644 --- a/src/lib/WKS4.cpp +++ b/src/lib/WKS4.cpp @@ -836,7 +836,7 @@ bool WKS4Parser::readZone() val=int(libwps::readU8(input)); f << "Entries(ItCount):dos"; if (val!=1) f << "=" << val << ","; - if (m_state->m_version==2) + else if (m_state->m_version==2) m_state->m_version=1; isParsed = needWriteInAscii = true; break; diff --git a/src/lib/WKS4Spreadsheet.cpp b/src/lib/WKS4Spreadsheet.cpp index caaf4e1..582f377 100644 --- a/src/lib/WKS4Spreadsheet.cpp +++ b/src/lib/WKS4Spreadsheet.cpp @@ -1798,10 +1798,14 @@ bool WKS4Spreadsheet::readCell for (int dim = 0; dim < 2; dim++) { auto val = int(libwps::readU16(m_input)); - if ((val & 0xF000) == 0); // absolue value ? - else if ((val & 0xc000) == 0x8000) // relative ? + if ((val & 0x8000) == 0); // absolue value ? + else { - if (version()==1) + // relative + // wb1: maximum row=0x2000, maximum col=0x100 + // wks dos (v3) maximum row=0x4000, maximum col=0x100 + // wdb maximum number of data ? + if (version()==1 && dim==0) { val &= 0xFF; if ((val & 0x80) && val+actPos[dim] >= 0x100) @@ -1810,27 +1814,17 @@ bool WKS4Spreadsheet::readCell } else { - val &= 0x3FFF; - if (val & 0x2000) val = val - 0x4000; + // 0x400 for old file(unsure), ie. find many problematic files on + // the web, so maybe 0x4000 is ok and these files are + // problematic + int const maxVal= (dim==1 || m_mainParser.creator()==libwps::WPS_LOTUS) ? 0x2000 : version()==1 ? 0x400 : 0x4000; + val &= (2*maxVal-1); + if (val & maxVal) val = val - 2*maxVal; + if (val+actPos[dim]>=maxVal) val-=maxVal; } val += actPos[dim]; absolute[dim] = false; } - else if (val==0xFFFF) - { - static bool first=true; - if (first) // in general associated with a nan value, so maybe be normal - { - WPS_DEBUG_MSG(("WKS4Spreadsheet::readCell: find some ffff cell\n")); - first=false; - } - ok = false; - } - else - { - WPS_DEBUG_MSG(("WKS4Spreadsheet::readCell: can not read cell %x\n", unsigned(val))); - ok = false; - } pos[dim] = val; } diff --git a/src/lib/WPSDocument.cpp b/src/lib/WPSDocument.cpp index 7e974b6..5b18eb8 100644 --- a/src/lib/WPSDocument.cpp +++ b/src/lib/WPSDocument.cpp @@ -155,6 +155,10 @@ WPSLIB WPSConfidence WPSDocument::isFileFormatSupported(librevenge::RVNGInputStr WKS4Parser parser(header->getInput(), header); if (!parser.checkHeader(header.get(), true)) return WPS_CONFIDENCE_NONE; + // checkHeader() may set new kind and creator values, + // pass them up to caller. + kind = header->getKind(); + creator = header->getCreator(); needEncoding=header->getNeedEncoding(); return header->getIsEncrypted() ? WPS_CONFIDENCE_SUPPORTED_ENCRYPTION : WPS_CONFIDENCE_EXCELLENT; }