@@ -61,7 +61,7 @@ public function __construct($offset = 0, $totalNumberOfLines = null, array $skip
61
61
*/
62
62
public function parse ($ value , $ exceptionOnInvalidType = false , $ objectSupport = false , $ objectForMap = false )
63
63
{
64
- if (! preg_match ('//u ' , $ value )) {
64
+ if (false === preg_match ('//u ' , $ value )) {
65
65
throw new ParseException ('The YAML value does not appear to be valid UTF-8. ' );
66
66
}
67
67
$ this ->currentLineNb = -1 ;
@@ -92,13 +92,13 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
92
92
}
93
93
94
94
$ isRef = $ mergeNode = false ;
95
- if (preg_match ('#^\-((?P<leadspaces>\s+)(?P<value>.+? ))?\s* $#u ' , $ this ->currentLine , $ values )) {
95
+ if (self :: preg_match ('#^\-((?P<leadspaces>\s+)(?P<value>.+))?$#u ' , rtrim ( $ this ->currentLine ) , $ values )) {
96
96
if ($ context && 'mapping ' == $ context ) {
97
97
throw new ParseException ('You cannot define a sequence item when in a mapping ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
98
98
}
99
99
$ context = 'sequence ' ;
100
100
101
- if (isset ($ values ['value ' ]) && preg_match ('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
101
+ if (isset ($ values ['value ' ]) && self :: preg_match ('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
102
102
$ isRef = $ matches ['ref ' ];
103
103
$ values ['value ' ] = $ matches ['value ' ];
104
104
}
@@ -108,7 +108,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
108
108
$ data [] = $ this ->parseBlock ($ this ->getRealCurrentLineNb () + 1 , $ this ->getNextEmbedBlock (null , true ), $ exceptionOnInvalidType , $ objectSupport , $ objectForMap );
109
109
} else {
110
110
if (isset ($ values ['leadspaces ' ])
111
- && preg_match ('#^(?P<key> ' .Inline::REGEX_QUOTED_STRING .'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+? ))?\s* $#u ' , $ values ['value ' ], $ matches )
111
+ && self :: preg_match ('#^(?P<key> ' .Inline::REGEX_QUOTED_STRING .'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+))?$#u ' , rtrim ( $ values ['value ' ]) , $ matches )
112
112
) {
113
113
// this is a compact notation element, add to next block and parse
114
114
$ block = $ values ['value ' ];
@@ -124,7 +124,10 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
124
124
if ($ isRef ) {
125
125
$ this ->refs [$ isRef ] = end ($ data );
126
126
}
127
- } elseif (preg_match ('#^(?P<key> ' .Inline::REGEX_QUOTED_STRING .'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u ' , $ this ->currentLine , $ values ) && (false === strpos ($ values ['key ' ], ' # ' ) || in_array ($ values ['key ' ][0 ], array ('" ' , "' " )))) {
127
+ } elseif (
128
+ self ::preg_match ('#^(?P<key> ' .Inline::REGEX_QUOTED_STRING .'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+))?$#u ' , rtrim ($ this ->currentLine ), $ values )
129
+ && (false === strpos ($ values ['key ' ], ' # ' ) || in_array ($ values ['key ' ][0 ], array ('" ' , "' " )))
130
+ ) {
128
131
if ($ context && 'sequence ' == $ context ) {
129
132
throw new ParseException ('You cannot define a mapping item when in a sequence ' , $ this ->currentLineNb + 1 , $ this ->currentLine );
130
133
}
@@ -191,7 +194,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
191
194
$ data += $ parsed ; // array union
192
195
}
193
196
}
194
- } elseif (isset ($ values ['value ' ]) && preg_match ('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
197
+ } elseif (isset ($ values ['value ' ]) && self :: preg_match ('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
195
198
$ isRef = $ matches ['ref ' ];
196
199
$ values ['value ' ] = $ matches ['value ' ];
197
200
}
@@ -250,27 +253,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
250
253
return $ value ;
251
254
}
252
255
253
- switch (preg_last_error ()) {
254
- case PREG_INTERNAL_ERROR :
255
- $ error = 'Internal PCRE error. ' ;
256
- break ;
257
- case PREG_BACKTRACK_LIMIT_ERROR :
258
- $ error = 'pcre.backtrack_limit reached. ' ;
259
- break ;
260
- case PREG_RECURSION_LIMIT_ERROR :
261
- $ error = 'pcre.recursion_limit reached. ' ;
262
- break ;
263
- case PREG_BAD_UTF8_ERROR :
264
- $ error = 'Malformed UTF-8 data. ' ;
265
- break ;
266
- case PREG_BAD_UTF8_OFFSET_ERROR :
267
- $ error = 'Offset doesn \'t correspond to the begin of a valid UTF-8 code point. ' ;
268
- break ;
269
- default :
270
- $ error = 'Unable to parse. ' ;
271
- }
272
-
273
- throw new ParseException ($ error , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
256
+ throw new ParseException ('Unable to parse ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
274
257
}
275
258
}
276
259
@@ -515,7 +498,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
515
498
return $ this ->refs [$ value ];
516
499
}
517
500
518
- if (preg_match ('/^ ' .self ::BLOCK_SCALAR_HEADER_PATTERN .'$/ ' , $ value , $ matches )) {
501
+ if (self :: preg_match ('/^ ' .self ::BLOCK_SCALAR_HEADER_PATTERN .'$/ ' , $ value , $ matches )) {
519
502
$ modifiers = isset ($ matches ['modifiers ' ]) ? $ matches ['modifiers ' ] : '' ;
520
503
521
504
return $ this ->parseBlockScalar ($ matches ['separator ' ], preg_replace ('#\d+# ' , '' , $ modifiers ), (int ) abs ($ modifiers ));
@@ -570,7 +553,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
570
553
571
554
// determine indentation if not specified
572
555
if (0 === $ indentation ) {
573
- if (preg_match ('/^ +/ ' , $ this ->currentLine , $ matches )) {
556
+ if (self :: preg_match ('/^ +/ ' , $ this ->currentLine , $ matches )) {
574
557
$ indentation = strlen ($ matches [0 ]);
575
558
}
576
559
}
@@ -581,7 +564,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
581
564
while (
582
565
$ notEOF && (
583
566
$ isCurrentLineBlank ||
584
- preg_match ($ pattern , $ this ->currentLine , $ matches )
567
+ self :: preg_match ($ pattern , $ this ->currentLine , $ matches )
585
568
)
586
569
) {
587
570
if ($ isCurrentLineBlank && strlen ($ this ->currentLine ) > $ indentation ) {
@@ -804,6 +787,49 @@ private function isStringUnIndentedCollectionItem()
804
787
*/
805
788
private function isBlockScalarHeader ()
806
789
{
807
- return (bool ) preg_match ('~ ' .self ::BLOCK_SCALAR_HEADER_PATTERN .'$~ ' , $ this ->currentLine );
790
+ return (bool ) self ::preg_match ('~ ' .self ::BLOCK_SCALAR_HEADER_PATTERN .'$~ ' , $ this ->currentLine );
791
+ }
792
+
793
+ /**
794
+ * A local wrapper for `preg_match` which will throw a ParseException if there
795
+ * is an internal error in the PCRE engine.
796
+ *
797
+ * This avoids us needing to check for "false" every time PCRE is used
798
+ * in the YAML engine
799
+ *
800
+ * @throws ParseException on a PCRE internal error
801
+ *
802
+ * @see preg_last_error()
803
+ *
804
+ * @internal
805
+ */
806
+ public static function preg_match ($ pattern , $ subject , &$ matches = null , $ flags = 0 , $ offset = 0 )
807
+ {
808
+ $ ret = preg_match ($ pattern , $ subject , $ matches , $ flags , $ offset );
809
+ if ($ ret === false ) {
810
+ switch (preg_last_error ()) {
811
+ case PREG_INTERNAL_ERROR :
812
+ $ error = 'Internal PCRE error. ' ;
813
+ break ;
814
+ case PREG_BACKTRACK_LIMIT_ERROR :
815
+ $ error = 'pcre.backtrack_limit reached. ' ;
816
+ break ;
817
+ case PREG_RECURSION_LIMIT_ERROR :
818
+ $ error = 'pcre.recursion_limit reached. ' ;
819
+ break ;
820
+ case PREG_BAD_UTF8_ERROR :
821
+ $ error = 'Malformed UTF-8 data. ' ;
822
+ break ;
823
+ case PREG_BAD_UTF8_OFFSET_ERROR :
824
+ $ error = 'Offset doesn \'t correspond to the begin of a valid UTF-8 code point. ' ;
825
+ break ;
826
+ default :
827
+ $ error = 'Error. ' ;
828
+ }
829
+
830
+ throw new ParseException ($ error );
831
+ }
832
+
833
+ return $ ret ;
808
834
}
809
835
}
0 commit comments