ExcelFormat 读取失败以及解决方法-Bug1

ExcelFormat是C++读取xls文件的库,来自:

http://www.codeproject.com/Articles/42504/ExcelFormat-Library

 

https://github.com/metamaker/ExcelFormat-BiiExample

使用过程中发现了一个问题,提示vector访问超过范围。经过调试问题在BasicExcel.cpp文件中,改正的代码如下:

只增加了一行代码,strings_[i].Read1(&*(data_.begin())+npos);

分析过程:

在调试过程中发现,phonetic_没有读取实际应该是16,但是他是0。因为他没有读取unicode_、richtext_、phonetic_,因此出现这个错误。他将phonetic_标志当成字符串内容读取了,下次读取的时候字符串长度已经不是协议中得了多次以后造成内存访问超过范围错误。

ULONG Workbook::SharedStringTable::Read(const char* data)
{
	Record::Read(data);
	LittleEndian::Read(data_, stringsTotal_, 0, 4);
	LittleEndian::Read(data_, uniqueStringsTotal_, 4, 4);
	strings_.clear();
	strings_.resize(uniqueStringsTotal_);

	ULONG npos = 8;
	if (continueIndices_.empty()) {
		for(ULONG i=0; i<uniqueStringsTotal_; ++i)
			npos += strings_[i].Read(&*(data_.begin())+npos);
	} else {
		// Require special handling since CONTINUE records are present
		ULONG maxContinue = (ULONG) continueIndices_.size();

		for(ULONG i=0, c=0; i<uniqueStringsTotal_; ++i) {
			char unicode;
			ULONG stringSize;
			LittleEndian::Read(data_, stringSize, npos, 2);
			LittleEndian::Read(data_, unicode, npos+2, 1);
			int multiplier = unicode & 1 ? 2 : 1;

			if (c >= maxContinue || npos+stringSize*multiplier+3 <= continueIndices_[c]) {
				// String to be read is not split into two records
				npos += strings_[i].Read(&*(data_.begin())+npos);
			} else {
				//2019-03-01 by cch 解决标记未读取的错误
				strings_[i].Read1(&*(data_.begin())+npos);
				
				// String to be read is split into two or more records
				int bytesRead = 2;// Start from unicode field

				int size = continueIndices_[c] - npos - 1 - bytesRead;
				++c;

				if (size > 0) {
					size /= multiplier; // Number of characters available for string in current record.
					bytesRead += strings_[i].ContinueRead(&*(data_.begin())+npos+bytesRead, size);
					stringSize -= size;
					size = 0;
				}

				while(c<maxContinue && npos+stringSize+1>continueIndices_[c]) {
					ULONG dataSize = (continueIndices_[c] - continueIndices_[c-1] - 1) / multiplier;
					bytesRead += strings_[i].ContinueRead(&*(data_.begin())+npos+bytesRead, dataSize);
					stringSize -= dataSize + 1;
					++c;
				}

				if (stringSize > 0)
					bytesRead += strings_[i].ContinueRead(&*(data_.begin())+npos+bytesRead, stringSize);

				npos += bytesRead;
			}
		}
	}

	return npos + 4*(npos/8224 + 1);
}


void LargeString::Read1(const char* data)
{
	//short stringSize;
	//LittleEndian::Read(data, stringSize, 0, 2);
	LittleEndian::Read(data, unicode_, 2, 1);
	ULONG npos = 3;

	if (unicode_ & 8) {
		LittleEndian::Read(data, richtext_, npos, 2);
		npos += 2;
	}

	if (unicode_ & 4)
		LittleEndian::Read(data, phonetic_, npos, 4);

	name_.clear();
	wname_.clear();
}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值