30
30
31
31
#define RECORD_ERROR (stmt ) _firebird_error(NULL, stmt, __FILE__, __LINE__)
32
32
33
+ #define READ_AND_RETURN_USING_MEMCPY (type , sqldata ) do { \
34
+ type ret; \
35
+ memcpy(&ret, sqldata, sizeof(ret)); \
36
+ return ret; \
37
+ } while (0);
38
+
39
+ static zend_always_inline ISC_INT64 get_isc_int64_from_sqldata (const ISC_SCHAR * sqldata )
40
+ {
41
+ READ_AND_RETURN_USING_MEMCPY (ISC_INT64 , sqldata );
42
+ }
43
+
44
+ static zend_always_inline ISC_LONG get_isc_long_from_sqldata (const ISC_SCHAR * sqldata )
45
+ {
46
+ READ_AND_RETURN_USING_MEMCPY (ISC_LONG , sqldata );
47
+ }
48
+
49
+ static zend_always_inline double get_double_from_sqldata (const ISC_SCHAR * sqldata )
50
+ {
51
+ READ_AND_RETURN_USING_MEMCPY (double , sqldata );
52
+ }
53
+
54
+ static zend_always_inline ISC_TIMESTAMP get_isc_timestamp_from_sqldata (const ISC_SCHAR * sqldata )
55
+ {
56
+ READ_AND_RETURN_USING_MEMCPY (ISC_TIMESTAMP , sqldata );
57
+ }
58
+
59
+ static zend_always_inline ISC_QUAD get_isc_quad_from_sqldata (const ISC_SCHAR * sqldata )
60
+ {
61
+ READ_AND_RETURN_USING_MEMCPY (ISC_QUAD , sqldata );
62
+ }
63
+
33
64
/* free the allocated space for passing field values to the db and back */
34
65
static void free_sqlda (XSQLDA const * sqlda ) /* {{{ */
35
66
{
@@ -380,18 +411,18 @@ static int firebird_stmt_get_col(
380
411
n = * (short * )var -> sqldata ;
381
412
break ;
382
413
case SQL_LONG :
383
- n = * ( ISC_LONG * ) var -> sqldata ;
414
+ n = get_isc_long_from_sqldata ( var -> sqldata ) ;
384
415
break ;
385
416
case SQL_INT64 :
386
- n = * ( ISC_INT64 * ) var -> sqldata ;
417
+ n = get_isc_int64_from_sqldata ( var -> sqldata ) ;
387
418
break ;
388
419
case SQL_DOUBLE :
389
420
break ;
390
421
EMPTY_SWITCH_DEFAULT_CASE ()
391
422
}
392
423
393
424
if ((var -> sqltype & ~1 ) == SQL_DOUBLE ) {
394
- str = zend_strpprintf (0 , "%.*F" , - var -> sqlscale , * ( double * ) var -> sqldata );
425
+ str = zend_strpprintf (0 , "%.*F" , - var -> sqlscale , get_double_from_sqldata ( var -> sqldata ) );
395
426
} else if (n >= 0 ) {
396
427
str = zend_strpprintf (0 , "%" LL_MASK "d.%0*" LL_MASK "d" ,
397
428
n / f , - var -> sqlscale , n % f );
@@ -417,13 +448,13 @@ static int firebird_stmt_get_col(
417
448
ZVAL_LONG (result , * (short * )var -> sqldata );
418
449
break ;
419
450
case SQL_LONG :
420
- ZVAL_LONG (result , * ( ISC_LONG * ) var -> sqldata );
451
+ ZVAL_LONG (result , get_isc_long_from_sqldata ( var -> sqldata ) );
421
452
break ;
422
453
case SQL_INT64 :
423
454
#if SIZEOF_ZEND_LONG >= 8
424
- ZVAL_LONG (result , * ( ISC_INT64 * ) var -> sqldata );
455
+ ZVAL_LONG (result , get_isc_int64_from_sqldata ( var -> sqldata ) );
425
456
#else
426
- ZVAL_STR (result , zend_strpprintf (0 , "%" LL_MASK "d" , * ( ISC_INT64 * ) var -> sqldata ));
457
+ ZVAL_STR (result , zend_strpprintf (0 , "%" LL_MASK "d" , get_isc_int64_from_sqldata ( var -> sqldata ) ));
427
458
#endif
428
459
break ;
429
460
case SQL_FLOAT :
@@ -432,7 +463,7 @@ static int firebird_stmt_get_col(
432
463
break ;
433
464
case SQL_DOUBLE :
434
465
/* TODO: Why is this not returned as the native type? */
435
- ZVAL_STR (result , zend_strpprintf (0 , "%F" , * ( double * ) var -> sqldata ));
466
+ ZVAL_STR (result , zend_strpprintf (0 , "%F" , get_double_from_sqldata ( var -> sqldata ) ));
436
467
break ;
437
468
#ifdef SQL_BOOLEAN
438
469
case SQL_BOOLEAN :
@@ -448,16 +479,21 @@ static int firebird_stmt_get_col(
448
479
fmt = S -> H -> time_format ? S -> H -> time_format : PDO_FB_DEF_TIME_FMT ;
449
480
} else if (0 ) {
450
481
case SQL_TIMESTAMP :
451
- isc_decode_timestamp ((ISC_TIMESTAMP * )var -> sqldata , & t );
482
+ {
483
+ ISC_TIMESTAMP timestamp = get_isc_timestamp_from_sqldata (var -> sqldata );
484
+ isc_decode_timestamp (& timestamp , & t );
485
+ }
452
486
fmt = S -> H -> timestamp_format ? S -> H -> timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT ;
453
487
}
454
488
/* convert the timestamp into a string */
455
489
char buf [80 ];
456
490
size_t len = strftime (buf , sizeof (buf ), fmt , & t );
457
491
ZVAL_STRINGL (result , buf , len );
458
492
break ;
459
- case SQL_BLOB :
460
- return firebird_fetch_blob (stmt , colno , result , (ISC_QUAD * )var -> sqldata );
493
+ case SQL_BLOB : {
494
+ ISC_QUAD quad = get_isc_quad_from_sqldata (var -> sqldata );
495
+ return firebird_fetch_blob (stmt , colno , result , & quad );
496
+ }
461
497
}
462
498
}
463
499
}
@@ -610,7 +646,12 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
610
646
* var -> sqlind = -1 ;
611
647
return 1 ;
612
648
}
613
- return firebird_bind_blob (stmt , (ISC_QUAD * )var -> sqldata , parameter );
649
+ ISC_QUAD quad = get_isc_quad_from_sqldata (var -> sqldata );
650
+ if (firebird_bind_blob (stmt , & quad , parameter ) != 0 ) {
651
+ memcpy (var -> sqldata , & quad , sizeof (quad ));
652
+ return 1 ;
653
+ }
654
+ return 0 ;
614
655
}
615
656
}
616
657
0 commit comments