diff --git a/src/Ar/CSVFileLib/ANSIC.lby b/src/Ar/CSVFileLib/ANSIC.lby index 85226c0..f9b3fa5 100644 --- a/src/Ar/CSVFileLib/ANSIC.lby +++ b/src/Ar/CSVFileLib/ANSIC.lby @@ -1,6 +1,6 @@  - + CSVFileLib.typ CSVFileLib.var diff --git a/src/Ar/CSVFileLib/CHANGELOG.md b/src/Ar/CSVFileLib/CHANGELOG.md index 49f37dc..f5250ef 100644 --- a/src/Ar/CSVFileLib/CHANGELOG.md +++ b/src/Ar/CSVFileLib/CHANGELOG.md @@ -1,3 +1,8 @@ +2.0.1 - Fix page fault when the file being read is larger than IN.CFG.MaxFileSize + Read buffers now allocate one extra byte so a completely full buffer is still a + valid string, and CSV_ST_OPEN reports CSV_ERR_BUFFERFULL instead of parsing a + truncated file + 2.0.0 - Migrate to Automation Studio 6 1.2.5 - Fix critical bug introduced in 1.2.4 diff --git a/src/Ar/CSVFileLib/CSVFn_Cyclic.c b/src/Ar/CSVFileLib/CSVFn_Cyclic.c index ddbdbf6..3fd7d9c 100644 --- a/src/Ar/CSVFileLib/CSVFn_Cyclic.c +++ b/src/Ar/CSVFileLib/CSVFn_Cyclic.c @@ -588,6 +588,27 @@ switch( t->OUT.STAT.State ){ t->Internal.FIOWrap.IN.CMD.Open= 0; + + /* The file did not fit in the read buffer. FIOWrap passes IN.PAR.len straight + to FileRead, so the buffer is filled completely and the data is truncated + mid-file. Do not parse it. */ + + if( t->Internal.FIOWrap.OUT.STAT.FileLen > t->Internal.ReadBuffer.MaxLength ){ + + csvSetError( (UINT)CSV_ERR_BUFFERFULL, t ); + + break; + + } + + + /* Record how much was actually read and terminate the buffer for parsing */ + + t->Internal.ReadBuffer.CurrentLength= t->Internal.FIOWrap.OUT.STAT.FileLen; + + *(char*)(t->Internal.ReadBuffer.pData + t->Internal.ReadBuffer.CurrentLength)= '\0'; + + t->Internal.LineNumber= 0; t->Internal.SuccessfulLineCount= 0; diff --git a/src/Ar/CSVFileLib/csvClearBuffer.c b/src/Ar/CSVFileLib/csvClearBuffer.c index 42dcbe5..2868b8c 100644 --- a/src/Ar/CSVFileLib/csvClearBuffer.c +++ b/src/Ar/CSVFileLib/csvClearBuffer.c @@ -52,7 +52,7 @@ if( pBuffer == 0 ){ pBuffer->CurrentLength= 0; -memset( (void*)pBuffer->pData, 0, pBuffer->MaxLength ); +memset( (void*)pBuffer->pData, 0, pBuffer->MaxLength + 1 ); return 0; diff --git a/src/Ar/CSVFileLib/csvInitBuffer.c b/src/Ar/CSVFileLib/csvInitBuffer.c index b05d88a..88dfc9d 100644 --- a/src/Ar/CSVFileLib/csvInitBuffer.c +++ b/src/Ar/CSVFileLib/csvInitBuffer.c @@ -56,7 +56,10 @@ if( (BufferLength == 0) memset( pBuffer, 0, sizeof(CSVFileMgr_Int_Buffer_typ) ); -if( TMP_alloc( BufferLength, (void **)&(pBuffer->pData) ) != 0 ) return CSV_ERR_MEMALLOC; +/* Allocate one extra byte so that a completely full buffer is still a valid C string. + MaxLength stays at BufferLength, so all overflow checks remain unchanged. */ + +if( TMP_alloc( BufferLength + 1, (void **)&(pBuffer->pData) ) != 0 ) return CSV_ERR_MEMALLOC; pBuffer->MaxLength= BufferLength;