Skip to content

Commit

Permalink
#11 Update Link to 7.x-1.11 incl. SA-CONTRIB-2022-034
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Hunt committed May 5, 2022
1 parent 781b787 commit b65b6cf
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 39 deletions.
21 changes: 21 additions & 0 deletions docroot/sites/all/modules/contrib/link/CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
Link 7.x-1.11, 2022-05-04
-------------------------
By brad.bulger, DamienMcKenna, greggles: Improved output w/o token handling.


Link 7.x-1.10, 2022-05-04
-------------------------
#3210438 by DamienMcKenna: Test coverage - URLs with multiple query parameters.
#3230624 by DamienMcKenna: Change test permission handling.
#2209995 by jenlampton, RenatoG: formatter "URL, as link" throws error when
displayed via Display Suite.
#3230730 by DamienMcKenna, clemens.tolboom, jvogt, RenatoG: Wrong permission
used for the settings page.
#3254549 by DamienMcKenna, RenatoG: Tidy variable assertion logic in
_link_sanitize().
#3269635 by marciaibanez, DamienMcKenna, poker10, RenatoG: PHP 8.1: strlen()
parameter change.
#3268969 by roderik, RenatoG: Non-standard URL schemes with more than just
hostname fail validation.


Link 7.x-1.9, 2021-04-19
------------------------
#3209434 by DamienMcKenna, tiziano.sartori: Syntax error, unexpected '(' after
Expand Down
6 changes: 3 additions & 3 deletions docroot/sites/all/modules/contrib/link/link.info
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ test_dependencies[] = token:token
; Standalone unit tests.
files[] = tests/LinkUnitTestCase.test

; Information added by Drupal.org packaging script on 2021-04-19
version = "7.x-1.9"
; Information added by Drupal.org packaging script on 2022-05-04
version = "7.x-1.11"
core = "7.x"
project = "link"
datestamp = "1618831239"
datestamp = "1651671649"
7 changes: 7 additions & 0 deletions docroot/sites/all/modules/contrib/link/link.install
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,10 @@ function link_update_7001() {
}
}
}

/**
* Rebuild the menu cache to make the settings page use the correct permission.
*/
function link_update_7100() {
variable_set('menu_rebuild_needed', TRUE);
}
64 changes: 44 additions & 20 deletions docroot/sites/all/modules/contrib/link/link.module
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ function _link_validate(&$item, $delta, $field, $entity, $instance, $langcode, &
}
}
// Require a link if we have a title.
if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : NULL) > 0 && strlen(trim($item['url'])) == 0) {
if ($instance['settings']['url'] !== 'optional' && strlen(isset($item['title']) ? $item['title'] : '') > 0 && strlen(trim($item['url'])) == 0) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'link_required',
'message' => t('You cannot enter a title without a link url.'),
Expand Down Expand Up @@ -762,7 +762,7 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) {
}

// Replace title tokens.
if ($title && $instance['settings']['enable_tokens']) {
if ($title !== '' && $instance['settings']['enable_tokens']) {
$text_tokens = token_scan($title);
if (!empty($text_tokens)) {
// Load the entity if necessary for entities in views.
Expand All @@ -776,24 +776,32 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) {
$title = token_replace($title, array($entity_token_type => $entity_loaded));
}
}
if ($title && ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens'])) {
$title = filter_xss($title, array(
'b',
'br',
'code',
'em',
'i',
'img',
'span',
'strong',
'sub',
'sup',
'tt',
'u',
));
$item['html'] = TRUE;
if ($title !== '') {
// if title may potentially use tokens, assume that they may contain HTML
if ($instance['settings']['title'] == 'value' || $instance['settings']['enable_tokens']) {
$item['html'] = TRUE;
}
if (!empty($item['html'])) {
$title = filter_xss($title, array(
'b',
'br',
'code',
'em',
'i',
'img',
'span',
'strong',
'sub',
'sup',
'tt',
'u',
));
}
$item['title'] = $title;
}
else {
$item['title'] = $item['display_url'];
}
$item['title'] = empty($title) && $title !== '0' ? $item['display_url'] : $title;

if (!isset($item['attributes'])) {
$item['attributes'] = array();
Expand Down Expand Up @@ -955,7 +963,7 @@ function link_menu() {
'description' => 'Settings for the link module.',
'page callback' => 'drupal_get_form',
'page arguments' => array('link_admin_settings'),
'access arguments' => array('access administration pages'),
'access arguments' => array('administer site configuration'),
'file' => 'link.admin.inc',
);
return $items;
Expand Down Expand Up @@ -1449,6 +1457,12 @@ function theme_link_formatter_link_url($vars) {
}
unset($link_options['title']);
unset($link_options['url']);

if (!isset($vars['element']['display_url'])) {
// Display suite sometimes does not set 'display_url'.
$vars['element']['display_url'] = $vars['element']['url'];
}

return l($vars['element']['display_url'], $vars['element']['url'], $link_options);
}

Expand Down Expand Up @@ -1624,6 +1638,16 @@ function link_validate_url($text, $langcode = NULL) {
$text = link_cleanup_url($text);
$type = link_url_type($text);

if ($type == LINK_EXTERNAL) {
$scheme = parse_url($text, PHP_URL_SCHEME);
if ($scheme && !in_array(strtolower($scheme), array('http', 'https', 'ftp', 'feed'))) {
// valid_url() cannot validate this scheme (which can be anything, if
// filter_allowed_protocols was changed). The exact syntax is likely
// unknown, so skip the next block and accept anything.
$type = $scheme;
}
}

if ($type && ($type == LINK_INTERNAL || $type == LINK_EXTERNAL)) {
$flag = valid_url($text, $type == LINK_EXTERNAL);
if (!$flag) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ class LinkBaseTestClass extends DrupalWebTestCase {
* @var array
*/
protected $permissions = array(
'access content',
'administer content types',
'administer fields',
'administer nodes',
'administer filters',
'access comments',
'post comments',
'access administration pages',
'create page content',
'access content' => 'access content',
'administer content types' => 'administer content types',
'administer fields' => 'administer fields',
'administer nodes' => 'administer nodes',
'administer filters' => 'administer filters',
'access comments' => 'access comments',
'post comments' => 'post comments',
'access administration pages' => 'access administration pages',
'create page content' => 'create page content',
);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ class LinkDefaultProtocolTest extends LinkBaseTestClass {
);
}

/**
* {@inheritdoc}
*/
public function setUp(array $modules = array()) {
// This extra permission is required for the settings page.
$this->permissions['administer site configuration'] = 'administer site configuration';
parent::setUp($modules);
}

/**
* A link without a default protocol uses the default (HTTP).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ class LinkFieldAttributesTest extends LinkBaseTestClass {

// Now that we have a new content type, create a user that has privileges
// on the content type.
$permissions = array_merge($this->permissions, array($permission));
$permissions = $this->permissions;
$permissions[$permission] = $permission;
$this->web_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->web_user);

Expand Down Expand Up @@ -196,7 +197,8 @@ class LinkFieldAttributesTest extends LinkBaseTestClass {

// Now that we have a new content type, create a user that has privileges
// on the content type.
$permissions = array_merge($this->permissions, array($permission));
$permissions = $this->permissions;
$permissions[$permission] = $permission;
$this->web_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->web_user);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ class LinkFieldCrudTest extends LinkBaseTestClass {
array(
'href' => 'http://example.com/' . $this->randomName() . '?property=value',
),
array(
'href' => 'http://example.com/' . $this->randomName() . '?property=value&mango=thebest',
),
array(
'href' => 'http://example.com/' . $this->randomName() . '#position',
),
Expand Down Expand Up @@ -565,7 +568,9 @@ class LinkFieldCrudTest extends LinkBaseTestClass {
// Loop over the nodes, confirm each URL is rendered correctly.
foreach ($link_title_tests as $input) {
$this->drupalGet($input['url']);
$this->assertRaw(l($input['href'], $input['href']), "Test that the link title has been set to " . $input['href']);
// This is precarious. It isn't possible to compare the link as-is because
// it is already filtered via check_plain().
$this->assertRaw(l($input['href'], $input['href'], array('html' => TRUE)), "Test that the link title has been set to " . $input['href']);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ class LinkPathPrefixesTest extends LinkBaseTestClass {
* {@inheritdoc}
*/
public function setUp(array $modules = array()) {
$this->permissions = array_merge($this->permissions, array(
'administer site configuration',
'administer languages',
));
$this->permissions['administer site configuration'] = 'administer site configuration';
$this->permissions['administer languages'] = 'administer languages';
$modules[] = 'locale';
$modules[] = 'locale_test';
$modules[] = 'translation';
Expand Down
43 changes: 43 additions & 0 deletions docroot/sites/all/modules/contrib/link/tests/LinkSanitizeTest.test
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class LinkSanitizeTest extends LinkBaseTestClass {
$defaults['attributes'] = array();
$defaults['display']['url_cutoff'] = 20;
$defaults['title'] = 'Test title';
$defaults['enable_tokens'] = 0;
$settings += $defaults;
$settings['display'] += $defaults['display'];
$instance['settings'] = $settings;
Expand Down Expand Up @@ -124,6 +125,20 @@ class LinkSanitizeTest extends LinkBaseTestClass {
$this->assertEqual(NULL, $item['fragment']);
}

/**
* Test that unwanted HTML in titles is removed.
*/
public function testHtmlTitle() {
$item['title'] = '<script>alert("hi");</script>';
$item['url'] = 'https://www.drupal.org/';
list($field, $instance, $entity) = $this->generateParams();
// Disable the URL cutoff to confirm the URL.
$instance['settings']['display']['url_cutoff'] = FALSE;
_link_sanitize($item, NULL, $field, $instance, $entity);
$this->verbose('<pre>' . print_r($item, TRUE) . '</pre>');
$this->assertEqual('alert("hi");', $item['title']);
}

/**
* Test that query URLs can be turned into absolute URLs.
*/
Expand All @@ -137,10 +152,38 @@ class LinkSanitizeTest extends LinkBaseTestClass {
$this->verbose('<pre>' . print_r($item, TRUE) . '</pre>');
$this->assertEqual('https://www.drupal.org/?page=42', $item['display_url']);
$this->assertEqual('https://www.drupal.org/', $item['url']);
$this->assertTrue(is_array($item['query']));
$this->assertEqual(array('page' => 42), $item['query']);
$this->assertEqual(NULL, $item['fragment']);
}

/**
* Test that multiple query URLs can be turned into absolute URLs.
*/
public function testBlankTitleWithMultipleQueries() {
$item['title'] = '';
$item['url'] = 'https://www.drupal.org/?page=42&mango=thebest';
list($field, $instance, $entity) = $this->generateParams();
// Disable the URL cutoff to confirm the URL.
$instance['settings']['display']['url_cutoff'] = FALSE;
_link_sanitize($item, NULL, $field, $instance, $entity);
$this->verbose('<pre>' . print_r($item, TRUE) . '</pre>');
$this->assertEqual('https://www.drupal.org/?page=42&mango=thebest', $item['display_url']);
$this->assertEqual('https://www.drupal.org/', $item['url']);
$this->assertTrue(is_array($item['query']));
$this->assertTrue(isset($item['query']['page']));
$this->assertEqual($item['query']['page'], 42);
$this->assertTrue(isset($item['query']['page']));
$this->assertEqual($item['query']['mango'], 'thebest');

// Make sure there aren't any other items in the 'query' array.
unset($item['query']['mango']);
unset($item['query']['page']);
$this->assertEqual(array(), $item['query']);

$this->assertEqual(NULL, $item['fragment']);
}

/**
* Test that query URLs can be turned into absolute URLs.
*/
Expand Down
11 changes: 11 additions & 0 deletions docroot/sites/all/modules/contrib/link/tests/LinkUnitTestCase.test
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ class LinkUnitTestCase extends DrupalUnitTestCase {
'page' => 42,
),
),
'https://www.drupal.org/?page=42&mango=thebest' => array(
'url' => 'https://www.drupal.org/',
'query' => array(
'page' => 42,
'mango' => 'thebest',
),
),
'https://www.drupal.org/#footer' => array(
'url' => 'https://www.drupal.org/',
'fragment' => 'footer',
Expand All @@ -69,6 +76,10 @@ class LinkUnitTestCase extends DrupalUnitTestCase {
$this->assertTrue(isset($actual_parts['query']));
$this->assertTrue(is_array($actual_parts['query']));
$this->assertEqual(count($expected_parts['query']), count($actual_parts['query']));
foreach ($expected_parts['query'] as $key => $val) {
$this->assertTrue(isset($actual_parts['query'][$key]));
$this->assertEqual($val, $actual_parts['query'][$key]);
}
}
// If it was not expected, make sure it wasn't added anyway.
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class LinkValidationApiTest extends LinkBaseTestClass {
foreach ($allowed_protocols as $protocol) {
if ($protocol !== 'news' && $protocol !== 'mailto') {
$links[] = $protocol . '://www.example.com';
$links[] = $protocol . '://www.example.com/resource';
}
}
foreach ($links as $link) {
Expand Down

0 comments on commit b65b6cf

Please sign in to comment.