diff --git a/core/composer.json b/core/composer.json
index 438d4312b3..a1e70748f4 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -31,7 +31,7 @@
         "symfony/process": "~3.4.0",
         "symfony/polyfill-iconv": "^1.0",
         "symfony/yaml": "~3.4.5",
-        "typo3/phar-stream-wrapper": "^3.1.2",
+        "typo3/phar-stream-wrapper": "^3.1.2 || dev-master",
         "twig/twig": "^1.38.2",
         "doctrine/common": "^2.7",
         "doctrine/annotations": "^1.4",
diff --git a/core/drupalci.yml b/core/drupalci.yml
index ed02d43c63..7621541666 100644
--- a/core/drupalci.yml
+++ b/core/drupalci.yml
@@ -15,6 +15,10 @@ build:
         sniff-all-files: false
         halt-on-fail: false
     testing:
+      # Update PHPUnit & friends.
+      container_command:
+        commands:
+          - "sudo -u www-data /usr/local/bin/composer require typo3/phar-stream-wrapper:dev-master --no-progress"
       # run_tests task is executed several times in order of performance speeds.
       # halt-on-fail can be set on the run_tests tasks in order to fail fast.
       # suppress-deprecations is false in order to be alerted to usages of
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index d2d54979b7..34508bcce0 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1128,7 +1128,7 @@ function template_preprocess_item_list(&$variables) {
             // \Drupal\Core\Render\Element::children(), which cannot be used
             // here, since it triggers an error on string values.
             foreach ($child as $child_key => $child_value) {
-              if ($child_key[0] !== '#') {
+              if (is_string($child_key) && $child_key[0] !== '#') {
                 $child['#items'][$child_key] = $child_value;
                 unset($child[$child_key]);
               }
diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php b/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php
index 1d8cf2fbc3..4daab37105 100644
--- a/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php
+++ b/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php
@@ -966,13 +966,16 @@ private function Identifier()
 
         $className = $this->lexer->token['value'];
 
-        while ($this->lexer->lookahead['position'] === ($this->lexer->token['position'] + strlen($this->lexer->token['value']))
+        $position = $this->lexer->lookahead['position'] ?? NULL;
+        while ($position === ($this->lexer->token['position'] + strlen($this->lexer->token['value']))
                 && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) {
 
             $this->match(DocLexer::T_NAMESPACE_SEPARATOR);
             $this->matchAny(self::$classIdentifiers);
 
             $className .= '\\' . $this->lexer->token['value'];
+
+            $position = $this->lexer->lookahead['position'] ?? NULL;
         }
 
         return $className;
@@ -987,7 +990,7 @@ private function Value()
     {
         $peek = $this->lexer->glimpse();
 
-        if (DocLexer::T_EQUALS === $peek['type']) {
+        if (!empty($peek) && DocLexer::T_EQUALS === $peek['type']) {
             return $this->FieldAssignment();
         }
 
diff --git a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php
index 703ea49a9c..f8a23f2c4e 100644
--- a/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php
+++ b/core/lib/Drupal/Core/Asset/CssCollectionRenderer.php
@@ -49,6 +49,9 @@ public function render(array $css_assets) {
 
     foreach ($css_assets as $css_asset) {
       $element = $link_element_defaults;
+      if (empty($css_asset)) {
+        throw new \Exception('Invalid CSS asset type.');
+      }
       $element['#attributes']['media'] = $css_asset['media'];
       $element['#browsers'] = $css_asset['browsers'];
 
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 03b458f5e5..8139e0e47a 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -117,7 +117,7 @@ public function buildByExtension($extension) {
           $library['version'] = \Drupal::VERSION;
         }
         // Remove 'v' prefix from external library versions.
-        elseif ($library['version'][0] === 'v') {
+        elseif (((string) $library['version'])[0] === 'v') {
           $library['version'] = substr($library['version'], 1);
         }
       }
diff --git a/core/lib/Drupal/Core/Controller/ArgumentResolver/RawParameterValueResolver.php b/core/lib/Drupal/Core/Controller/ArgumentResolver/RawParameterValueResolver.php
index 7e2a35a470..23fb61125c 100644
--- a/core/lib/Drupal/Core/Controller/ArgumentResolver/RawParameterValueResolver.php
+++ b/core/lib/Drupal/Core/Controller/ArgumentResolver/RawParameterValueResolver.php
@@ -15,7 +15,7 @@
    * {@inheritdoc}
    */
   public function supports(Request $request, ArgumentMetadata $argument) {
-    return !$argument->isVariadic() && $request->attributes->has('_raw_variables') && array_key_exists($argument->getName(), $request->attributes->get('_raw_variables'));
+    return !$argument->isVariadic() && $request->attributes->has('_raw_variables') && array_key_exists($argument->getName(), (array) $request->attributes->get('_raw_variables'));
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
index 565fa4e6f7..40817d28b5 100644
--- a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
@@ -168,7 +168,7 @@ public function getPreconfiguredOptions($field_type) {
    */
   public function getPluginClass($type) {
     $plugin_definition = $this->getDefinition($type, FALSE);
-    return $plugin_definition['class'];
+    return $plugin_definition['class'] ?? NULL;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
index c3b67ba0b7..689b7128bc 100644
--- a/core/lib/Drupal/Core/Field/WidgetBase.php
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -456,8 +456,8 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
           }
           // Otherwise, pass errors by delta to the corresponding sub-element.
           else {
-            $original_delta = $field_state['original_deltas'][$delta];
-            $delta_element = $element[$original_delta];
+            $original_delta = $field_state['original_deltas'][$delta] ?? NULL;
+            $delta_element = $element[$original_delta] ?? NULL;
           }
           foreach ($delta_violations as $violation) {
             // @todo: Pass $violation->arrayPropertyPath as property path.
diff --git a/core/lib/Drupal/Core/Render/Element.php b/core/lib/Drupal/Core/Render/Element.php
index 682f236163..02c3b038dd 100644
--- a/core/lib/Drupal/Core/Render/Element.php
+++ b/core/lib/Drupal/Core/Render/Element.php
@@ -78,7 +78,7 @@ public static function children(array &$elements, $sort = FALSE) {
     $i = 0;
     $sortable = FALSE;
     foreach ($elements as $key => $value) {
-      if ($key === '' || $key[0] !== '#') {
+      if ($key === '' || (is_string($key) && $key[0] !== '#')) {
         if (is_array($value)) {
           if (isset($value['#weight'])) {
             $weight = $value['#weight'];
diff --git a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
index 90513008f3..50dcf41482 100644
--- a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
+++ b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
@@ -126,7 +126,7 @@ protected function validateNode(TypedDataInterface $data, $constraints = NULL, $
 
     $metadata = $this->metadataFactory->getMetadataFor($data);
     $cache_key = spl_object_hash($data);
-    $property_path = $is_root_call ? '' : PropertyPath::append($previous_path, $data->getName());
+    $property_path = $is_root_call ? '' : PropertyPath::append((string) $previous_path, (string) $data->getName());
 
     // Prefer a specific instance of the typed data manager stored by the data
     // if it is available. This is necessary for specialized typed data objects,
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
index a695760dfc..b9f38183be 100644
--- a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -21,7 +21,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
     $widget_type = $widget_settings['type'];
 
     $field_data = unserialize($field_definition['data']);
-    $field_settings = $field_data['settings'];
+    $field_settings = $field_data['settings'] ?? NULL;
 
     // Get taxonomy term reference handler settings from allowed values.
     if ($row->getSourceProperty('type') == 'taxonomy_term_reference') {
diff --git a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
index 48dbb81b47..55d641a823 100644
--- a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
+++ b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php
@@ -82,7 +82,7 @@ public function normalize($field_item, $format = NULL, array $context = []) {
 
     // Normalize the target entity.
     $embedded = $this->serializer->normalize($target_entity, $format, $context);
-    $link = $embedded['_links']['self'];
+    $link = $embedded['_links']['self'] ?? NULL;
     // If the field is translatable, add the langcode to the link relation
     // object. This does not indicate the language of the target entity.
     if ($langcode) {
diff --git a/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php b/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
index d0937aed51..5aff4094ed 100644
--- a/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
+++ b/core/modules/inline_form_errors/tests/src/Unit/FormErrorHandlerTest.php
@@ -138,7 +138,7 @@ public function testErrorMessagesInline() {
         foreach ($render_array[1]['#items'] as $item) {
           $links[] = htmlspecialchars($item['#title']);
         }
-        return $render_array[0]['#markup'] . '<ul-comma-list-mock><li-mock>' . implode($links, '</li-mock><li-mock>') . '</li-mock></ul-comma-list-mock>';
+        return $render_array[0]['#markup'] . '<ul-comma-list-mock><li-mock>' . implode('</li-mock><li-mock>', $links) . '</li-mock></ul-comma-list-mock>';
       }));
 
     $form_state = new FormState();
diff --git a/core/modules/language/src/LanguageServiceProvider.php b/core/modules/language/src/LanguageServiceProvider.php
index a7e934aab6..46cd006cd6 100644
--- a/core/modules/language/src/LanguageServiceProvider.php
+++ b/core/modules/language/src/LanguageServiceProvider.php
@@ -87,7 +87,8 @@ protected function isMultilingual() {
   protected function getDefaultLanguageValues() {
     $config_storage = BootstrapConfigStorageFactory::get();
     $system = $config_storage->read('system.site');
-    $default_language = $config_storage->read(static::CONFIG_PREFIX . $system['default_langcode']);
+    $system_default_langcode = $system['default_langcode'] ?? '';
+    $default_language = $config_storage->read(static::CONFIG_PREFIX . $system_default_langcode);
     if (is_array($default_language)) {
       return $default_language;
     }
diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index 373c3f03ad..f07c173336 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -188,7 +188,7 @@ public function setValue($values, $notify = TRUE) {
     }
     // Unserialize the values, this is deprecated as the storage takes care of
     // this, options must not be passed as a string anymore.
-    if (is_string($values['options'])) {
+    if (isset($values['options']) && is_string($values['options'])) {
       @trigger_error('Support for passing options as a serialized string is deprecated in 8.7.0 and will be removed before Drupal 9.0.0. Pass them as an array instead. See https://www.drupal.org/node/2961643.', E_USER_DEPRECATED);
       $values['options'] = unserialize($values['options'], ['allowed_classes' => FALSE]);
     }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 9a8d8c999c..fff6ea3292 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -649,7 +649,7 @@ function template_preprocess_node(&$variables) {
   }
 
   if (!$skip_custom_preprocessing || !$node->getFieldDefinition('title')->isDisplayConfigurable('view')) {
-    $variables['label'] = $variables['elements']['title'];
+    $variables['label'] = $variables['elements']['title'] ?? NULL;
     unset($variables['elements']['title']);
   }
 
diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php
index e33f24a59a..c28f72cd79 100644
--- a/core/modules/rdf/src/Entity/RdfMapping.php
+++ b/core/modules/rdf/src/Entity/RdfMapping.php
@@ -148,7 +148,9 @@ public function calculateDependencies() {
     $entity_type = \Drupal::entityTypeManager()->getDefinition($this->targetEntityType);
     $this->addDependency('module', $entity_type->getProvider());
     $bundle_config_dependency = $entity_type->getBundleConfigDependency($this->bundle);
-    $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']);
+    if (!empty($bundle_config_dependency)) {
+      $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']);
+    }
 
     return $this;
   }
diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php
index 8180b70cb8..bf0c34b694 100644
--- a/core/modules/rest/src/RequestHandler.php
+++ b/core/modules/rest/src/RequestHandler.php
@@ -330,7 +330,8 @@ protected function getLegacyParameters(RouteMatchInterface $route_match, $unseri
     $parameters = [];
     // Filter out all internal parameters starting with "_".
     foreach ($route_parameters as $key => $parameter) {
-      if ($key{0} !== '_') {
+      $key = (string) $key;
+      if ($key[0] !== '_') {
         $parameters[] = $parameter;
       }
     }
diff --git a/core/modules/search/src/SearchQuery.php b/core/modules/search/src/SearchQuery.php
index 9e47cf1a42..6e342ca202 100644
--- a/core/modules/search/src/SearchQuery.php
+++ b/core/modules/search/src/SearchQuery.php
@@ -246,7 +246,7 @@ protected function parseSearchExpression() {
 
       // Strip off phrase quotes.
       $phrase = FALSE;
-      if ($match[2]{0} == '"') {
+      if ($match[2][0] == '"') {
         $match[2] = substr($match[2], 1, -1);
         $phrase = TRUE;
         $this->simple = FALSE;
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index e29d8e932b..4cbfd9dadb 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -101,7 +101,7 @@ public function getPath() {
   protected function isDefaultTabPath() {
     $menu = $this->getOption('menu');
     $tab_options = $this->getOption('tab_options');
-    return $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none';
+    return !empty($menu) && $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none';
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/filter/StringFilter.php b/core/modules/views/src/Plugin/views/filter/StringFilter.php
index 47adcdbcdd..229eb90733 100644
--- a/core/modules/views/src/Plugin/views/filter/StringFilter.php
+++ b/core/modules/views/src/Plugin/views/filter/StringFilter.php
@@ -341,7 +341,7 @@ protected function opContainsWord($field) {
     foreach ($matches as $match) {
       $phrase = FALSE;
       // Strip off phrase quotes
-      if ($match[2]{0} == '"') {
+      if ($match[2][0] == '"') {
         $match[2] = substr($match[2], 1, -1);
         $phrase = TRUE;
       }
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index dfda4a9fc0..290e494aea 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -605,7 +605,7 @@ protected function tearDown() {
 
     // Remove all prefixed tables.
     $original_connection_info = Database::getConnectionInfo('simpletest_original_default');
-    $original_prefix = $original_connection_info['default']['prefix']['default'];
+    $original_prefix = $original_connection_info['default']['prefix']['default'] ?? NULL;
     $test_connection_info = Database::getConnectionInfo('default');
     $test_prefix = $test_connection_info['default']['prefix']['default'];
     if ($original_prefix != $test_prefix) {
