2016-09-28 19:55 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* contrib/hbssl/hbssl.h
  * contrib/hbssl/ssl_sock.c
  * contrib/hbssl/ssl_inet.c
    + added new 'PHB_ITEM pSSL' parameter to hb_sockexNewSSL() and
      hb_ssl_socketNew() C functions - it allows to bind harbour item
      with SSL pointer which should not be released before connection
      is closed. In new OpenSSL version such tricks can be replaced
      by SSL_up_ref()
      This modification also fixes possible GPF trap when SSL filter
      socket was create dynamically from C code without SSL pointer
      item on HVM stack in 2-nd parameter and removes old hack which
      saved internally 2-nd HVM stack parameter.
    + allow to pass SSL_CTX instead of SSL in "ssl", "ctx" or "key" items
      of hash array used to initialize SSL socket filter. Using SSL_CTX
      allows to use the same hash array to set SSL socket filter for
      different connections
    + allow to use codeblocks or function pointers as "ssl", "ctx" or
      "key" items of hash array used to initialize SSL socket filter

  * contrib/hbssl/hbssl.h
  * contrib/hbssl/sslctx.c
    + added new C function:
         SSL_CTX * hb_SSL_CTX_itemGet( PHB_ITEM pItem )

  * contrib/hbssl/ssl_sock.c
  * src/rtl/hbcom.c
  * src/rtl/hbsocket.c
    ! fixed timeout checking in select()/poll()

  * src/rtl/hbsockhb.c
    ! fixed possible GPF trap when socket filter refuse to create new
      socket wrapper

  * include/hbinit.h
    * in GCC C++ builds for startup code use GCC constructor function
      attribute instead of static variable initialization to avoid
      warnings in new GCC versions

  * src/rtl/hbntos.c
    ! fixed missing '-' in result of negative integer numbers - thanks
      to Luigi Ferraris

  * src/common/hbstr.c
    + added code to round integer part when the size of number is greater
      then double precision (~16 digits).
This commit is contained in:
Przemysław Czerpak
2016-09-28 19:55:11 +02:00
parent 228b0e8a65
commit 35fe3becc7
11 changed files with 188 additions and 48 deletions

View File

@@ -10,6 +10,53 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2016-09-28 19:55 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbssl/hbssl.h
* contrib/hbssl/ssl_sock.c
* contrib/hbssl/ssl_inet.c
+ added new 'PHB_ITEM pSSL' parameter to hb_sockexNewSSL() and
hb_ssl_socketNew() C functions - it allows to bind harbour item
with SSL pointer which should not be released before connection
is closed. In new OpenSSL version such tricks can be replaced
by SSL_up_ref()
This modification also fixes possible GPF trap when SSL filter
socket was create dynamically from C code without SSL pointer
item on HVM stack in 2-nd parameter and removes old hack which
saved internally 2-nd HVM stack parameter.
+ allow to pass SSL_CTX instead of SSL in "ssl", "ctx" or "key" items
of hash array used to initialize SSL socket filter. Using SSL_CTX
allows to use the same hash array to set SSL socket filter for
different connections
+ allow to use codeblocks or function pointers as "ssl", "ctx" or
"key" items of hash array used to initialize SSL socket filter
* contrib/hbssl/hbssl.h
* contrib/hbssl/sslctx.c
+ added new C function:
SSL_CTX * hb_SSL_CTX_itemGet( PHB_ITEM pItem )
* contrib/hbssl/ssl_sock.c
* src/rtl/hbcom.c
* src/rtl/hbsocket.c
! fixed timeout checking in select()/poll()
* src/rtl/hbsockhb.c
! fixed possible GPF trap when socket filter refuse to create new
socket wrapper
* include/hbinit.h
* in GCC C++ builds for startup code use GCC constructor function
attribute instead of static variable initialization to avoid
warnings in new GCC versions
* src/rtl/hbntos.c
! fixed missing '-' in result of negative integer numbers - thanks
to Luigi Ferraris
* src/common/hbstr.c
+ added code to round integer part when the size of number is greater
then double precision (~16 digits).
2016-09-23 11:00 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/gtqtc/gtqtc1.cpp
* removed unnecessary casting after recent modification

View File

@@ -170,9 +170,9 @@ struct _HB_SSLSTREAM;
typedef struct _HB_SSLSTREAM * PHB_SSLSTREAM;
extern PHB_SOCKEX hb_sockexNewSSL( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
HB_MAXINT timeout );
HB_MAXINT timeout, PHB_ITEM pSSL );
extern PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
HB_MAXINT timeout, int * piResult );
HB_MAXINT timeout, PHB_ITEM pSSL, int * piResult );
extern void hb_ssl_socketClose( PHB_SSLSTREAM pStream );
extern const char * hb_ssl_socketErrorStr( int iError );
extern long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd,
@@ -188,6 +188,7 @@ extern BIO * hb_BIO_par( int iParam );
extern void * hb_SSL_CTX_is( int iParam );
extern SSL_CTX * hb_SSL_CTX_par( int iParam );
extern SSL_CTX * hb_SSL_CTX_itemGet( PHB_ITEM pItem );
extern void * hb_SSL_is( int iParam );
extern SSL * hb_SSL_par( int iParam );

View File

@@ -113,8 +113,9 @@ static void hb_inetStartSSL( HB_BOOL fServer )
{
HB_MAXINT timeout = HB_ISNUM( 3 ) ? hb_parnint( 3 ) :
hb_znetInetTimeout( pItem, HB_FALSE );
PHB_SSLSTREAM pStream = hb_ssl_socketNew( sd, ssl, fServer,
timeout, &iResult );
PHB_SSLSTREAM pStream = hb_ssl_socketNew( sd, ssl, fServer, timeout,
hb_param( 2, HB_IT_POINTER ),
&iResult );
if( pStream )
{
if( ! hb_znetInetInitialize( pItem, ( PHB_ZNETSTREAM ) pStream,

View File

@@ -260,12 +260,16 @@ long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd,
void hb_ssl_socketClose( PHB_SSLSTREAM pStream )
{
SSL_shutdown( pStream->ssl );
hb_itemRelease( pStream->pSSL );
if( pStream->pSSL )
hb_itemRelease( pStream->pSSL );
else
SSL_free( pStream->ssl );
hb_xfree( pStream );
}
PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
HB_MAXINT timeout, int * piResult )
HB_MAXINT timeout, PHB_ITEM pSSL,
int * piResult )
{
int iResult;
@@ -276,7 +280,7 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
timer = timeout <= 0 ? 0 : hb_dateMilliSeconds();
pStream->ssl = ssl;
pStream->pSSL = hb_itemNew( hb_param( 2, HB_IT_POINTER ) );
pStream->pSSL = pSSL ? hb_itemNew( pSSL ) : NULL;
pStream->blocking = timeout < 0;
if( hb_socketSetBlockingIO( sd, pStream->blocking ) < 0 )
pStream->blocking = !pStream->blocking;
@@ -307,6 +311,8 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
if( timecurr > timer )
{
timeout -= timecurr - timer;
if( timeout < 0 )
timeout = 0;
timer = timecurr;
}
@@ -345,26 +351,62 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
/* socket filter */
static SSL * s_SSL_itemGet( PHB_ITEM pItem, PHB_ITEM * pSSL, HB_BOOL * pfFree )
{
SSL * ssl = NULL;
if( pItem )
{
PHB_ITEM pRelease = NULL;
if( HB_IS_EVALITEM( pItem ) )
pItem = pRelease = hb_itemDo( pItem, 0 );
ssl = hb_SSL_itemGet( pItem );
if( ssl == NULL )
{
SSL_CTX * ssl_ctx = hb_SSL_CTX_itemGet( pItem );
if( ssl_ctx )
{
ssl = SSL_new( ssl_ctx );
if( pRelease )
hb_itemRelease( pRelease );
pItem = pRelease = NULL;
}
}
if( ssl )
{
* pSSL = pItem;
* pfFree = pRelease != NULL;
}
else if( pRelease )
hb_itemRelease( pRelease );
}
return ssl;
}
#define HB_SSLSOCK_GET( p ) ( ( PHB_SSLSTREAM ) p->cargo )
#define HB_SSLSOCK_READAHEAD 0x40
static PHB_SOCKEX s_sockexNew( HB_SOCKET sd, PHB_ITEM pParams )
{
PHB_SOCKEX pSock;
HB_BOOL fServer = HB_FALSE;
HB_BOOL fServer = HB_FALSE, fFree = HB_FALSE;
HB_MAXINT timeout = -1;
PHB_ITEM pSSL = NULL;
SSL * ssl = NULL;
if( pParams && HB_IS_HASH( pParams ) )
{
PHB_ITEM pItem;
if( ssl == NULL && ( pItem = hb_hashGetCItemPtr( pParams, "ssl" ) ) != NULL )
ssl = hb_SSL_itemGet( pItem );
if( ssl == NULL && ( pItem = hb_hashGetCItemPtr( pParams, "ctx" ) ) != NULL )
ssl = hb_SSL_itemGet( pItem );
if( ssl == NULL && ( pItem = hb_hashGetCItemPtr( pParams, "key" ) ) != NULL )
ssl = hb_SSL_itemGet( pItem );
if( ssl == NULL )
ssl = s_SSL_itemGet( hb_hashGetCItemPtr( pParams, "ssl" ), &pSSL, &fFree );
if( ssl == NULL )
ssl = s_SSL_itemGet( hb_hashGetCItemPtr( pParams, "ctx" ), &pSSL, &fFree );
if( ssl == NULL )
ssl = s_SSL_itemGet( hb_hashGetCItemPtr( pParams, "key" ), &pSSL, &fFree );
if( ( pItem = hb_hashGetCItemPtr( pParams, "timeout" ) ) != NULL &&
HB_IS_NUMERIC( pItem ) )
timeout = hb_itemGetNInt( pItem );
@@ -376,9 +418,11 @@ static PHB_SOCKEX s_sockexNew( HB_SOCKET sd, PHB_ITEM pParams )
fServer = ! hb_itemGetL( pItem );
}
pSock = hb_sockexNewSSL( sd, ssl, fServer, timeout );
pSock = hb_sockexNewSSL( sd, ssl, fServer, timeout, pSSL );
if( pSock )
hb_socekxParamsInit( pSock, pParams );
if( fFree )
hb_itemRelease( pSSL );
return pSock;
}
@@ -405,11 +449,7 @@ static int s_sockexClose( PHB_SOCKEX pSock, HB_BOOL fClose )
int iResult;
if( pSock->cargo )
{
SSL_shutdown( HB_SSLSOCK_GET( pSock )->ssl );
hb_itemRelease( HB_SSLSOCK_GET( pSock )->pSSL );
hb_xfree( pSock->cargo );
}
hb_ssl_socketClose( HB_SSLSOCK_GET( pSock ) );
iResult = hb_sockexRawClear( pSock, fClose );
hb_xfree( pSock );
@@ -527,13 +567,13 @@ static const HB_SOCKET_FILTER s_sockFilter =
};
PHB_SOCKEX hb_sockexNewSSL( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer,
HB_MAXINT timeout )
HB_MAXINT timeout, PHB_ITEM pSSL )
{
PHB_SOCKEX pSock = NULL;
if( sd != HB_NO_SOCKET && ssl )
{
PHB_SSLSTREAM pStream = hb_ssl_socketNew( sd, ssl, fServer, timeout, NULL );
PHB_SSLSTREAM pStream = hb_ssl_socketNew( sd, ssl, fServer, timeout, pSSL, NULL );
if( pStream )
{
pSock = ( PHB_SOCKEX ) hb_xgrabz( sizeof( HB_SOCKEX ) );
@@ -558,7 +598,7 @@ static void s_sslSocketNew( HB_BOOL fServer )
SSL * ssl = hb_SSL_par( 2 );
if( ssl )
pSock = hb_sockexNewSSL( sd, ssl, fServer, hb_parnintdef( 3, - 1 ) );
pSock = hb_sockexNewSSL( sd, ssl, fServer, hb_parnintdef( 3, - 1 ), hb_param( 2, HB_IT_ANY ) );
else if( HB_ISHASH( 2 ) )
pSock = hb_sockexNew( sd, s_sockFilter.pszName, hb_param( 2, HB_IT_ANY ) );
else

View File

@@ -88,6 +88,13 @@ SSL_CTX * hb_SSL_CTX_par( int iParam )
return ph ? ( SSL_CTX * ) *ph : NULL;
}
SSL_CTX * hb_SSL_CTX_itemGet( PHB_ITEM pItem )
{
void ** ph = ( void ** ) hb_itemGetPtrGC( pItem, &s_gcSSL_CTX_funcs );
return ph ? ( SSL_CTX * ) *ph : NULL;
}
const SSL_METHOD * hb_ssl_method_id_to_ptr( int n )
{
const SSL_METHOD * p;

View File

@@ -55,10 +55,13 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessSymbols( PHB_SYMB pSymbols, HB_USHORT uiSy
#define HB_INIT_SYMBOLS_END( func ) HB_INIT_SYMBOLS_EX_END( func, __FILE__, 0L, 0x0000 )
/* By default in all C++ builds use static vars initialization as startup code */
/* By default in all C++ builds use static variable initialization as startup
code with the exception for GCC which new versions show warning about
defined but not used static variable initialized with this method. */
#if defined( __cplusplus ) && ! defined( HB_STATIC_STARTUP ) && \
! defined( HB_PRAGMA_STARTUP ) && ! defined( HB_GNUC_STARTUP ) && \
! defined( HB_INITSEG_STARTUP ) && ! defined( HB_DATASEG_STARTUP )
! defined( HB_INITSEG_STARTUP ) && ! defined( HB_DATASEG_STARTUP ) && \
! defined( __GNUC__ )
#define HB_STATIC_STARTUP
#endif

View File

@@ -843,10 +843,18 @@ char * hb_dblToStr( char * szBuf, HB_SIZE nSize, double dNumber, int iMaxDec )
szResult = szBuf;
if( dNumber < 0 )
{
if( --iLen == 0 )
return NULL;
*szBuf++ = '-';
dFract = modf( -dNumber, &dInt );
if( --iLen == 0 )
{
if( dInt < 1 && dFract < 0.5 )
{
szBuf[ 0 ] = '0';
szBuf[ 1 ] = '\0';
return szBuf;
}
return NULL;
}
*szBuf++ = '-';
}
else
dFract = modf( dNumber, &dInt );
@@ -854,18 +862,14 @@ char * hb_dblToStr( char * szBuf, HB_SIZE nSize, double dNumber, int iMaxDec )
iPos = iLen;
do
{
if( iPos == 0 )
return NULL;
dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase;
szBuf[ --iPos ] = '0' + ( char ) ( dDig + 0.01 );
if( iPos == 0 )
{
if( dInt >= 1 )
return NULL;
break;
}
}
while( dInt >= 1 );
if( iPos > 0 )
memmove( szBuf, szBuf + iPos, HB_MIN( iLen - iPos, iPrec ) );
memmove( szBuf, szBuf + iPos, HB_MIN( iLen - iPos, iPrec + 1 ) );
iPos = iLen - iPos;
fFirst = iPos > 1 || szBuf[ 0 ] != '0';
@@ -873,22 +877,36 @@ char * hb_dblToStr( char * szBuf, HB_SIZE nSize, double dNumber, int iMaxDec )
{
if( iPos >= iPrec )
{
while( iPrec < iPos )
szBuf[ iPrec++ ] = '0';
fFirst = iPos == iPrec ? dFract >= 0.5 : szBuf[ iPrec ] >= '5';
if( iPrec < iPos )
memset( szBuf + iPrec , '0', iPos - iPrec );
if( fFirst )
{
for( ;; )
{
if( --iPrec < 0 )
{
if( iPos == iLen )
return NULL;
memmove( szBuf + 1, szBuf, iPos );
*szBuf = '1';
++iPos;
break;
}
if( szBuf[ iPrec ] != '9' )
{
++szBuf[ iPrec ];
break;
}
szBuf[ iPrec ] = '0';
}
}
iPrec = 0;
}
else
iPrec -= iPos;
}
while( dInt >= 1 )
{
if( iPos >= iLen )
return NULL;
dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase;
szBuf[ iPos++ ] = iPrec-- > 0 ? '0' + ( char ) ( dDig + 0.01 ) : '0';
}
if( iPrec > 0 && iLen - iPos > 1 && iMaxDec != 0 && dFract > 0 )
{
int iDec = iPos;

View File

@@ -576,7 +576,10 @@ static int hb_comCanRead( PHB_COM pCom, HB_MAXINT timeout )
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}
@@ -680,7 +683,10 @@ static int hb_comCanWrite( PHB_COM pCom, HB_MAXINT timeout )
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}

View File

@@ -97,12 +97,14 @@ HB_FUNC( HB_NTOC )
nNumber /= 10;
}
while( nNumber != 0 );
if( fNeg )
szBuffer[ --iPos ] = '-';
hb_retc( szBuffer + iPos );
}
else
hb_retc( hb_dblToStr( szBuffer, sizeof( szBuffer ),
hb_itemGetND( pNumber ), hb_parnidef( 2, 20 ) ) );
hb_itemGetND( pNumber ), hb_parnidef( 2, -1 ) ) );
}
else
hb_retc_null();

View File

@@ -1666,7 +1666,10 @@ static int hb_socketSelectRD( HB_SOCKET sd, HB_MAXINT timeout )
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}
@@ -1775,7 +1778,10 @@ static int hb_socketSelectWR( HB_SOCKET sd, HB_MAXINT timeout )
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}
@@ -1884,7 +1890,10 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout )
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}
@@ -3196,7 +3205,10 @@ int hb_socketSelect( PHB_ITEM pArrayRD, HB_BOOL fSetRD,
{
timeout -= timecurr - timer;
if( timeout > 0 )
{
timer = timecurr;
continue;
}
}
}
}

View File

@@ -580,8 +580,11 @@ PHB_SOCKEX hb_sockexNew( HB_SOCKET sd, const char * pszFilter, PHB_ITEM pParams
pFilters[ i ]->Next( pSock, pParams );
if( pSockNew == NULL )
{
hb_sockexClose( pSock, HB_FALSE );
pSock = NULL;
if( pSock )
{
hb_sockexClose( pSock, HB_FALSE );
pSock = NULL;
}
break;
}
pSock = pSockNew;