@@ -39,6 +39,8 @@ class ContextListener implements ListenerInterface
39
39
private $ dispatcher ;
40
40
private $ registered ;
41
41
42
+ private static $ unserializeExceptionCode = 0x37313bc ;
43
+
42
44
public function __construct (TokenStorageInterface $ tokenStorage , array $ userProviders , $ contextKey , LoggerInterface $ logger = null , EventDispatcherInterface $ dispatcher = null )
43
45
{
44
46
if (empty ($ contextKey )) {
@@ -77,7 +79,7 @@ public function handle(GetResponseEvent $event)
77
79
return ;
78
80
}
79
81
80
- $ token = unserialize ($ token );
82
+ $ token = $ this -> safelyUnserialize ($ token );
81
83
82
84
if (null !== $ this ->logger ) {
83
85
$ this ->logger ->debug ('Read existing security token from the session. ' , array ('key ' => $ this ->sessionKey ));
@@ -171,4 +173,43 @@ protected function refreshUser(TokenInterface $token)
171
173
172
174
throw new \RuntimeException (sprintf ('There is no user provider for user "%s". ' , get_class ($ user )));
173
175
}
176
+
177
+ private function safelyUnserialize ($ serializedToken )
178
+ {
179
+ $ e = $ token = null ;
180
+ $ prevUnserializeHandler = ini_set ('unserialize_callback_func ' , __CLASS__ .'::handleUnserializeCallback ' );
181
+ $ prevErrorHandler = set_error_handler (function ($ type , $ msg , $ file , $ line , $ context = array ()) use (&$ prevErrorHandler ) {
182
+ if (__FILE__ === $ file ) {
183
+ throw new \UnexpectedValueException ($ msg , self ::$ unserializeExceptionCode );
184
+ }
185
+
186
+ return $ prevErrorHandler ? $ prevErrorHandler ($ type , $ msg , $ file , $ line , $ context ) : false ;
187
+ });
188
+
189
+ try {
190
+ $ token = unserialize ($ serializedToken );
191
+ } catch (\Error $ e ) {
192
+ } catch (\Exception $ e ) {
193
+ }
194
+ restore_error_handler ();
195
+ ini_set ('unserialize_callback_func ' , $ prevUnserializeHandler );
196
+ if ($ e ) {
197
+ if (!$ e instanceof \UnexpectedValueException || self ::$ unserializeExceptionCode !== $ e ->getCode ()) {
198
+ throw $ e ;
199
+ }
200
+ if ($ this ->logger ) {
201
+ $ this ->logger ->warning ('Failed to unserialize the security token from the session. ' , array ('key ' => $ this ->sessionKey , 'received ' => $ serializedToken , 'exception ' => $ e ));
202
+ }
203
+ }
204
+
205
+ return $ token ;
206
+ }
207
+
208
+ /**
209
+ * @internal
210
+ */
211
+ public static function handleUnserializeCallback ($ class )
212
+ {
213
+ throw new \UnexpectedValueException ('Class not found: ' .$ class , self ::$ unserializeExceptionCode );
214
+ }
174
215
}
0 commit comments