Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
031a6876
Commit
031a6876
authored
Nov 08, 2009
by
Angie Byron
Browse files
#318636
by effulgentsia, sun, Damien Tournoud, Xano, and jrchamp: Make l() themable.
parent
15d972d1
Changes
3
Hide whitespace changes
Inline
Side-by-side
includes/common.inc
View file @
031a6876
...
...
@@ -2683,6 +2683,7 @@ function drupal_attributes(array $attributes = array()) {
*/
function
l
(
$text
,
$path
,
array
$options
=
array
())
{
global
$language_url
;
static
$use_theme
=
NULL
;
// Merge in defaults.
$options
+=
array
(
...
...
@@ -2702,6 +2703,35 @@ function l($text, $path, array $options = array()) {
$options
[
'attributes'
][
'title'
]
=
strip_tags
(
$options
[
'attributes'
][
'title'
]);
}
// Determine if rendering of the link is to be done with a theme function
// or the inline default. Inline is faster, but if the theme system has been
// loaded and a module or theme implements a preprocess or process function
// or overrides the theme_link() function, then invoke theme(). Preliminary
// benchmarks indicate that invoking theme() can slow down the l() function
// by 20% or more, and that some of the link-heavy Drupal pages spend more
// than 10% of the total page request time in the l() function.
if
(
!
isset
(
$use_theme
)
&&
function_exists
(
'theme'
))
{
// Allow edge cases to prevent theme initialization and force inline link
// rendering.
if
(
variable_get
(
'theme_link'
,
TRUE
))
{
drupal_theme_initialize
();
$registry
=
theme_get_registry
();
// We don't want to duplicate functionality that's in theme(), so any
// hint of a module or theme doing anything at all special with the 'link'
// theme hook should simply result in theme() being called. This includes
// the overriding of theme_link() with an alternate function or template,
// the presence of preprocess or process functions, or the presence of
// include files.
$use_theme
=
!
isset
(
$registry
[
'link'
][
'function'
])
||
(
$registry
[
'link'
][
'function'
]
!=
'theme_link'
);
$use_theme
=
$use_theme
||
!
empty
(
$registry
[
'link'
][
'preprocess functions'
])
||
!
empty
(
$registry
[
'link'
][
'process functions'
])
||
!
empty
(
$registry
[
'link'
][
'includes'
]);
}
else
{
$use_theme
=
FALSE
;
}
}
if
(
$use_theme
)
{
return
theme
(
'link'
,
array
(
'text'
=>
$text
,
'path'
=>
$path
,
'options'
=>
$options
));
}
return
'<a href="'
.
check_plain
(
url
(
$path
,
$options
))
.
'"'
.
drupal_attributes
(
$options
[
'attributes'
])
.
'>'
.
(
$options
[
'html'
]
?
$text
:
check_plain
(
$text
))
.
'</a>'
;
}
...
...
@@ -5348,6 +5378,9 @@ function drupal_common_theme() {
'status_messages'
=>
array
(
'variables'
=>
array
(
'display'
=>
NULL
),
),
'link'
=>
array
(
'variables'
=>
array
(
'text'
=>
NULL
,
'path'
=>
NULL
,
'options'
=>
array
()),
),
'links'
=>
array
(
'variables'
=>
array
(
'links'
=>
NULL
,
'attributes'
=>
array
(
'class'
=>
array
(
'links'
)),
'heading'
=>
array
()),
),
...
...
includes/theme.inc
View file @
031a6876
...
...
@@ -1369,6 +1369,31 @@ function theme_status_messages($variables) {
return
$output
;
}
/**
* Return a themed link.
*
* All Drupal code that outputs a link should call the l() function. That
* function performs some initial preprocessing, and then, if necessary,
* calls theme('link') for rendering the anchor tag.
*
* To optimize performance for sites that don't need custom theming of links,
* the l() function includes an inline copy of this function, and uses that copy
* if none of the enabled modules or the active theme implement any preprocess
* or process functions or override this theme implementation.
*
* @param $variables
* An associative array containing the keys 'text', 'path', and 'options'.
* See the l() function for information about these variables.
*
* @return
* An HTML string containing a link to the given path.
*
* @see l()
*/
function
theme_link
(
$variables
)
{
return
'<a href="'
.
check_plain
(
url
(
$variables
[
'path'
],
$variables
[
'options'
]))
.
'"'
.
drupal_attributes
(
$variables
[
'options'
][
'attributes'
])
.
'>'
.
(
$variables
[
'options'
][
'html'
]
?
$variables
[
'text'
]
:
check_plain
(
$variables
[
'text'
]))
.
'</a>'
;
}
/**
* Return a themed set of links.
*
...
...
modules/simpletest/tests/common.test
View file @
031a6876
...
...
@@ -70,9 +70,23 @@ class CommonURLUnitTest extends DrupalUnitTestCase {
* Confirm that invalid text given as $path is filtered.
*/
function
testLXSS
()
{
global
$conf
;
$text
=
$this
->
randomName
();
$path
=
"<SCRIPT>alert('XSS')</SCRIPT>"
;
// Regardless of whether there is a theme override of theme_link() or not,
// unless the 'theme_link' configuration variable is FALSE, l() will
// attempt to initialize the theme system in order to determine if
// the link needs to be themed. However, drupal_theme_initialize() requires
// a database query, which doesn't work in the context of unit tests,
// because simpletest sets up a table prefix, but doesn't generate the
// corresponding prefixed tables. We need to either circumvent theme system
// initialization, or make CommonURLUnitTest inherit from DrupalWebTestCase.
// Since our goal in this unit test is specifically to test the default
// implementation, we choose the former.
$theme_link_saved
=
isset
(
$conf
[
'theme_link'
])
?
$conf
[
'theme_link'
]
:
NULL
;
$conf
[
'theme_link'
]
=
FALSE
;
$link
=
l
(
$text
,
$path
);
$conf
[
'theme_link'
]
=
$theme_link_saved
;
$sanitized_path
=
check_url
(
url
(
$path
));
$this
->
assertTrue
(
strpos
(
$link
,
$sanitized_path
)
!==
FALSE
,
t
(
'XSS attack @path was filtered'
,
array
(
'@path'
=>
$path
)));
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment