@@ -1332,9 +1332,11 @@ SQLRETURN sql2c_double(esodbc_rec_st *arec, esodbc_rec_st *irec,
1332
1332
1333
1333
case SQL_C_FLOAT :
1334
1334
REJECT_IF_NULL_DEST_BUFF (stmt , data_ptr );
1335
- udbl = dbl < 0 ? - dbl : dbl ;
1336
- if (udbl < FLT_MIN || FLT_MAX < udbl ) {
1337
- REJECT_AS_OOR (stmt , dbl , /* is fixed */ FALSE, SQLREAL );
1335
+ if (dbl ) {
1336
+ udbl = dbl < 0 ? - dbl : dbl ;
1337
+ if (udbl < FLT_MIN || FLT_MAX < udbl ) {
1338
+ REJECT_AS_OOR (stmt , dbl , /* is fixed */ FALSE, SQLREAL );
1339
+ }
1338
1340
}
1339
1341
* (SQLREAL * )data_ptr = (SQLREAL )dbl ;
1340
1342
write_out_octets (octet_len_ptr , sizeof (SQLREAL ), irec );
@@ -1382,15 +1384,38 @@ static SQLRETURN wstr_to_cstr(esodbc_rec_st *arec, esodbc_rec_st *irec,
1382
1384
1383
1385
gd_offset_apply (stmt , & xstr );
1384
1386
1387
+ assert (xstr .w .str [xstr .w .cnt ] == L'\0' );
1388
+ /* how much space would the converted string take? */
1389
+ in_bytes = WCS2U8 (xstr .w .str , (int )xstr .w .cnt + 1 , NULL , 0 );
1390
+ if (in_bytes <= 0 ) {
1391
+ ERRNH (stmt , "failed to convert wchar* to char* for string `"
1392
+ LWPDL "`." , LWSTR (& xstr .w ));
1393
+ RET_HDIAGS (stmt , SQL_STATE_22018 );
1394
+ }
1395
+ /* out length needs to be provided with no (potential) truncation. */
1396
+ if (octet_len_ptr ) {
1397
+ /* chars_0 accounts for 0-terminator, so WCS2U8 will count that in
1398
+ * the output as well => trim it, since we must not count it when
1399
+ * indicating the length to the application */
1400
+ out_bytes = in_bytes - 1 ;
1401
+ write_out_octets (octet_len_ptr , out_bytes , irec );
1402
+ } else {
1403
+ DBGH (stmt , "REC@0x%p, NULL octet_len_ptr." , arec );
1404
+ }
1405
+
1385
1406
if (data_ptr ) {
1386
1407
charp = (char * )data_ptr ;
1387
1408
1388
- in_bytes = (int )buff_octet_size ((xstr .w .cnt + 1 ) * sizeof (SQLWCHAR ),
1389
- sizeof (SQLCHAR ), arec , irec , & state );
1409
+ /* calculate how much of original data could possibly be copied in
1410
+ * provided buffer; this will be given as a limitation to W-to-C
1411
+ * conversion function. */
1412
+ in_bytes = (int )buff_octet_size (in_bytes , sizeof (SQLCHAR ), arec , irec ,
1413
+ & state );
1390
1414
/* trim the original string until it fits in output buffer, with given
1391
1415
* length limitation */
1392
1416
for (c = (int )xstr .w .cnt + 1 ; 0 < c ; c -- ) {
1393
1417
out_bytes = WCS2U8 (xstr .w .str , c , charp , in_bytes );
1418
+ /* if user gives 0 as buffer size, out_bytes will also be 0 */
1394
1419
if (out_bytes <= 0 ) {
1395
1420
if (WCS2U8_BUFF_INSUFFICIENT ) {
1396
1421
continue ;
@@ -1404,10 +1429,7 @@ static SQLRETURN wstr_to_cstr(esodbc_rec_st *arec, esodbc_rec_st *irec,
1404
1429
}
1405
1430
}
1406
1431
1407
- /* if 0's present => 0 < out_bytes */
1408
- assert (xstr .w .str [xstr .w .cnt ] == L'\0' );
1409
1432
assert (0 < out_bytes );
1410
- /* if user gives 0 as buffer size, out_bytes will also be 0 */
1411
1433
if (charp [out_bytes - 1 ]) {
1412
1434
/* ran out of buffer => not 0-terminated and truncated already */
1413
1435
charp [out_bytes - 1 ] = 0 ;
@@ -1418,30 +1440,12 @@ static SQLRETURN wstr_to_cstr(esodbc_rec_st *arec, esodbc_rec_st *irec,
1418
1440
/* only update offset if data is copied out */
1419
1441
gd_offset_update (stmt , xstr .w .cnt , c );
1420
1442
1421
- DBGH (stmt , "REC@0x%p, data_ptr@0x%p, copied %zd bytes: `" LWPD "`." ,
1443
+ DBGH (stmt , "REC@0x%p, data_ptr@0x%p, copied %d bytes: `" LCPD "`." ,
1422
1444
arec , data_ptr , out_bytes , charp );
1423
1445
} else {
1424
1446
DBGH (stmt , "REC@0x%p, NULL data_ptr." , arec );
1425
1447
}
1426
1448
1427
- /* if length needs to be given, calculate it (not truncated) & converted */
1428
- if (octet_len_ptr ) {
1429
- out_bytes = (size_t )WCS2U8 (xstr .w .str , (int )xstr .w .cnt + 1 , NULL , 0 );
1430
- if (out_bytes <= 0 ) {
1431
- ERRNH (stmt , "failed to convert wchar* to char* for string `"
1432
- LWPDL "`." , LWSTR (& xstr .w ));
1433
- RET_HDIAGS (stmt , SQL_STATE_22018 );
1434
- } else {
1435
- /* chars_0 accounts for 0-terminator, so WCS2U8 will count that in
1436
- * the output as well => trim it, since we must not count it when
1437
- * indicating the length to the application */
1438
- out_bytes -- ;
1439
- }
1440
- write_out_octets (octet_len_ptr , out_bytes , irec );
1441
- } else {
1442
- DBGH (stmt , "REC@0x%p, NULL octet_len_ptr." , arec );
1443
- }
1444
-
1445
1449
if (state != SQL_STATE_00000 ) {
1446
1450
RET_HDIAGS (stmt , state );
1447
1451
}
0 commit comments