summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2014-09-22 11:55:48 (GMT)
committerAlex Pott2014-09-22 11:55:48 (GMT)
commit5e938c16d17779aaef1d3213ab7360e09c8e9a87 (patch)
treee6b412402c65df49811e3337d01c2200a281b649
parentc554974c9c1b5f4bfc7f56c511c9110b97f2a84e (diff)
Issue #1342504 by jbrown, Jelle_S, Dave Reid: Support data URIs.
-rw-r--r--core/includes/file.inc38
-rw-r--r--core/modules/file/src/Tests/DownloadTest.php1
-rw-r--r--core/modules/system/src/Tests/File/StreamWrapperTest.php5
-rw-r--r--core/modules/system/src/Tests/Theme/FunctionsTest.php13
4 files changed, 41 insertions, 16 deletions
diff --git a/core/includes/file.inc b/core/includes/file.inc
index f576781..78fdbfa 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -276,18 +276,22 @@ function file_stream_wrapper_get_class($scheme) {
/**
* Returns the scheme of a URI (e.g. a stream).
*
- * @param $uri
- * A stream, referenced as "scheme://target".
+ * @param string $uri
+ * A stream, referenced as "scheme://target" or "data:target".
*
- * @return
+ * @return string
* A string containing the name of the scheme, or FALSE if none. For example,
* the URI "public://example.txt" would return "public".
*
* @see file_uri_target()
*/
function file_uri_scheme($uri) {
- $position = strpos($uri, '://');
- return $position ? substr($uri, 0, $position) : FALSE;
+ if (preg_match('/^([\w\-]+):\/\/|^(data):/', $uri, $matches)) {
+ // The scheme will always be the last element in the matches array.
+ return array_pop($matches);
+ }
+
+ return FALSE;
}
/**
@@ -312,10 +316,10 @@ function file_stream_wrapper_valid_scheme($scheme) {
/**
* Returns the part of a URI after the schema.
*
- * @param $uri
- * A stream, referenced as "scheme://target".
+ * @param string $uri
+ * A stream, referenced as "scheme://target" or "data:target".
*
- * @return
+ * @return string|bool
* A string containing the target (path), or FALSE if none.
* For example, the URI "public://sample/test.txt" would return
* "sample/test.txt".
@@ -323,10 +327,12 @@ function file_stream_wrapper_valid_scheme($scheme) {
* @see file_uri_scheme()
*/
function file_uri_target($uri) {
- $data = explode('://', $uri, 2);
+ // Remove the scheme from the URI and remove erroneous leading or trailing,
+ // forward-slashes and backslashes.
+ $target = trim(preg_replace('/^[\w\-]+:\/\/|^data:/', '', $uri), '\/');
- // Remove erroneous leading or trailing, forward-slashes and backslashes.
- return count($data) == 2 ? trim($data[1], '\/') : FALSE;
+ // If nothing was replaced, the URI doesn't have a valid scheme.
+ return $target !== $uri ? $target : FALSE;
}
/**
@@ -439,11 +445,11 @@ function file_stream_wrapper_get_instance_by_scheme($scheme) {
* - "shipped files", i.e. those outside of the files directory, which ship as
* part of Drupal core or contributed modules or themes.
*
- * @param $uri
+ * @param string $uri
* The URI to a file for which we need an external URL, or the path to a
* shipped file.
*
- * @return
+ * @return string
* A string containing a URL that may be used to access the file.
* If the provided string already contains a preceding 'http', 'https', or
* '/', nothing is done and the same string is returned. If a stream wrapper
@@ -476,9 +482,9 @@ function file_create_url($uri) {
return $GLOBALS['base_url'] . '/' . UrlHelper::encodePath($uri);
}
}
- elseif ($scheme == 'http' || $scheme == 'https') {
- // Check for HTTP so that we don't have to implement getExternalUrl() for
- // the HTTP wrapper.
+ elseif ($scheme == 'http' || $scheme == 'https' || $scheme == 'data') {
+ // Check for HTTP and data URI-encoded URLs so that we don't have to
+ // implement getExternalUrl() for the HTTP and data schemes.
return $uri;
}
else {
diff --git a/core/modules/file/src/Tests/DownloadTest.php b/core/modules/file/src/Tests/DownloadTest.php
index 92ba740..9b58599 100644
--- a/core/modules/file/src/Tests/DownloadTest.php
+++ b/core/modules/file/src/Tests/DownloadTest.php
@@ -126,6 +126,7 @@ class DownloadTest extends FileManagedTestBase {
$this->checkUrl('public', '', $basename, $base_path . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . $basename_encoded);
$this->checkUrl('private', '', $basename, $base_path . '/' . $script_path . 'system/files/' . $basename_encoded);
}
+ $this->assertEqual(file_create_url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', t('Generated URL matches expected URL.'));
}
/**
diff --git a/core/modules/system/src/Tests/File/StreamWrapperTest.php b/core/modules/system/src/Tests/File/StreamWrapperTest.php
index 755e988..0c97214 100644
--- a/core/modules/system/src/Tests/File/StreamWrapperTest.php
+++ b/core/modules/system/src/Tests/File/StreamWrapperTest.php
@@ -72,7 +72,10 @@ class StreamWrapperTest extends FileTestBase {
// Test file_uri_target().
$this->assertEqual(file_uri_target('public://foo/bar.txt'), 'foo/bar.txt', 'Got a valid stream target from public://foo/bar.txt.');
+ $this->assertEqual(file_uri_target('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='), 'image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', t('Got a valid stream target from a data URI.'));
$this->assertFalse(file_uri_target('foo/bar.txt'), 'foo/bar.txt is not a valid stream.');
+ $this->assertFalse(file_uri_target('public://'), 'public:// has no target.');
+ $this->assertFalse(file_uri_target('data:'), 'data: has no target.');
// Test file_build_uri() and
// Drupal\Core\StreamWrapper\LocalStream::getDirectoryPath().
@@ -88,6 +91,8 @@ class StreamWrapperTest extends FileTestBase {
*/
function testGetValidStreamScheme() {
$this->assertEqual('foo', file_uri_scheme('foo://pork//chops'), 'Got the correct scheme from foo://asdf');
+ $this->assertEqual('data', file_uri_scheme('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='), 'Got the correct scheme from a data URI.');
+ $this->assertFalse(file_uri_scheme('foo/bar.txt'), 'foo/bar.txt is not a valid stream.');
$this->assertTrue(file_stream_wrapper_valid_scheme(file_uri_scheme('public://asdf')), 'Got a valid stream scheme from public://asdf');
$this->assertFalse(file_stream_wrapper_valid_scheme(file_uri_scheme('foo://asdf')), 'Did not get a valid stream scheme from foo://asdf');
}
diff --git a/core/modules/system/src/Tests/Theme/FunctionsTest.php b/core/modules/system/src/Tests/Theme/FunctionsTest.php
index aac2533..c970553 100644
--- a/core/modules/system/src/Tests/Theme/FunctionsTest.php
+++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php
@@ -382,4 +382,17 @@ class FunctionsTest extends WebTestBase {
$this->assertIdentical(strpos($parent_html, 'First child link'), FALSE, '"First child link" link not found.');
$this->assertIdentical(strpos($parent_html, 'Third child link'), FALSE, '"Third child link" link not found.');
}
+
+ /**
+ * Tests theme_image().
+ */
+ function testImage() {
+ // Test that data URIs work with theme_image().
+ $variables = array();
+ $variables['uri'] = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
+ $variables['alt'] = 'Data URI image of a red dot';
+ $expected = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Data URI image of a red dot" />' . "\n";
+ $this->assertThemeOutput('image', $variables, $expected);
+ }
+
}