예제 #1
0
 /**
  * Checks that harmful protocols are stripped.
  */
 function testBadProtocolStripping()
 {
     // Ensure that check_url() strips out harmful protocols, and encodes for
     // HTML.
     // Ensure \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() can
     // be used to return a plain-text string stripped of harmful protocols.
     $url = 'javascript:http://www.example.com/?x=1&y=2';
     $expected_plain = 'http://www.example.com/?x=1&y=2';
     $expected_html = 'http://www.example.com/?x=1&y=2';
     $this->assertIdentical(check_url($url), $expected_html, 'check_url() filters a URL and encodes it for HTML.');
     $this->assertIdentical(UrlHelper::filterBadProtocol($url), $expected_html, '\\Drupal\\Component\\Utility\\UrlHelper::filterBadProtocol() filters a URL and encodes it for HTML.');
     $this->assertIdentical(UrlHelper::stripDangerousProtocols($url), $expected_plain, '\\Drupal\\Component\\Utility\\UrlHelper::stripDangerousProtocols() filters a URL and returns plain text.');
 }
 /**
  * Creates a comment, then tests the tokens generated from it.
  */
 function testCommentTokenReplacement()
 {
     $token_service = \Drupal::token();
     $language_interface = \Drupal::languageManager()->getCurrentLanguage();
     $url_options = array('absolute' => TRUE, 'language' => $language_interface);
     // Change the title of the admin user.
     $this->adminUser->name->value = 'This is a title with some special & > " stuff.';
     $this->adminUser->save();
     $this->drupalLogin($this->adminUser);
     // Set comment variables.
     $this->setCommentSubject(TRUE);
     // Create a node and a comment.
     $node = $this->drupalCreateNode(['type' => 'article', 'title' => '<script>alert("123")</script>']);
     $parent_comment = $this->postComment($node, $this->randomMachineName(), $this->randomMachineName(), TRUE);
     // Post a reply to the comment.
     $this->drupalGet('comment/reply/node/' . $node->id() . '/comment/' . $parent_comment->id());
     $child_comment = $this->postComment(NULL, $this->randomMachineName(), $this->randomMachineName());
     $comment = Comment::load($child_comment->id());
     $comment->setHomepage('http://example.org/');
     // Add HTML to ensure that sanitation of some fields tested directly.
     $comment->setSubject('<blink>Blinking Comment</blink>');
     // Generate and test tokens.
     $tests = array();
     $tests['[comment:cid]'] = $comment->id();
     $tests['[comment:hostname]'] = $comment->getHostname();
     $tests['[comment:author]'] = Html::escape($comment->getAuthorName());
     $tests['[comment:mail]'] = $this->adminUser->getEmail();
     $tests['[comment:homepage]'] = UrlHelper::filterBadProtocol($comment->getHomepage());
     $tests['[comment:title]'] = Html::escape($comment->getSubject());
     $tests['[comment:body]'] = $comment->comment_body->processed;
     $tests['[comment:langcode]'] = $comment->language()->getId();
     $tests['[comment:url]'] = $comment->url('canonical', $url_options + array('fragment' => 'comment-' . $comment->id()));
     $tests['[comment:edit-url]'] = $comment->url('edit-form', $url_options);
     $tests['[comment:created]'] = \Drupal::service('date.formatter')->format($comment->getCreatedTime(), 'medium', array('langcode' => $language_interface->getId()));
     $tests['[comment:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getCreatedTime(), array('langcode' => $language_interface->getId()));
     $tests['[comment:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getChangedTimeAcrossTranslations(), array('langcode' => $language_interface->getId()));
     $tests['[comment:parent:cid]'] = $comment->hasParentComment() ? $comment->getParentComment()->id() : NULL;
     $tests['[comment:parent:title]'] = $parent_comment->getSubject();
     $tests['[comment:entity]'] = Html::escape($node->getTitle());
     // Test node specific tokens.
     $tests['[comment:entity:nid]'] = $comment->getCommentedEntityId();
     $tests['[comment:entity:title]'] = Html::escape($node->getTitle());
     $tests['[comment:author:uid]'] = $comment->getOwnerId();
     $tests['[comment:author:name]'] = Html::escape($this->adminUser->getDisplayName());
     $base_bubbleable_metadata = BubbleableMetadata::createFromObject($comment);
     $metadata_tests = [];
     $metadata_tests['[comment:cid]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:hostname]'] = $base_bubbleable_metadata;
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $bubbleable_metadata->addCacheableDependency($this->adminUser);
     $metadata_tests['[comment:author]'] = $bubbleable_metadata;
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $bubbleable_metadata->addCacheableDependency($this->adminUser);
     $metadata_tests['[comment:mail]'] = $bubbleable_metadata;
     $metadata_tests['[comment:homepage]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:title]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:body]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:langcode]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:url]'] = $base_bubbleable_metadata;
     $metadata_tests['[comment:edit-url]'] = $base_bubbleable_metadata;
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:created]'] = $bubbleable_metadata->addCacheTags(['rendered']);
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:created:since]'] = $bubbleable_metadata->setCacheMaxAge(0);
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:changed:since]'] = $bubbleable_metadata->setCacheMaxAge(0);
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:parent:cid]'] = $bubbleable_metadata->addCacheTags(['comment:1']);
     $metadata_tests['[comment:parent:title]'] = $bubbleable_metadata;
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:entity]'] = $bubbleable_metadata->addCacheTags(['node:2']);
     // Test node specific tokens.
     $metadata_tests['[comment:entity:nid]'] = $bubbleable_metadata;
     $metadata_tests['[comment:entity:title]'] = $bubbleable_metadata;
     $bubbleable_metadata = clone $base_bubbleable_metadata;
     $metadata_tests['[comment:author:uid]'] = $bubbleable_metadata->addCacheTags(['user:2']);
     $metadata_tests['[comment:author:name]'] = $bubbleable_metadata;
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
     foreach ($tests as $input => $expected) {
         $bubbleable_metadata = new BubbleableMetadata();
         $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->getId()), $bubbleable_metadata);
         $this->assertEqual($output, $expected, new FormattableMarkup('Comment token %token replaced.', ['%token' => $input]));
         $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
     }
     // Test anonymous comment author.
     $author_name = 'This is a random & " > string';
     $comment->setOwnerId(0)->setAuthorName($author_name);
     $input = '[comment:author]';
     $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->getId()));
     $this->assertEqual($output, Html::escape($author_name), format_string('Comment author token %token replaced.', array('%token' => $input)));
     // Load node so comment_count gets computed.
     $node = Node::load($node->id());
     // Generate comment tokens for the node (it has 2 comments, both new).
     $tests = array();
     $tests['[entity:comment-count]'] = 2;
     $tests['[entity:comment-count-new]'] = 2;
     foreach ($tests as $input => $expected) {
         $output = $token_service->replace($input, array('entity' => $node, 'node' => $node), array('langcode' => $language_interface->getId()));
         $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input)));
     }
 }
예제 #3
0
 /**
  * Tests bad protocol filtering and escaping.
  *
  * @dataProvider providerTestFilterBadProtocol
  * @covers ::setAllowedProtocols
  * @covers ::filterBadProtocol
  *
  * @param string $uri
  *    Protocol URI.
  * @param string $expected
  *    Expected escaped value.
  * @param array $protocols
  *    Protocols to allow.
  */
 public function testFilterBadProtocol($uri, $expected, $protocols)
 {
     UrlHelper::setAllowedProtocols($protocols);
     $this->assertEquals($expected, UrlHelper::filterBadProtocol($uri));
     // Multiple calls to UrlHelper::filterBadProtocol() do not cause double
     // escaping.
     $this->assertEquals($expected, UrlHelper::filterBadProtocol(UrlHelper::filterBadProtocol($uri)));
 }
예제 #4
0
 /**
  * Tests bad protocol filtering and escaping.
  *
  * @dataProvider providerTestFilterBadProtocol
  * @covers ::setAllowedProtocols
  * @covers ::filterBadProtocol
  *
  * @param string $uri
  *    Protocol URI.
  * @param string $expected
  *    Expected escaped value.
  * @param array $protocols
  *    Protocols to allow.
  */
 public function testFilterBadProtocol($uri, $expected, $protocols)
 {
     UrlHelper::setAllowedProtocols($protocols);
     $filtered = UrlHelper::filterBadProtocol($uri);
     $this->assertEquals($expected, $filtered);
 }
 /**
  * {@inheritdoc}
  */
 public function validateForm(array &$form, FormStateInterface $form_state)
 {
     parent::validateForm($form, $form_state);
     // Custom variables validation.
     foreach ($form_state->getValue(['piwik_custom_var', 'slots']) as $custom_var) {
         $form_state->setValue(['piwik_custom_var', 'slots', $custom_var['slot'], 'name'], trim($custom_var['name']));
         $form_state->setValue(['piwik_custom_var', 'slots', $custom_var['slot'], 'value'], trim($custom_var['value']));
         // Validate empty names/values.
         if (empty($custom_var['name']) && !empty($custom_var['value'])) {
             $form_state->setErrorByName("piwik_custom_var][slots][" . $custom_var['slot'] . "][name", t('The custom variable @slot-number requires a <em>Name</em> if a <em>Value</em> has been provided.', ['@slot-number' => $custom_var['slot']]));
         } elseif (!empty($custom_var['name']) && empty($custom_var['value'])) {
             $form_state->setErrorByName("piwik_custom_var][slots][" . $custom_var['slot'] . "][value", t('The custom variable @slot-number requires a <em>Value</em> if a <em>Name</em> has been provided.', ['@slot-number' => $custom_var['slot']]));
         }
     }
     $form_state->setValue('piwik_custom_var', $form_state->getValue(['piwik_custom_var', 'slots']));
     // Trim some text area values.
     $form_state->setValue('piwik_site_id', trim($form_state->getValue('piwik_site_id')));
     $form_state->setValue('piwik_visibility_request_path_pages', trim($form_state->getValue('piwik_visibility_request_path_pages')));
     $form_state->setValue('piwik_codesnippet_before', trim($form_state->getValue('piwik_codesnippet_before')));
     $form_state->setValue('piwik_codesnippet_after', trim($form_state->getValue('piwik_codesnippet_after')));
     $form_state->setValue('piwik_visibility_user_role_roles', array_filter($form_state->getValue('piwik_visibility_user_role_roles')));
     $form_state->setValue('piwik_trackmessages', array_filter($form_state->getValue('piwik_trackmessages')));
     if (!preg_match('/^\\d{1,}$/', $form_state->getValue('piwik_site_id'))) {
         $form_state->setErrorByName('piwik_site_id', t('A valid Piwik site ID is an integer only.'));
     }
     $url = $form_state->getValue('piwik_url_http') . 'piwik.php';
     try {
         $result = \Drupal::httpClient()->get($url);
         if ($result->getStatusCode() != 200 && $form_state->getValue('piwik_url_skiperror') == FALSE) {
             $form_state->setErrorByName('piwik_url_http', t('The validation of "@url" failed with error "@error" (HTTP code @code).', ['@url' => UrlHelper::filterBadProtocol($url), '@error' => $result->getReasonPhrase(), '@code' => $result->getStatusCode()]));
         }
     } catch (RequestException $exception) {
         $form_state->setErrorByName('piwik_url_http', t('The validation of "@url" failed with an exception "@error" (HTTP code @code).', ['@url' => UrlHelper::filterBadProtocol($url), '@error' => $exception->getMessage(), '@code' => $exception->getCode()]));
     }
     $piwik_url_https = $form_state->getValue('piwik_url_https');
     if (!empty($piwik_url_https)) {
         $url = $piwik_url_https . 'piwik.php';
         try {
             $result = \Drupal::httpClient()->get($url);
             if ($result->getStatusCode() != 200 && $form_state->getValue('piwik_url_skiperror') == FALSE) {
                 $form_state->setErrorByName('piwik_url_https', t('The validation of "@url" failed with error "@error" (HTTP code @code).', ['@url' => UrlHelper::filterBadProtocol($url), '@error' => $result->getReasonPhrase(), '@code' => $result->getStatusCode()]));
             }
         } catch (RequestException $exception) {
             $form_state->setErrorByName('piwik_url_https', t('The validation of "@url" failed with an exception "@error" (HTTP code @code).', ['@url' => UrlHelper::filterBadProtocol($url), '@error' => $exception->getMessage(), '@code' => $exception->getCode()]));
         }
     }
     // Verify that every path is prefixed with a slash, but don't check PHP
     // code snippets.
     if ($form_state->getValue('piwik_visibility_request_path_mode') != 2) {
         $pages = preg_split('/(\\r\\n?|\\n)/', $form_state->getValue('piwik_visibility_request_path_pages'));
         foreach ($pages as $page) {
             if (strpos($page, '/') !== 0 && $page !== '<front>') {
                 $form_state->setErrorByName('piwik_visibility_request_path_pages', t('Path "@page" not prefixed with slash.', ['@page' => $page]));
                 // Drupal forms show one error only.
                 break;
             }
         }
     }
     // Clear obsolete local cache if cache has been disabled.
     if ($form_state->isValueEmpty('piwik_cache') && $form['advanced']['piwik_cache']['#default_value']) {
         piwik_clear_js_cache();
     }
     // This is for the Newbie's who cannot read a text area description.
     if (preg_match('/(.*)<\\/?script(.*)>(.*)/i', $form_state->getValue('piwik_codesnippet_before'))) {
         $form_state->setErrorByName('piwik_codesnippet_before', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
     }
     if (preg_match('/(.*)<\\/?script(.*)>(.*)/i', $form_state->getValue('piwik_codesnippet_after'))) {
         $form_state->setErrorByName('piwik_codesnippet_after', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
     }
 }