From 38af08e97dbe001ef2d9f8fb42519eb74ef469c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Wed, 2 Sep 2015 15:54:08 +0200 Subject: [PATCH] 2015-09-02 15:54 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbapifs.h * src/rtl/filebuf.c * added new C function hb_fileLoadData() - it can be used to load data from already opened regular files and streams * include/harbour.hbx * src/rtl/vfile.c + added new PRG function: hb_vfLoad( , [ ] ) -> | NIL * src/vm/runner.c * use hb_fileLoadData() * contrib/hbwin/win_bmp.c * use hb_fileLoad() --- ChangeLog.txt | 17 +++++++ contrib/hbwin/win_bmp.c | 33 +++++-------- include/harbour.hbx | 1 + include/hbapifs.h | 1 + src/rtl/filebuf.c | 106 ++++++++++++++++++++++------------------ src/rtl/vfile.c | 16 ++++++ src/vm/runner.c | 22 ++++----- 7 files changed, 115 insertions(+), 81 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index e5135a03e7..43817f28c5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,23 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-09-02 15:54 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapifs.h + * src/rtl/filebuf.c + * added new C function hb_fileLoadData() - it can be used to load data + from already opened regular files and streams + + * include/harbour.hbx + * src/rtl/vfile.c + + added new PRG function: + hb_vfLoad( , [ ] ) -> | NIL + + * src/vm/runner.c + * use hb_fileLoadData() + + * contrib/hbwin/win_bmp.c + * use hb_fileLoad() + 2015-09-01 23:04 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * package/harbour.spec + added HBCOMIO, HBPIPEIO, HBTCPIO to RPM package diff --git a/contrib/hbwin/win_bmp.c b/contrib/hbwin/win_bmp.c index 53190d10fe..b8373a97f5 100644 --- a/contrib/hbwin/win_bmp.c +++ b/contrib/hbwin/win_bmp.c @@ -91,34 +91,25 @@ HB_FUNC( WIN_BITMAPTYPE ) HB_FUNC( WIN_LOADBITMAPFILE ) { - char * pBuffer = NULL; - PHB_FILE pFile = hb_fileExtOpen( hb_parcx( 1 ), NULL, - FO_READ | FO_SHARED | FO_PRIVATE | - FXO_SHARELOCK | FXO_NOSEEKPOS, - NULL, NULL ); - if( pFile != NULL ) - { - HB_SIZE nSize = ( HB_SIZE ) hb_fileSize( pFile ); + HB_SIZE nSize; + char * pBuffer = ( char * ) hb_fileLoad( hb_parcx( 1 ), HB_MAX_BMP_SIZE, &nSize ); + if( pBuffer ) + { /* TOFIX: No check is done on read data from disk which is a large security hole and may cause GPF even in simple error cases, like invalid file content. [vszakats] */ - if( nSize > 2 && nSize <= HB_MAX_BMP_SIZE ) - { - pBuffer = ( char * ) hb_xgrab( nSize + 1 ); - if( hb_fileReadAt( pFile, pBuffer, nSize, 0 ) != nSize || - hbwin_bitmapType( pBuffer, nSize ) == HB_WIN_BITMAP_UNKNOWN ) - { - hb_xfree( pBuffer ); - pBuffer = NULL; - } - else - hb_retclen_buffer( pBuffer, nSize ); + if( nSize <= 2 || hbwin_bitmapType( pBuffer, nSize ) == HB_WIN_BITMAP_UNKNOWN ) + { + hb_xfree( pBuffer ); + pBuffer = NULL; } - hb_fileClose( pFile ); } - if( pBuffer == NULL ) + + if( pBuffer ) + hb_retclen_buffer( pBuffer, nSize ); + else hb_retc_null(); } diff --git a/include/harbour.hbx b/include/harbour.hbx index e1195f04bd..2859083242 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -927,6 +927,7 @@ DYNAMIC hb_vfHandle DYNAMIC hb_vfLink DYNAMIC hb_vfLinkRead DYNAMIC hb_vfLinkSym +DYNAMIC hb_vfLoad DYNAMIC hb_vfLock DYNAMIC hb_vfLockTest DYNAMIC hb_vfOpen diff --git a/include/hbapifs.h b/include/hbapifs.h index 04d5f60bab..c1cbdb405b 100644 --- a/include/hbapifs.h +++ b/include/hbapifs.h @@ -418,6 +418,7 @@ extern HB_EXPORT HB_BOOL hb_fileIsLocal( PHB_FILE pFile ); extern HB_EXPORT HB_BOOL hb_fileIsLocalName( const char * pszFileName ); extern HB_EXPORT HB_SIZE hb_fileResult( HB_SIZE nSize ); extern HB_EXPORT HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, HB_SIZE * pnSize ); +extern HB_EXPORT HB_BYTE * hb_fileLoadData( PHB_FILE pFile, HB_SIZE nMaxSize, HB_SIZE * pnSize ); /* interface to PRG level hb_vf*() file pointer items */ diff --git a/src/rtl/filebuf.c b/src/rtl/filebuf.c index 5a8732acc8..5ca26de8b2 100644 --- a/src/rtl/filebuf.c +++ b/src/rtl/filebuf.c @@ -1490,68 +1490,58 @@ HB_SIZE hb_fileResult( HB_SIZE nSize ) #define HB_FILELOAD_BUFFERSIZE 65536 -HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, - HB_SIZE * pnSize ) +HB_BYTE * hb_fileLoadData( PHB_FILE pFile, HB_SIZE nMaxSize, + HB_SIZE * pnSize ) { HB_BYTE * pFileBuf = NULL; HB_SIZE nSize = 0; - PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, - FO_READ | FO_SHARED | FO_PRIVATE | - FXO_SHARELOCK | FXO_NOSEEKPOS, - NULL, NULL ); + HB_FOFFSET nFileSize = hb_fileSize( pFile ); - if( pFile != NULL ) + if( nFileSize == FS_ERROR || + ( nFileSize == 0 && hb_fsError() == HB_FILE_ERR_UNSUPPORTED ) ) { - HB_FOFFSET nFileSize = hb_fileSize( pFile ); + HB_SIZE nRead, nBufSize = 0; - if( nFileSize == FS_ERROR || - ( nFileSize == 0 && hb_fsError() == HB_FILE_ERR_UNSUPPORTED ) ) + for( ;; ) { - HB_SIZE nRead, nBufSize = 0; - - for( ;; ) + if( nBufSize == nSize ) { - if( nBufSize == nSize ) + nBufSize += nBufSize == 0 ? HB_FILELOAD_BUFFERSIZE : nBufSize >> 1; + if( nMaxSize > 0 && nBufSize > nMaxSize ) { - nBufSize += nBufSize == 0 ? HB_FILELOAD_BUFFERSIZE : nBufSize >> 1; - if( nMaxSize > 0 && nBufSize > nMaxSize ) - { - nBufSize = nMaxSize; - if( nBufSize == nSize ) - break; - } - pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nBufSize ); + nBufSize = nMaxSize; + if( nBufSize == nSize ) + break; } - nRead = hb_fileRead( pFile, pFileBuf + nSize, nBufSize - nSize, -1 ); - if( nRead == 0 || nRead == ( HB_SIZE ) FS_ERROR ) - break; - nSize += nRead; + pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nBufSize ); } + nRead = hb_fileRead( pFile, pFileBuf + nSize, nBufSize - nSize, -1 ); + if( nRead == 0 || nRead == ( HB_SIZE ) FS_ERROR ) + break; + nSize += nRead; } - else - { - nSize = ( HB_SIZE ) nFileSize; - if( nMaxSize > 0 && nSize > nMaxSize ) - nSize = nMaxSize; + } + else + { + nSize = ( HB_SIZE ) nFileSize; + if( nMaxSize > 0 && nSize > nMaxSize ) + nSize = nMaxSize; - pFileBuf = ( HB_BYTE * ) hb_xgrab( nSize + 1 ); - nSize = hb_fileReadAt( pFile, pFileBuf, nSize, 0 ); - if( nSize == ( HB_SIZE ) FS_ERROR ) - nSize = 0; - } + pFileBuf = ( HB_BYTE * ) hb_xgrab( nSize + 1 ); + nSize = hb_fileReadAt( pFile, pFileBuf, nSize, 0 ); + if( nSize == ( HB_SIZE ) FS_ERROR ) + nSize = 0; + } - hb_fileClose( pFile ); - - if( nSize > 0 ) - { - pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nSize + 1 ); - pFileBuf[ nSize ] = '\0'; - } - else if( pFileBuf ) - { - hb_xfree( pFileBuf ); - pFileBuf = NULL; - } + if( nSize > 0 ) + { + pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nSize + 1 ); + pFileBuf[ nSize ] = '\0'; + } + else if( pFileBuf ) + { + hb_xfree( pFileBuf ); + pFileBuf = NULL; } if( pnSize ) @@ -1559,3 +1549,23 @@ HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, return pFileBuf; } + +HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, + HB_SIZE * pnSize ) +{ + HB_BYTE * pFileBuf = NULL; + PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, + FO_READ | FO_SHARED | FO_PRIVATE | + FXO_SHARELOCK | FXO_NOSEEKPOS, + NULL, NULL ); + + if( pFile != NULL ) + { + pFileBuf = hb_fileLoadData( pFile, nMaxSize, pnSize ); + hb_fileClose( pFile ); + } + else if( pnSize ) + *pnSize = 0; + + return pFileBuf; +} diff --git a/src/rtl/vfile.c b/src/rtl/vfile.c index b3eadfa985..52cc0d2c17 100644 --- a/src/rtl/vfile.c +++ b/src/rtl/vfile.c @@ -856,3 +856,19 @@ HB_FUNC( HB_VFTEMPFILE ) hb_fsSetFError( hb_fsError() ); hb_storc( szName, 1 ); } + +/* hb_vfLoad( , [ ] ) -> | NIL */ +HB_FUNC( HB_VFLOAD ) +{ + const char * pszFileName = hb_parc( 1 ); + + if( pszFileName ) + { + HB_SIZE nSize; + char * pBuffer = ( char * ) hb_fileLoad( pszFileName, hb_parns( 2 ), &nSize ); + if( pBuffer ) + hb_retclen_buffer( pBuffer, nSize ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 2021, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/src/vm/runner.c b/src/vm/runner.c index 4edcc09fd9..090b14f94e 100644 --- a/src/vm/runner.c +++ b/src/vm/runner.c @@ -602,20 +602,18 @@ static PHRB_BODY hb_hrbLoadFromFile( const char * szHrb, HB_USHORT usMode ) if( pFile != NULL ) { - HB_SIZE nBodySize = ( HB_SIZE ) hb_fileSize( pFile ); + HB_SIZE nBodySize; + HB_BYTE * pBuffer = hb_fileLoadData( pFile, 0, &nBodySize ); - if( nBodySize ) - { - char * pbyBuffer; - - pbyBuffer = ( char * ) hb_xgrab( nBodySize + sizeof( char ) + 1 ); - hb_fileReadAt( pFile, pbyBuffer, nBodySize, 0 ); - pbyBuffer[ nBodySize ] = '\0'; - - pHrbBody = hb_hrbLoad( ( const char * ) pbyBuffer, nBodySize, usMode, szHrb ); - hb_xfree( pbyBuffer ); - } hb_fileClose( pFile ); + + if( pBuffer ) + { + pHrbBody = hb_hrbLoad( ( const char * ) pBuffer, nBodySize, usMode, szHrb ); + hb_xfree( pBuffer ); + } + else + hb_errRT_BASE( EG_CORRUPTION, 9998, NULL, HB_ERR_FUNCNAME, 0 ); } return pHrbBody;