28
28
#include "php_mbregex.h"
29
29
#include "mbstring.h"
30
30
#include "libmbfl/filters/mbfilter_utf8.h"
31
+ #include <stdbool.h>
31
32
32
33
#include "php_onig_compat.h" /* must come prior to the oniguruma header */
33
34
#include <oniguruma.h>
@@ -600,8 +601,8 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT
600
601
/* }}} */
601
602
602
603
/* {{{ _php_mb_regex_init_options */
603
- static void
604
- _php_mb_regex_init_options ( const char * parg , size_t narg , OnigOptionType * option , OnigSyntaxType * * syntax , int * eval )
604
+ static bool _php_mb_regex_init_options ( const char * parg , size_t narg , OnigOptionType * option ,
605
+ OnigSyntaxType * * syntax , uint32_t option_arg_num )
605
606
{
606
607
size_t n ;
607
608
char c ;
@@ -660,14 +661,16 @@ _php_mb_regex_init_options(const char *parg, size_t narg, OnigOptionType *option
660
661
* syntax = ONIG_SYNTAX_POSIX_EXTENDED ;
661
662
break ;
662
663
case 'e' :
663
- if ( eval != NULL ) * eval = 1 ;
664
- break ;
664
+ zend_argument_value_error ( option_arg_num , "option 'e' is not supported" ) ;
665
+ return false ;
665
666
default :
667
+ // TODO Unsupported ValueError
666
668
break ;
667
669
}
668
670
}
669
671
if (option != NULL ) * option |=optm ;
670
672
}
673
+ return true;
671
674
}
672
675
/* }}} */
673
676
@@ -908,6 +911,11 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
908
911
RETURN_THROWS ();
909
912
}
910
913
914
+ if (arg_pattern_len == 0 ) {
915
+ zend_argument_value_error (1 , "must not be empty" );
916
+ RETURN_THROWS ();
917
+ }
918
+
911
919
if (array != NULL ) {
912
920
array = zend_try_array_init (array );
913
921
if (!array ) {
@@ -920,20 +928,15 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
920
928
string_len ,
921
929
php_mb_regex_get_mbctype_encoding ()
922
930
)) {
923
- RETURN_FALSE ;
931
+ zend_argument_value_error (2 , "must be a valid string in '%s'" , php_mb_regex_get_mbctype ());
932
+ RETURN_THROWS ();
924
933
}
925
934
926
935
options = MBREX (regex_default_options );
927
936
if (icase ) {
928
937
options |= ONIG_OPTION_IGNORECASE ;
929
938
}
930
939
931
- if (arg_pattern_len == 0 ) {
932
- php_error_docref (NULL , E_WARNING , "Empty pattern" );
933
- RETVAL_FALSE ;
934
- goto out ;
935
- }
936
-
937
940
re = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , options , MBREX (regex_default_syntax ));
938
941
if (re == NULL ) {
939
942
RETVAL_FALSE ;
@@ -1017,15 +1020,14 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
1017
1020
smart_str out_buf = {0 };
1018
1021
smart_str eval_buf = {0 };
1019
1022
smart_str * pbuf ;
1020
- int err , eval , n ;
1023
+ int err , n ;
1021
1024
OnigUChar * pos ;
1022
1025
OnigUChar * string_lim ;
1023
1026
char * description = NULL ;
1024
1027
1025
1028
const mbfl_encoding * enc = php_mb_regex_get_mbctype_encoding ();
1026
1029
ZEND_ASSERT (enc != NULL );
1027
1030
1028
- eval = 0 ;
1029
1031
{
1030
1032
char * option_str = NULL ;
1031
1033
size_t option_str_len = 0 ;
@@ -1049,42 +1051,36 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
1049
1051
}
1050
1052
1051
1053
if (!php_mb_check_encoding (string , string_len , enc )) {
1052
- RETURN_NULL ();
1054
+ zend_argument_value_error (3 , "must be a valid string in '%s'" , php_mb_regex_get_mbctype ());
1055
+ RETURN_THROWS ();
1053
1056
}
1054
1057
1055
1058
if (option_str != NULL ) {
1056
- _php_mb_regex_init_options (option_str , option_str_len , & options , & syntax , & eval );
1059
+ /* Initialize option and in case of failure it means there is a value error */
1060
+ if (!_php_mb_regex_init_options (option_str , option_str_len , & options , & syntax , 4 )) {
1061
+ RETURN_THROWS ();
1062
+ }
1057
1063
} else {
1058
1064
options |= MBREX (regex_default_options );
1059
1065
syntax = MBREX (regex_default_syntax );
1060
1066
}
1061
1067
}
1062
- if (eval && !is_callable ) {
1063
- php_error_docref (NULL , E_WARNING , "The 'e' option is no longer supported, use mb_ereg_replace_callback instead" );
1064
- RETURN_FALSE ;
1065
- }
1066
1068
1067
1069
/* create regex pattern buffer */
1068
1070
re = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , options , syntax );
1069
1071
if (re == NULL ) {
1072
+ // Should this be considered an error instead?
1070
1073
RETURN_FALSE ;
1071
1074
}
1072
1075
1073
- if (eval || is_callable ) {
1076
+ if (is_callable ) {
1074
1077
pbuf = & eval_buf ;
1075
1078
description = zend_make_compiled_string_description ("mbregex replace" );
1076
1079
} else {
1077
1080
pbuf = & out_buf ;
1078
1081
description = NULL ;
1079
1082
}
1080
1083
1081
- if (is_callable ) {
1082
- if (eval ) {
1083
- php_error_docref (NULL , E_WARNING , "Option 'e' cannot be used with replacement callback" );
1084
- RETURN_FALSE ;
1085
- }
1086
- }
1087
-
1088
1084
/* do the actual work */
1089
1085
err = 0 ;
1090
1086
pos = (OnigUChar * )string ;
@@ -1106,35 +1102,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
1106
1102
mb_regex_substitute (pbuf , string , string_len , replace , replace_len , re , regs , enc );
1107
1103
}
1108
1104
1109
- if (eval ) {
1110
- zval v ;
1111
- zend_string * eval_str ;
1112
- /* null terminate buffer */
1113
- smart_str_0 (& eval_buf );
1114
-
1115
- if (eval_buf .s ) {
1116
- eval_str = eval_buf .s ;
1117
- } else {
1118
- eval_str = ZSTR_EMPTY_ALLOC ();
1119
- }
1120
-
1121
- /* do eval */
1122
- if (zend_eval_stringl (ZSTR_VAL (eval_str ), ZSTR_LEN (eval_str ), & v , description ) == FAILURE ) {
1123
- efree (description );
1124
- zend_throw_error (NULL , "Failed evaluating code: %s%s" , PHP_EOL , ZSTR_VAL (eval_str ));
1125
- onig_region_free (regs , 1 );
1126
- smart_str_free (& out_buf );
1127
- smart_str_free (& eval_buf );
1128
- RETURN_FALSE ;
1129
- }
1130
-
1131
- /* result of eval */
1132
- convert_to_string (& v );
1133
- smart_str_appendl (& out_buf , Z_STRVAL (v ), Z_STRLEN (v ));
1134
- /* Clean up */
1135
- smart_str_free (& eval_buf );
1136
- zval_ptr_dtor_str (& v );
1137
- } else if (is_callable ) {
1105
+ if (is_callable ) {
1138
1106
zval args [1 ];
1139
1107
zval subpats , retval ;
1140
1108
int i ;
@@ -1163,7 +1131,9 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
1163
1131
zval_ptr_dtor (& retval );
1164
1132
} else {
1165
1133
if (!EG (exception )) {
1166
- php_error_docref (NULL , E_WARNING , "Unable to call custom replacement function" );
1134
+ zend_throw_error (NULL , "Unable to call custom replacement function" );
1135
+ zval_ptr_dtor (& subpats );
1136
+ RETURN_THROWS ();
1167
1137
}
1168
1138
}
1169
1139
zval_ptr_dtor (& subpats );
@@ -1195,6 +1165,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
1195
1165
}
1196
1166
smart_str_free (& eval_buf );
1197
1167
1168
+ // Need to investigate if failure in Oniguruma and if should throw.
1198
1169
if (err <= -2 ) {
1199
1170
smart_str_free (& out_buf );
1200
1171
RETVAL_FALSE ;
@@ -1255,11 +1226,13 @@ PHP_FUNCTION(mb_split)
1255
1226
}
1256
1227
1257
1228
if (!php_mb_check_encoding (string , string_len , php_mb_regex_get_mbctype_encoding ())) {
1258
- RETURN_FALSE ;
1229
+ zend_argument_value_error (2 , "must be a valid string in '%s'" , php_mb_regex_get_mbctype ());
1230
+ RETURN_THROWS ();
1259
1231
}
1260
1232
1261
1233
/* create regex pattern buffer */
1262
1234
if ((re = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , MBREX (regex_default_options ), MBREX (regex_default_syntax ))) == NULL ) {
1235
+ // TODO throw as invalid regex?
1263
1236
RETURN_FALSE ;
1264
1237
}
1265
1238
@@ -1296,6 +1269,7 @@ PHP_FUNCTION(mb_split)
1296
1269
onig_region_free (regs , 1 );
1297
1270
1298
1271
/* see if we encountered an error */
1272
+ // ToDo investigate if this can actually/should happen ...
1299
1273
if (err <= -2 ) {
1300
1274
OnigUChar err_str [ONIG_MAX_ERROR_MESSAGE_LEN ];
1301
1275
onig_error_code_to_str (err_str , err );
@@ -1341,18 +1315,22 @@ PHP_FUNCTION(mb_ereg_match)
1341
1315
}
1342
1316
1343
1317
if (option_str != NULL ) {
1344
- _php_mb_regex_init_options (option_str , option_str_len , & option , & syntax , NULL );
1318
+ if (!_php_mb_regex_init_options (option_str , option_str_len , & option , & syntax , 3 )) {
1319
+ RETURN_THROWS ();
1320
+ }
1345
1321
} else {
1346
1322
option |= MBREX (regex_default_options );
1347
1323
syntax = MBREX (regex_default_syntax );
1348
1324
}
1349
1325
}
1350
1326
1351
1327
if (!php_mb_check_encoding (string , string_len , php_mb_regex_get_mbctype_encoding ())) {
1352
- RETURN_FALSE ;
1328
+ zend_argument_value_error (2 , "must be a valid string in '%s'" , php_mb_regex_get_mbctype ());
1329
+ RETURN_THROWS ();
1353
1330
}
1354
1331
1355
1332
if ((re = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , option , syntax )) == NULL ) {
1333
+ // TODO throw as invalid regex?
1356
1334
RETURN_FALSE ;
1357
1335
}
1358
1336
@@ -1398,7 +1376,9 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode)
1398
1376
1399
1377
if (arg_options ) {
1400
1378
option = 0 ;
1401
- _php_mb_regex_init_options (arg_options , arg_options_len , & option , & syntax , NULL );
1379
+ if (!_php_mb_regex_init_options (arg_options , arg_options_len , & option , & syntax , 2 )) {
1380
+ RETURN_THROWS ();
1381
+ }
1402
1382
}
1403
1383
1404
1384
if (MBREX (search_regs )) {
@@ -1409,6 +1389,7 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode)
1409
1389
if (arg_pattern ) {
1410
1390
/* create regex pattern buffer */
1411
1391
if ((MBREX (search_re ) = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , option , MBREX (regex_default_syntax ))) == NULL ) {
1392
+ // TODO throw as invalid regex?
1412
1393
RETURN_FALSE ;
1413
1394
}
1414
1395
}
@@ -1422,13 +1403,13 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode)
1422
1403
}
1423
1404
1424
1405
if (MBREX (search_re ) == NULL ) {
1425
- php_error_docref (NULL , E_WARNING , "No regex given " );
1426
- RETURN_FALSE ;
1406
+ zend_throw_error (NULL , "No pattern was provided " );
1407
+ RETURN_THROWS () ;
1427
1408
}
1428
1409
1429
1410
if (str == NULL ) {
1430
- php_error_docref (NULL , E_WARNING , "No string given " );
1431
- RETURN_FALSE ;
1411
+ zend_throw_error (NULL , "No string was provided " );
1412
+ RETURN_THROWS () ;
1432
1413
}
1433
1414
1434
1415
MBREX (search_regs ) = onig_region_new ();
@@ -1531,21 +1512,24 @@ PHP_FUNCTION(mb_ereg_search_init)
1531
1512
}
1532
1513
1533
1514
if (ZEND_NUM_ARGS () > 1 && arg_pattern_len == 0 ) {
1534
- php_error_docref ( NULL , E_WARNING , "Empty pattern " );
1535
- RETURN_FALSE ;
1515
+ zend_argument_value_error ( 2 , "must not be empty " );
1516
+ RETURN_THROWS () ;
1536
1517
}
1537
1518
1538
1519
option = MBREX (regex_default_options );
1539
1520
syntax = MBREX (regex_default_syntax );
1540
1521
1541
1522
if (ZEND_NUM_ARGS () == 3 ) {
1542
1523
option = 0 ;
1543
- _php_mb_regex_init_options (arg_options , arg_options_len , & option , & syntax , NULL );
1524
+ if (!_php_mb_regex_init_options (arg_options , arg_options_len , & option , & syntax , 3 )) {
1525
+ RETURN_THROWS ();
1526
+ }
1544
1527
}
1545
1528
1546
1529
if (ZEND_NUM_ARGS () > 1 ) {
1547
1530
/* create regex pattern buffer */
1548
1531
if ((MBREX (search_re ) = php_mbregex_compile_pattern (arg_pattern , arg_pattern_len , option , syntax )) == NULL ) {
1532
+ // TODO throw as invalid regex?
1549
1533
RETURN_FALSE ;
1550
1534
}
1551
1535
}
@@ -1556,18 +1540,15 @@ PHP_FUNCTION(mb_ereg_search_init)
1556
1540
1557
1541
ZVAL_STR_COPY (& MBREX (search_str ), arg_str );
1558
1542
1559
- if (php_mb_check_encoding (
1560
- ZSTR_VAL (arg_str ),
1561
- ZSTR_LEN (arg_str ),
1562
- php_mb_regex_get_mbctype_encoding ()
1563
- )) {
1564
- MBREX (search_pos ) = 0 ;
1565
- RETVAL_TRUE ;
1566
- } else {
1543
+ if (!php_mb_check_encoding (ZSTR_VAL (arg_str ), ZSTR_LEN (arg_str ), php_mb_regex_get_mbctype_encoding ())) {
1567
1544
MBREX (search_pos ) = ZSTR_LEN (arg_str );
1568
- RETVAL_FALSE ;
1545
+ zend_argument_value_error (1 , "must be a valid string in '%s'" , php_mb_regex_get_mbctype ());
1546
+ RETURN_THROWS ();
1569
1547
}
1570
1548
1549
+ MBREX (search_pos ) = 0 ;
1550
+ RETVAL_TRUE ;
1551
+
1571
1552
if (MBREX (search_regs ) != NULL ) {
1572
1553
onig_region_free (MBREX (search_regs ), 1 );
1573
1554
MBREX (search_regs ) = NULL ;
@@ -1613,6 +1594,7 @@ PHP_FUNCTION(mb_ereg_search_getregs)
1613
1594
onig_foreach_name (MBREX (search_re ), mb_regex_groups_iter , & args );
1614
1595
}
1615
1596
} else {
1597
+ // TODO This seems to be some logical error, promote to Error
1616
1598
RETVAL_FALSE ;
1617
1599
}
1618
1600
}
@@ -1646,12 +1628,12 @@ PHP_FUNCTION(mb_ereg_search_setpos)
1646
1628
}
1647
1629
1648
1630
if (position < 0 || (!Z_ISUNDEF (MBREX (search_str )) && Z_TYPE (MBREX (search_str )) == IS_STRING && (size_t )position > Z_STRLEN (MBREX (search_str )))) {
1649
- php_error_docref (NULL , E_WARNING , "Position is out of range" );
1650
- MBREX (search_pos ) = 0 ;
1651
- RETURN_FALSE ;
1631
+ zend_argument_value_error (1 , "is out of range" );
1632
+ RETURN_THROWS ();
1652
1633
}
1653
1634
1654
1635
MBREX (search_pos ) = position ;
1636
+ // TODO Return void
1655
1637
RETURN_TRUE ;
1656
1638
}
1657
1639
/* }}} */
@@ -1687,7 +1669,9 @@ PHP_FUNCTION(mb_regex_set_options)
1687
1669
if (string != NULL ) {
1688
1670
opt = 0 ;
1689
1671
syntax = NULL ;
1690
- _php_mb_regex_init_options (string , string_len , & opt , & syntax , NULL );
1672
+ if (!_php_mb_regex_init_options (string , string_len , & opt , & syntax , 1 )) {
1673
+ RETURN_THROWS ();
1674
+ }
1691
1675
_php_mb_regex_set_options (opt , syntax , & prev_opt , & prev_syntax );
1692
1676
opt = prev_opt ;
1693
1677
syntax = prev_syntax ;
0 commit comments