security update core 7.58
This commit is contained in:
@@ -1,4 +1,32 @@
|
|||||||
|
|
||||||
|
Drupal 7.58, 2018-03-28
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-002.
|
||||||
|
|
||||||
|
Drupal 7.57, 2018-02-21
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-001.
|
||||||
|
|
||||||
|
Drupal 7.56, 2017-06-21
|
||||||
|
-----------------------
|
||||||
|
- Fixed security issues (access bypass). See SA-CORE-2017-003.
|
||||||
|
|
||||||
|
Drupal 7.55, 2017-06-07
|
||||||
|
-----------------------
|
||||||
|
- Fixed incompatibility with PHP versions 7.0.19 and 7.1.5 due to duplicate
|
||||||
|
DATE_RFC7231 definition.
|
||||||
|
- Made Drupal core pass all automated tests on PHP 7.1.
|
||||||
|
- Allowed services such as Let's Encrypt to work with Drupal on Apache, by
|
||||||
|
making Drupal's .htaccess file allow access to the .well-known directory
|
||||||
|
defined by RFC 5785.
|
||||||
|
- Made new Drupal sites work correctly on Apache 2.4 when the mod_access_compat
|
||||||
|
Apache module is disabled.
|
||||||
|
- Fixed Drupal's URL-generating functions to always encode '[' and ']' so that
|
||||||
|
the URLs will pass HTML5 validation.
|
||||||
|
- Various additional bug fixes.
|
||||||
|
- Various API documentation improvements.
|
||||||
|
- Additional automated test coverage.
|
||||||
|
|
||||||
Drupal 7.54, 2017-02-01
|
Drupal 7.54, 2017-02-01
|
||||||
-----------------------
|
-----------------------
|
||||||
- Modules are now able to define theme engines (API addition:
|
- Modules are now able to define theme engines (API addition:
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
CREATE THE MySQL DATABASE
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a database set up (e.g.,
|
||||||
|
by your host). In the following examples, 'username' is an example MySQL user
|
||||||
|
which has the CREATE and GRANT privileges. Use the appropriate user name for
|
||||||
|
your system.
|
||||||
|
|
||||||
|
First, you must create a new database for your Drupal site (here, 'databasename'
|
||||||
|
is the name of the new database):
|
||||||
|
|
||||||
|
mysqladmin -u username -p create databasename
|
||||||
|
|
||||||
|
MySQL will prompt for the 'username' database password and then create the
|
||||||
|
initial database files. Next you must log in and set the access database rights:
|
||||||
|
|
||||||
|
mysql -u username -p
|
||||||
|
|
||||||
|
Again, you will be asked for the 'username' database password. At the MySQL
|
||||||
|
prompt, enter the following command:
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
|
||||||
|
CREATE TEMPORARY TABLES ON databasename.*
|
||||||
|
TO 'username'@'localhost' IDENTIFIED BY 'password';
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
'databasename' is the name of your database
|
||||||
|
'username' is the username of your MySQL account
|
||||||
|
'localhost' is the web server host where Drupal is installed
|
||||||
|
'password' is the password required for that username
|
||||||
|
|
||||||
|
Note: Unless the database user/host combination for your Drupal installation
|
||||||
|
has all of the privileges listed above (except possibly CREATE TEMPORARY TABLES,
|
||||||
|
which is currently only used by Drupal core automated tests and some
|
||||||
|
contributed modules), you will not be able to install or run Drupal.
|
||||||
|
|
||||||
|
If successful, MySQL will reply with:
|
||||||
|
|
||||||
|
Query OK, 0 rows affected
|
||||||
|
|
||||||
|
If the InnoDB storage engine is available, it will be used for all database
|
||||||
|
tables. InnoDB provides features over MyISAM such as transaction support,
|
||||||
|
row-level locks, and consistent non-locking reads.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
CREATE THE PostgreSQL DATABASE
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Note that the database must be created with UTF-8 (Unicode) encoding.
|
||||||
|
|
||||||
|
1. CREATE DATABASE USER
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a user set up (e.g., by
|
||||||
|
your host), or want to create a new user for use with Drupal only. The
|
||||||
|
following command creates a new user named 'username' and asks for a password
|
||||||
|
for that user:
|
||||||
|
|
||||||
|
createuser --pwprompt --encrypted --no-createrole --no-createdb username
|
||||||
|
|
||||||
|
If there are no errors, then the command was successful.
|
||||||
|
|
||||||
|
2. CREATE DRUPAL DATABASE
|
||||||
|
|
||||||
|
This step is only necessary if you don't already have a database set up
|
||||||
|
(e.g., by your host) or want to create a new database for use with Drupal
|
||||||
|
only. The following command creates a new database named 'databasename',
|
||||||
|
which is owned by the previously created 'username':
|
||||||
|
|
||||||
|
createdb --encoding=UTF8 --owner=username databasename
|
||||||
|
|
||||||
|
If there are no errors, then the command was successful.
|
||||||
|
|
||||||
|
3. CREATE SCHEMA OR SCHEMAS (Optional advanced step)
|
||||||
|
|
||||||
|
Drupal will run across different schemas within your database if you so wish.
|
||||||
|
By default, Drupal runs inside the 'public' schema but you can use $db_prefix
|
||||||
|
inside settings.php to define a schema for Drupal to run inside of, or
|
||||||
|
specify tables that are shared inside of a separate schema. Drupal will not
|
||||||
|
create schemas for you. In fact, the user that Drupal runs as should not be
|
||||||
|
allowed to do this. You'll need to execute the SQL below as a superuser,
|
||||||
|
replace 'username' with the username that Drupal uses to connect to
|
||||||
|
PostgreSQL, and replace 'schema_name' with a schema name you wish to use,
|
||||||
|
such as 'shared':
|
||||||
|
|
||||||
|
CREATE SCHEMA schema_name AUTHORIZATION username;
|
||||||
|
|
||||||
|
Do this for as many schemas as you need. See default.settings.php for
|
||||||
|
instructions on how to set which tables use which schemas.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
SQLITE REQUIREMENTS
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
To use SQLite with your Drupal installation, the following requirements must be
|
||||||
|
met: Server has PHP 5.2 or later with PDO, and the PDO SQLite driver must be
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
SQLITE DATABASE CREATION
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The Drupal installer will create the SQLite database for you. The only
|
||||||
|
requirement is that the installer must have write permissions to the directory
|
||||||
|
where the database file resides. This directory (not just the database file) also
|
||||||
|
has to remain writeable by the web server going forward for SQLite to continue to
|
||||||
|
be able to operate.
|
||||||
|
|
||||||
|
On the "Database configuration" form in the "Database file" field, you must
|
||||||
|
supply the exact path to where you wish your database file to reside. It is
|
||||||
|
strongly suggested that you choose a path that is outside of the webroot, yet
|
||||||
|
ensure that the directory is writeable by the web server.
|
||||||
|
|
||||||
|
If you must place your database file in your webroot, you could try using the
|
||||||
|
following in your "Database file" field:
|
||||||
|
|
||||||
|
sites/default/files/.ht.sqlite
|
||||||
|
|
||||||
|
Note: The .ht in the name will tell Apache to prevent the database from being
|
||||||
|
downloaded. Please check that the file is, indeed, protected by your webserver.
|
||||||
|
If not, please consult the documentation of your webserver on how to protect a
|
||||||
|
file from downloading.
|
||||||
+400
@@ -0,0 +1,400 @@
|
|||||||
|
|
||||||
|
CONTENTS OF THIS FILE
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
* Requirements and notes
|
||||||
|
* Optional server requirements
|
||||||
|
* Installation
|
||||||
|
* Building and customizing your site
|
||||||
|
* Multisite configuration
|
||||||
|
* More information
|
||||||
|
|
||||||
|
REQUIREMENTS AND NOTES
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Drupal requires:
|
||||||
|
|
||||||
|
- A web server. Apache (version 2.0 or greater) is recommended.
|
||||||
|
- PHP 5.2.4 (or greater) (http://www.php.net/).
|
||||||
|
- One of the following databases:
|
||||||
|
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
|
||||||
|
- MariaDB 5.1.44 (or greater) (http://mariadb.org/). MariaDB is a fully
|
||||||
|
compatible drop-in replacement for MySQL.
|
||||||
|
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
|
||||||
|
Server is a backwards-compatible replacement for MySQL.
|
||||||
|
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
|
||||||
|
- SQLite 3.3.7 (or greater) (http://www.sqlite.org/).
|
||||||
|
|
||||||
|
For more detailed information about Drupal requirements, including a list of
|
||||||
|
PHP extensions and configurations that are required, see "System requirements"
|
||||||
|
(http://drupal.org/requirements) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
For detailed information on how to configure a test server environment using a
|
||||||
|
variety of operating systems and web servers, see "Local server setup"
|
||||||
|
(http://drupal.org/node/157602) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
Note that all directories mentioned in this document are always relative to the
|
||||||
|
directory of your Drupal installation, and commands are meant to be run from
|
||||||
|
this directory (except for the initial commands that create that directory).
|
||||||
|
|
||||||
|
OPTIONAL SERVER REQUIREMENTS
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
- If you want to use Drupal's "Clean URLs" feature on an Apache web server, you
|
||||||
|
will need the mod_rewrite module and the ability to use local .htaccess
|
||||||
|
files. For Clean URLs support on IIS, see "Clean URLs with IIS"
|
||||||
|
(http://drupal.org/node/3854) in the Drupal.org online documentation.
|
||||||
|
|
||||||
|
- If you plan to use XML-based services such as RSS aggregation, you will need
|
||||||
|
PHP's XML extension. This extension is enabled by default on most PHP
|
||||||
|
installations.
|
||||||
|
|
||||||
|
- To serve gzip compressed CSS and JS files on an Apache web server, you will
|
||||||
|
need the mod_headers module and the ability to use local .htaccess files.
|
||||||
|
|
||||||
|
- Some Drupal functionality (e.g., checking whether Drupal and contributed
|
||||||
|
modules need updates, RSS aggregation, etc.) require that the web server be
|
||||||
|
able to go out to the web and download information. If you want to use this
|
||||||
|
functionality, you need to verify that your hosting provider or server
|
||||||
|
configuration allows the web server to initiate outbound connections. Most web
|
||||||
|
hosting setups allow this.
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Download and extract Drupal.
|
||||||
|
|
||||||
|
You can obtain the latest Drupal release from http://drupal.org -- the files
|
||||||
|
are available in .tar.gz and .zip formats and can be extracted using most
|
||||||
|
compression tools.
|
||||||
|
|
||||||
|
To download and extract the files, on a typical Unix/Linux command line, use
|
||||||
|
the following commands (assuming you want version x.y of Drupal in .tar.gz
|
||||||
|
format):
|
||||||
|
|
||||||
|
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
|
||||||
|
tar -zxvf drupal-x.y.tar.gz
|
||||||
|
|
||||||
|
This will create a new directory drupal-x.y/ containing all Drupal files and
|
||||||
|
directories. Then, to move the contents of that directory into a directory
|
||||||
|
within your web server's document root or your public HTML directory,
|
||||||
|
continue with this command:
|
||||||
|
|
||||||
|
mv drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
|
||||||
|
|
||||||
|
2. Optionally, download a translation.
|
||||||
|
|
||||||
|
By default, Drupal is installed in English, and further languages may be
|
||||||
|
installed later. If you prefer to install Drupal in another language
|
||||||
|
initially:
|
||||||
|
|
||||||
|
- Download a translation file for the correct Drupal version and language
|
||||||
|
from the translation server: http://localize.drupal.org/translate/downloads
|
||||||
|
|
||||||
|
- Place the file into your installation profile's translations directory.
|
||||||
|
For instance, if you are using the Standard installation profile,
|
||||||
|
move the .po file into the directory:
|
||||||
|
|
||||||
|
profiles/standard/translations/
|
||||||
|
|
||||||
|
For detailed instructions, visit http://drupal.org/localize
|
||||||
|
|
||||||
|
3. Create the Drupal database.
|
||||||
|
|
||||||
|
Because Drupal stores all site information in a database, you must create
|
||||||
|
this database in order to install Drupal, and grant Drupal certain database
|
||||||
|
privileges (such as the ability to create tables). For details, consult
|
||||||
|
INSTALL.mysql.txt, INSTALL.pgsql.txt, or INSTALL.sqlite.txt. You may also
|
||||||
|
need to consult your web hosting provider for instructions specific to your
|
||||||
|
web host.
|
||||||
|
|
||||||
|
Take note of the username, password, database name, and hostname as you
|
||||||
|
create the database. You will enter this information during the install.
|
||||||
|
|
||||||
|
4. Run the install script.
|
||||||
|
|
||||||
|
To run the install script, point your browser to the base URL of your
|
||||||
|
website (e.g., http://www.example.com).
|
||||||
|
|
||||||
|
You will be guided through several screens to set up the database, add the
|
||||||
|
site maintenance account (the first user, also known as user/1), and provide
|
||||||
|
basic web site settings.
|
||||||
|
|
||||||
|
During installation, several files and directories need to be created, which
|
||||||
|
the install script will try to do automatically. However, on some hosting
|
||||||
|
environments, manual steps are required, and the install script will tell
|
||||||
|
you that it cannot proceed until you fix certain issues. This is normal and
|
||||||
|
does not indicate a problem with your server.
|
||||||
|
|
||||||
|
The most common steps you may need to perform are:
|
||||||
|
|
||||||
|
a. Missing files directory.
|
||||||
|
|
||||||
|
The install script will attempt to create a file storage directory in
|
||||||
|
the default location at sites/default/files (the location of the files
|
||||||
|
directory may be changed after Drupal is installed).
|
||||||
|
|
||||||
|
If auto-creation fails, you can make it work by changing permissions on
|
||||||
|
the sites/default directory so that the web server can create the files
|
||||||
|
directory within it for you. (If you are creating a multisite
|
||||||
|
installation, substitute the correct sites directory for sites/default;
|
||||||
|
see the Multisite Configuration section of this file, below.)
|
||||||
|
|
||||||
|
For example, on a Unix/Linux command line, you can grant everyone
|
||||||
|
(including the web server) permission to write to the sites/default
|
||||||
|
directory with this command:
|
||||||
|
|
||||||
|
chmod a+w sites/default
|
||||||
|
|
||||||
|
Be sure to set the permissions back after the installation is finished!
|
||||||
|
Sample command:
|
||||||
|
|
||||||
|
chmod go-w sites/default
|
||||||
|
|
||||||
|
Alternatively, instead of allowing the web server to create the files
|
||||||
|
directory for you as described above, you can create it yourself. Sample
|
||||||
|
commands from a Unix/Linux command line:
|
||||||
|
|
||||||
|
mkdir sites/default/files
|
||||||
|
chmod a+w sites/default/files
|
||||||
|
|
||||||
|
b. Missing settings file.
|
||||||
|
|
||||||
|
Drupal will try to automatically create a settings.php configuration file,
|
||||||
|
which is normally in the directory sites/default (to avoid problems when
|
||||||
|
upgrading, Drupal is not packaged with this file). If auto-creation fails,
|
||||||
|
you will need to create this file yourself, using the file
|
||||||
|
sites/default/default.settings.php as a template.
|
||||||
|
|
||||||
|
For example, on a Unix/Linux command line, you can make a copy of the
|
||||||
|
default.settings.php file with the command:
|
||||||
|
|
||||||
|
cp sites/default/default.settings.php sites/default/settings.php
|
||||||
|
|
||||||
|
Next, grant write privileges to the file to everyone (including the web
|
||||||
|
server) with the command:
|
||||||
|
|
||||||
|
chmod a+w sites/default/settings.php
|
||||||
|
|
||||||
|
Be sure to set the permissions back after the installation is finished!
|
||||||
|
Sample command:
|
||||||
|
|
||||||
|
chmod go-w sites/default/settings.php
|
||||||
|
|
||||||
|
c. Write permissions after install.
|
||||||
|
|
||||||
|
The install script will attempt to write-protect the settings.php file and
|
||||||
|
the sites/default directory after saving your configuration. If this
|
||||||
|
fails, you will be notified, and you can do it manually. Sample commands
|
||||||
|
from a Unix/Linux command line:
|
||||||
|
|
||||||
|
chmod go-w sites/default/settings.php
|
||||||
|
chmod go-w sites/default
|
||||||
|
|
||||||
|
5. Verify that the site is working.
|
||||||
|
|
||||||
|
When the install script finishes, you will be logged in with the site
|
||||||
|
maintenance account on a "Welcome" page. If the default Drupal theme is not
|
||||||
|
displaying properly and links on the page result in "Page Not Found" errors,
|
||||||
|
you may be experiencing problems with clean URLs. Visit
|
||||||
|
http://drupal.org/getting-started/clean-urls to troubleshoot.
|
||||||
|
|
||||||
|
6. Change file system storage settings (optional).
|
||||||
|
|
||||||
|
The files directory created in step 4 is the default file system path used to
|
||||||
|
store all uploaded files, as well as some temporary files created by
|
||||||
|
Drupal. After installation, you can modify the file system path to store
|
||||||
|
uploaded files in a different location.
|
||||||
|
|
||||||
|
It is not necessary to modify this path, but you may wish to change it if:
|
||||||
|
|
||||||
|
- Your site runs multiple Drupal installations from a single codebase (modify
|
||||||
|
the file system path of each installation to a different directory so that
|
||||||
|
uploads do not overlap between installations).
|
||||||
|
|
||||||
|
- Your site runs on a number of web servers behind a load balancer or reverse
|
||||||
|
proxy (modify the file system path on each server to point to a shared file
|
||||||
|
repository).
|
||||||
|
|
||||||
|
- You want to restrict access to uploaded files.
|
||||||
|
|
||||||
|
To modify the file system path:
|
||||||
|
|
||||||
|
a. Ensure that the new location for the path exists and is writable by the
|
||||||
|
web server. For example, to create a new directory named uploads and grant
|
||||||
|
write permissions, use the following commands on a Unix/Linux command
|
||||||
|
line:
|
||||||
|
|
||||||
|
mkdir uploads
|
||||||
|
chmod a+w uploads
|
||||||
|
|
||||||
|
b. Navigate to Administration > Configuration > Media > File system, and
|
||||||
|
enter the desired path. Note that if you want to use private file storage,
|
||||||
|
you need to first enter the path for private files and save the
|
||||||
|
configuration, and then change the "Default download method" setting and
|
||||||
|
save again.
|
||||||
|
|
||||||
|
Changing the file system path after files have been uploaded may cause
|
||||||
|
unexpected problems on an existing site. If you modify the file system path
|
||||||
|
on an existing site, remember to copy all files from the original location
|
||||||
|
to the new location.
|
||||||
|
|
||||||
|
7. Revoke documentation file permissions (optional).
|
||||||
|
|
||||||
|
Some administrators suggest making the documentation files, especially
|
||||||
|
CHANGELOG.txt, non-readable so that the exact version of Drupal you are
|
||||||
|
running is slightly more difficult to determine. If you wish to implement
|
||||||
|
this optional security measure, from a Unix/Linux command line you can use
|
||||||
|
the following command:
|
||||||
|
|
||||||
|
chmod a-r CHANGELOG.txt
|
||||||
|
|
||||||
|
Note that the example only affects CHANGELOG.txt. To completely hide all
|
||||||
|
documentation files from public view, repeat this command for each of the
|
||||||
|
Drupal documentation files in the installation directory, substituting the
|
||||||
|
name of each file for CHANGELOG.txt in the example.
|
||||||
|
|
||||||
|
For more information on setting file permissions, see "Modifying Linux,
|
||||||
|
Unix, and Mac file permissions" (http://drupal.org/node/202483) or
|
||||||
|
"Modifying Windows file permissions" (http://drupal.org/node/202491) in the
|
||||||
|
Drupal.org online documentation.
|
||||||
|
|
||||||
|
8. Set up independent "cron" maintenance jobs.
|
||||||
|
|
||||||
|
Many Drupal modules have tasks that must be run periodically, including the
|
||||||
|
Search module (building and updating the index used for keyword searching),
|
||||||
|
the Aggregator module (retrieving feeds from other sites), and the System
|
||||||
|
module (performing routine maintenance and pruning of database tables). These
|
||||||
|
tasks are known as "cron maintenance tasks", named after the Unix/Linux
|
||||||
|
"cron" utility.
|
||||||
|
|
||||||
|
When you install Drupal, its built-in cron feature is enabled, which
|
||||||
|
automatically runs the cron tasks periodically, triggered by people visiting
|
||||||
|
pages of your site. You can configure the built-in cron feature by navigating
|
||||||
|
to Administration > Configuration > System > Cron.
|
||||||
|
|
||||||
|
It is also possible to run the cron tasks independent of site visits; this is
|
||||||
|
recommended for most sites. To do this, you will need to set up an automated
|
||||||
|
process to visit the page cron.php on your site, which executes the cron
|
||||||
|
tasks.
|
||||||
|
|
||||||
|
The URL of the cron.php page requires a "cron key" to protect against
|
||||||
|
unauthorized access. Your site's cron key is automatically generated during
|
||||||
|
installation and is specific to your site. The full URL of the page, with the
|
||||||
|
cron key, is available in the "Cron maintenance tasks" section of the Status
|
||||||
|
report page at Administration > Reports > Status report.
|
||||||
|
|
||||||
|
As an example for how to set up this automated process, you can use the
|
||||||
|
crontab utility on Unix/Linux systems. The following crontab line uses the
|
||||||
|
wget command to visit the cron.php page, and runs each hour, on the hour:
|
||||||
|
|
||||||
|
0 * * * * wget -O - -q -t 1 http://example.com/cron.php?cron_key=YOURKEY
|
||||||
|
|
||||||
|
Replace the text "http://example.com/cron.php?cron_key=YOURKEY" in the
|
||||||
|
example with the full URL displayed under "Cron maintenance tasks" on the
|
||||||
|
"Status report" page.
|
||||||
|
|
||||||
|
More information about cron maintenance tasks is available at
|
||||||
|
http://drupal.org/cron, and sample cron shell scripts can be found in the
|
||||||
|
scripts/ directory. (Note that these scripts must be customized like the
|
||||||
|
above example, to add your site-specific cron key and domain name.)
|
||||||
|
|
||||||
|
BUILDING AND CUSTOMIZING YOUR SITE
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
A new installation of Drupal defaults to a very basic configuration. To extend
|
||||||
|
your site, you use "modules" and "themes". A module is a plugin that adds
|
||||||
|
functionality to Drupal, while a theme changes the look of your site. The core
|
||||||
|
of Drupal provides several optional modules and themes, and you can download
|
||||||
|
more at http://drupal.org/project/modules and http://drupal.org/project/themes
|
||||||
|
|
||||||
|
Do not mix downloaded or custom modules and themes with Drupal's core modules
|
||||||
|
and themes. Drupal's modules and themes are located in the top-level modules and
|
||||||
|
themes directories, while the modules and themes you add to Drupal are normally
|
||||||
|
placed in the sites/all/modules and sites/all/themes directories. If you run a
|
||||||
|
multisite installation, you can also place modules and themes in the
|
||||||
|
site-specific directories -- see the Multisite Configuration section, below.
|
||||||
|
|
||||||
|
Never edit Drupal's core modules and themes; instead, use the hooks available in
|
||||||
|
the Drupal API. To modify the behavior of Drupal, develop a module as described
|
||||||
|
at http://drupal.org/developing/modules. To modify the look of Drupal, create a
|
||||||
|
subtheme as described at http://drupal.org/node/225125, or a completely new
|
||||||
|
theme as described at http://drupal.org/documentation/theme
|
||||||
|
|
||||||
|
MULTISITE CONFIGURATION
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
A single Drupal installation can host several Drupal-powered sites, each with
|
||||||
|
its own individual configuration.
|
||||||
|
|
||||||
|
Additional site configurations are created in subdirectories within the 'sites'
|
||||||
|
directory. Each subdirectory must have a 'settings.php' file, which specifies
|
||||||
|
the configuration settings. The easiest way to create additional sites is to
|
||||||
|
copy the 'default' directory and modify the 'settings.php' file as appropriate.
|
||||||
|
The new directory name is constructed from the site's URL. The configuration for
|
||||||
|
www.example.com could be in 'sites/example.com/settings.php' (note that 'www.'
|
||||||
|
should be omitted if users can access your site at http://example.com/).
|
||||||
|
|
||||||
|
Sites do not have to have a different domain. You can also use subdomains and
|
||||||
|
subdirectories for Drupal sites. For example, example.com, sub.example.com, and
|
||||||
|
sub.example.com/site3 can all be defined as independent Drupal sites. The setup
|
||||||
|
for a configuration such as this would look like the following:
|
||||||
|
|
||||||
|
sites/default/settings.php
|
||||||
|
sites/example.com/settings.php
|
||||||
|
sites/sub.example.com/settings.php
|
||||||
|
sites/sub.example.com.site3/settings.php
|
||||||
|
|
||||||
|
When searching for a site configuration (for example www.sub.example.com/site3),
|
||||||
|
Drupal will search for configuration files in the following order, using the
|
||||||
|
first configuration it finds:
|
||||||
|
|
||||||
|
sites/www.sub.example.com.site3/settings.php
|
||||||
|
sites/sub.example.com.site3/settings.php
|
||||||
|
sites/example.com.site3/settings.php
|
||||||
|
sites/www.sub.example.com/settings.php
|
||||||
|
sites/sub.example.com/settings.php
|
||||||
|
sites/example.com/settings.php
|
||||||
|
sites/default/settings.php
|
||||||
|
|
||||||
|
If you are installing on a non-standard port, the port number is treated as the
|
||||||
|
deepest subdomain. For example: http://www.example.com:8080/ could be loaded
|
||||||
|
from sites/8080.www.example.com/. The port number will be removed according to
|
||||||
|
the pattern above if no port-specific configuration is found, just like a real
|
||||||
|
subdomain.
|
||||||
|
|
||||||
|
Each site configuration can have its own site-specific modules and themes in
|
||||||
|
addition to those installed in the standard 'modules' and 'themes' directories.
|
||||||
|
To use site-specific modules or themes, simply create a 'modules' or 'themes'
|
||||||
|
directory within the site configuration directory. For example, if
|
||||||
|
sub.example.com has a custom theme and a custom module that should not be
|
||||||
|
accessible to other sites, the setup would look like this:
|
||||||
|
|
||||||
|
sites/sub.example.com/
|
||||||
|
settings.php
|
||||||
|
themes/custom_theme
|
||||||
|
modules/custom_module
|
||||||
|
|
||||||
|
NOTE: for more information about multiple virtual hosts or the configuration
|
||||||
|
settings, consult http://drupal.org/getting-started/6/install/multi-site
|
||||||
|
|
||||||
|
For more information on configuring Drupal's file system path in a multisite
|
||||||
|
configuration, see step 6 above.
|
||||||
|
|
||||||
|
MORE INFORMATION
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- See the Drupal.org online documentation:
|
||||||
|
http://drupal.org/documentation
|
||||||
|
|
||||||
|
- For a list of security announcements, see the "Security advisories" page at
|
||||||
|
http://drupal.org/security (available as an RSS feed). This page also
|
||||||
|
describes how to subscribe to these announcements via e-mail.
|
||||||
|
|
||||||
|
- For information about the Drupal security process, or to find out how to
|
||||||
|
report a potential security issue to the Drupal security team, see the
|
||||||
|
"Security team" page at http://drupal.org/security-team
|
||||||
|
|
||||||
|
- For information about the wide range of available support options, visit
|
||||||
|
http://drupal.org and click on Community and Support in the top or bottom
|
||||||
|
navigation.
|
||||||
+10
-1
@@ -8,7 +8,7 @@
|
|||||||
/**
|
/**
|
||||||
* The current system version.
|
* The current system version.
|
||||||
*/
|
*/
|
||||||
define('VERSION', '7.54');
|
define('VERSION', '7.58');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core API compatibility.
|
* Core API compatibility.
|
||||||
@@ -254,8 +254,13 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
|
|||||||
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
||||||
*
|
*
|
||||||
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
||||||
|
*
|
||||||
|
* This constant was introduced in PHP 7.0.19 and PHP 7.1.5 but needs to be
|
||||||
|
* defined by Drupal for earlier PHP versions.
|
||||||
*/
|
*/
|
||||||
|
if (!defined('DATE_RFC7231')) {
|
||||||
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
|
define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a caching wrapper to be used in place of large array structures.
|
* Provides a caching wrapper to be used in place of large array structures.
|
||||||
@@ -2627,6 +2632,10 @@ function _drupal_bootstrap_configuration() {
|
|||||||
timer_start('page');
|
timer_start('page');
|
||||||
// Initialize the configuration, including variables from settings.php.
|
// Initialize the configuration, including variables from settings.php.
|
||||||
drupal_settings_initialize();
|
drupal_settings_initialize();
|
||||||
|
|
||||||
|
// Sanitize unsafe keys from the request.
|
||||||
|
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
|
||||||
|
DrupalRequestSanitizer::sanitize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+5
-2
@@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') {
|
|||||||
$params = array();
|
$params = array();
|
||||||
|
|
||||||
foreach ($query as $key => $value) {
|
foreach ($query as $key => $value) {
|
||||||
$key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
|
$key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key);
|
||||||
|
|
||||||
// Recurse into children.
|
// Recurse into children.
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
@@ -2236,8 +2236,11 @@ function url($path = NULL, array $options = array()) {
|
|||||||
'prefix' => ''
|
'prefix' => ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Determine whether this is an external link, but ensure that the current
|
||||||
|
// path is always treated as internal by default (to prevent external link
|
||||||
|
// injection vulnerabilities).
|
||||||
if (!isset($options['external'])) {
|
if (!isset($options['external'])) {
|
||||||
$options['external'] = url_is_external($path);
|
$options['external'] = $path === $_GET['q'] ? FALSE : url_is_external($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve the original path before altering or aliasing.
|
// Preserve the original path before altering or aliasing.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name by which to obtain a lock for retrive the next insert id.
|
* The name by which to obtain a lock for retrieving the next insert id.
|
||||||
*/
|
*/
|
||||||
define('POSTGRESQL_NEXTID_LOCK', 1000);
|
define('POSTGRESQL_NEXTID_LOCK', 1000);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
$connection_options['pdo'] += array(
|
$connection_options['pdo'] += array(
|
||||||
// Prepared statements are most effective for performance when queries
|
// Prepared statements are most effective for performance when queries
|
||||||
// are recycled (used several times). However, if they are not re-used,
|
// are recycled (used several times). However, if they are not re-used,
|
||||||
// prepared statements become ineffecient. Since most of Drupal's
|
// prepared statements become inefficient. Since most of Drupal's
|
||||||
// prepared queries are not re-used, it should be faster to emulate
|
// prepared queries are not re-used, it should be faster to emulate
|
||||||
// the preparation than to actually ready statements for re-use. If in
|
// the preparation than to actually ready statements for re-use. If in
|
||||||
// doubt, reset to FALSE and measure performance.
|
// doubt, reset to FALSE and measure performance.
|
||||||
@@ -175,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrive a the next id in a sequence.
|
* Retrieve the next id in a sequence.
|
||||||
*
|
*
|
||||||
* PostgreSQL has built in sequences. We'll use these instead of inserting
|
* PostgreSQL has built in sequences. We'll use these instead of inserting
|
||||||
* and updating a sequences table.
|
* and updating a sequences table.
|
||||||
*/
|
*/
|
||||||
public function nextId($existing = 0) {
|
public function nextId($existing = 0) {
|
||||||
|
|
||||||
// Retrive the name of the sequence. This information cannot be cached
|
// Retrieve the name of the sequence. This information cannot be cached
|
||||||
// because the prefix may change, for example, like it does in simpletests.
|
// because the prefix may change, for example, like it does in simpletests.
|
||||||
$sequence_name = $this->makeSequenceName('sequences', 'value');
|
$sequence_name = $this->makeSequenceName('sequences', 'value');
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL advisory locks are simply locks to be used by an
|
// PostgreSQL advisory locks are simply locks to be used by an
|
||||||
// application such as Drupal. This will prevent other Drupal proccesses
|
// application such as Drupal. This will prevent other Drupal processes
|
||||||
// from altering the sequence while we are.
|
// from altering the sequence while we are.
|
||||||
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
$this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
|
|||||||
// Reset the sequence to a higher value than the existing id.
|
// Reset the sequence to a higher value than the existing id.
|
||||||
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
|
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
|
||||||
|
|
||||||
// Retrive the next id. We know this will be as high as we want it.
|
// Retrieve the next id. We know this will be as high as we want it.
|
||||||
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
|
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
|
||||||
|
|
||||||
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
$this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
|
|||||||
LANGUAGE \'sql\''
|
LANGUAGE \'sql\''
|
||||||
);
|
);
|
||||||
|
|
||||||
// Using || to concatenate in Drupal is not recommeneded because there are
|
// Using || to concatenate in Drupal is not recommended because there are
|
||||||
// database drivers for Drupal that do not support the syntax, however
|
// database drivers for Drupal that do not support the syntax, however
|
||||||
// they do support CONCAT(item1, item2) which we can replicate in
|
// they do support CONCAT(item1, item2) which we can replicate in
|
||||||
// PostgreSQL. PostgreSQL requires the function to be defined for each
|
// PostgreSQL. PostgreSQL requires the function to be defined for each
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a table loads all fields, it can not be added again. It would
|
// If a table loads all fields, it can not be added again. It would
|
||||||
// result in an ambigious alias error because that field would be loaded
|
// result in an ambiguous alias error because that field would be loaded
|
||||||
// twice: Once through table_alias.* and once directly. If the field
|
// twice: Once through table_alias.* and once directly. If the field
|
||||||
// actually belongs to a different table, it must be added manually.
|
// actually belongs to a different table, it must be added manually.
|
||||||
foreach ($this->tables as $table) {
|
foreach ($this->tables as $table) {
|
||||||
@@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If $field contains an characters which are not allowed in a field name
|
// If $field contains an characters which are not allowed in a field name
|
||||||
// it is considered an expression, these can't be handeld automatically
|
// it is considered an expression, these can't be handled automatically
|
||||||
// either.
|
// either.
|
||||||
if ($this->connection->escapeField($field) != $field) {
|
if ($this->connection->escapeField($field) != $field) {
|
||||||
return $return;
|
return $return;
|
||||||
|
|||||||
@@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface {
|
|||||||
/**
|
/**
|
||||||
* Executes the DELETE query.
|
* Executes the DELETE query.
|
||||||
*
|
*
|
||||||
* @return
|
* @return int
|
||||||
* The return value is dependent on the database connection.
|
* The number of rows affected by the delete query.
|
||||||
*/
|
*/
|
||||||
public function execute() {
|
public function execute() {
|
||||||
$values = array();
|
$values = array();
|
||||||
@@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
|
|||||||
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
|
* MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
|
||||||
* instead. MergeQuery::fields() can also be called which calls both of these
|
* instead. MergeQuery::fields() can also be called which calls both of these
|
||||||
* methods as the common case is to use the same column-value pairs for both
|
* methods as the common case is to use the same column-value pairs for both
|
||||||
* INSERT and UPDATE. However, this is not mandatory. Another convinient
|
* INSERT and UPDATE. However, this is not mandatory. Another convenient
|
||||||
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
|
* wrapper is MergeQuery::key() which adds the same column-value pairs to the
|
||||||
* condition and the INSERT query part.
|
* condition and the INSERT query part.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -164,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc';
|
|||||||
* @see drupal_install_schema()
|
* @see drupal_install_schema()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for database schema definitions.
|
||||||
|
*/
|
||||||
abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
||||||
|
|
||||||
protected $connection;
|
protected $connection;
|
||||||
@@ -291,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
|
|||||||
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
|
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
|
||||||
$info = $this->connection->getConnectionOptions();
|
$info = $this->connection->getConnectionOptions();
|
||||||
|
|
||||||
// Retrive the table name and schema
|
// Retrieve the table name and schema
|
||||||
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
|
$table_info = $this->getPrefixInfo($table_name, $add_prefix);
|
||||||
|
|
||||||
$condition = new DatabaseCondition('AND');
|
$condition = new DatabaseCondition('AND');
|
||||||
|
|||||||
@@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SQLite specific implementation of DeleteQuery.
|
* SQLite specific implementation of DeleteQuery.
|
||||||
*
|
|
||||||
* When the WHERE is omitted from a DELETE statement and the table being deleted
|
|
||||||
* has no triggers, SQLite uses an optimization to erase the entire table content
|
|
||||||
* without having to visit each row of the table individually.
|
|
||||||
*
|
|
||||||
* Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted
|
|
||||||
* by that optimized "truncate" optimization.
|
|
||||||
*/
|
*/
|
||||||
class DeleteQuery_sqlite extends DeleteQuery {
|
class DeleteQuery_sqlite extends DeleteQuery {
|
||||||
public function execute() {
|
public function execute() {
|
||||||
|
// When the WHERE is omitted from a DELETE statement and the table being
|
||||||
|
// deleted has no triggers, SQLite uses an optimization to erase the entire
|
||||||
|
// table content without having to visit each row of the table individually.
|
||||||
|
// Prior to SQLite 3.6.5, SQLite does not return the actual number of rows
|
||||||
|
// deleted by that optimized "truncate" optimization. But we want to return
|
||||||
|
// the number of rows affected, so we calculate it directly.
|
||||||
if (!count($this->condition)) {
|
if (!count($this->condition)) {
|
||||||
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
|
$total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
|
||||||
parent::execute();
|
parent::execute();
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
|
|||||||
// database. So the syntax '...RENAME TO database.table' would fail.
|
// database. So the syntax '...RENAME TO database.table' would fail.
|
||||||
// So we must determine the full table name here rather than surrounding
|
// So we must determine the full table name here rather than surrounding
|
||||||
// the table with curly braces incase the db_prefix contains a reference
|
// the table with curly braces incase the db_prefix contains a reference
|
||||||
// to a database outside of our existsing database.
|
// to a database outside of our existing database.
|
||||||
$info = $this->getPrefixInfo($new_name);
|
$info = $this->getPrefixInfo($new_name);
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
|
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
|
|||||||
_drupal_log_error(array(
|
_drupal_log_error(array(
|
||||||
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
|
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
|
||||||
// The standard PHP error handler considers that the error messages
|
// The standard PHP error handler considers that the error messages
|
||||||
// are HTML. We mimick this behavior here.
|
// are HTML. We mimic this behavior here.
|
||||||
'!message' => filter_xss_admin($message),
|
'!message' => filter_xss_admin($message),
|
||||||
'%function' => $caller['function'],
|
'%function' => $caller['function'],
|
||||||
'%file' => $caller['file'],
|
'%file' => $caller['file'],
|
||||||
@@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) {
|
|||||||
return array(
|
return array(
|
||||||
'%type' => get_class($exception),
|
'%type' => get_class($exception),
|
||||||
// The standard PHP exception handler considers that the exception message
|
// The standard PHP exception handler considers that the exception message
|
||||||
// is plain-text. We mimick this behavior here.
|
// is plain-text. We mimic this behavior here.
|
||||||
'!message' => check_plain($message),
|
'!message' => check_plain($message),
|
||||||
'%function' => $caller['function'],
|
'%function' => $caller['function'],
|
||||||
'%file' => $caller['file'],
|
'%file' => $caller['file'],
|
||||||
@@ -233,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Display the message if the current error reporting level allows this type
|
// Display the message if the current error reporting level allows this type
|
||||||
// of message to be displayed, and unconditionnaly in update.php.
|
// of message to be displayed, and unconditionally in update.php.
|
||||||
if (error_displayable($error)) {
|
if (error_displayable($error)) {
|
||||||
$class = 'error';
|
$class = 'error';
|
||||||
|
|
||||||
|
|||||||
+26
-3
@@ -535,7 +535,18 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
|
|||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
if ($private) {
|
if ($private) {
|
||||||
$lines = "Deny from all\n\n" . $lines;
|
$lines = <<<EOF
|
||||||
|
# Deny all requests from Apache 2.4+.
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Deny all requests from Apache 2.0-2.2.
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
|
EOF
|
||||||
|
. "\n\n" . $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $lines;
|
return $lines;
|
||||||
@@ -889,7 +900,6 @@ function file_valid_uri($uri) {
|
|||||||
*/
|
*/
|
||||||
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
|
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
|
||||||
$original_source = $source;
|
$original_source = $source;
|
||||||
$original_destination = $destination;
|
|
||||||
|
|
||||||
// Assert that the source file actually exists.
|
// Assert that the source file actually exists.
|
||||||
if (!file_exists($source)) {
|
if (!file_exists($source)) {
|
||||||
@@ -1604,6 +1614,20 @@ function file_save_upload($form_field_name, $validators = array(), $destination
|
|||||||
|
|
||||||
// If we made it this far it's safe to record this file in the database.
|
// If we made it this far it's safe to record this file in the database.
|
||||||
if ($file = file_save($file)) {
|
if ($file = file_save($file)) {
|
||||||
|
// Track non-public files in the session if they were uploaded by an
|
||||||
|
// anonymous user. This allows modules such as the File module to only
|
||||||
|
// grant view access to the specific anonymous user who uploaded the file.
|
||||||
|
// See file_file_download().
|
||||||
|
// The 'file_public_schema' variable is used to allow other publicly
|
||||||
|
// accessible file schemes to be treated the same as the public:// scheme
|
||||||
|
// provided by Drupal core and to avoid adding unnecessary data to the
|
||||||
|
// session (and the resulting bypass of the page cache) in those cases. For
|
||||||
|
// security reasons, only schemes that are completely publicly accessible,
|
||||||
|
// with no download restrictions, should be added to this variable. See
|
||||||
|
// file_managed_file_value().
|
||||||
|
if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) {
|
||||||
|
$_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid;
|
||||||
|
}
|
||||||
// Add file to the cache.
|
// Add file to the cache.
|
||||||
$upload_cache[$form_field_name] = $file;
|
$upload_cache[$form_field_name] = $file;
|
||||||
return $file;
|
return $file;
|
||||||
@@ -2553,7 +2577,6 @@ function file_directory_temp() {
|
|||||||
* An associative array of headers, as expected by file_transfer().
|
* An associative array of headers, as expected by file_transfer().
|
||||||
*/
|
*/
|
||||||
function file_get_content_headers($file) {
|
function file_get_content_headers($file) {
|
||||||
$name = mime_header_encode($file->filename);
|
|
||||||
$type = mime_header_encode($file->filemime);
|
$type = mime_header_encode($file->filemime);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains code for sanitizing user input from the request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes user input from the request.
|
||||||
|
*/
|
||||||
|
class DrupalRequestSanitizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks whether the request was already sanitized.
|
||||||
|
*/
|
||||||
|
protected static $sanitized = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the request to strip dangerous keys from user input.
|
||||||
|
*/
|
||||||
|
public static function sanitize() {
|
||||||
|
if (!self::$sanitized) {
|
||||||
|
$whitelist = variable_get('sanitize_input_whitelist', array());
|
||||||
|
$log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
|
||||||
|
|
||||||
|
// Process query string parameters.
|
||||||
|
$get_sanitized_keys = array();
|
||||||
|
$_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $get_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process request body parameters.
|
||||||
|
$post_sanitized_keys = array();
|
||||||
|
$_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $post_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process cookie parameters.
|
||||||
|
$cookie_sanitized_keys = array();
|
||||||
|
$_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
|
||||||
|
if ($log_sanitized_keys && $cookie_sanitized_keys) {
|
||||||
|
_drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request_sanitized_keys = array();
|
||||||
|
$_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
|
||||||
|
|
||||||
|
self::$sanitized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips dangerous keys from the provided input.
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* The input to sanitize.
|
||||||
|
* @param string[] $whitelist
|
||||||
|
* An array of keys to whitelist as safe.
|
||||||
|
* @param string[] $sanitized_keys
|
||||||
|
* An array of keys that have been removed.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* The sanitized input.
|
||||||
|
*/
|
||||||
|
protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
|
||||||
|
if (is_array($input)) {
|
||||||
|
foreach ($input as $key => $value) {
|
||||||
|
if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
|
||||||
|
unset($input[$key]);
|
||||||
|
$sanitized_keys[] = $key;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Initiates a browser-based installation of Drupal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the root directory of the Drupal installation.
|
||||||
|
*/
|
||||||
|
define('DRUPAL_ROOT', getcwd());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global flag to indicate the site is in installation mode.
|
||||||
|
*/
|
||||||
|
define('MAINTENANCE_MODE', 'install');
|
||||||
|
|
||||||
|
// Exit early if running an incompatible PHP version to avoid fatal errors.
|
||||||
|
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
|
||||||
|
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the installer.
|
||||||
|
require_once DRUPAL_ROOT . '/includes/install.core.inc';
|
||||||
|
install_drupal();
|
||||||
+93
-4
@@ -27,6 +27,42 @@ $.fn.init = function (selector, context, rootjQuery) {
|
|||||||
};
|
};
|
||||||
$.fn.init.prototype = jquery_init.prototype;
|
$.fn.init.prototype = jquery_init.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-filter Ajax requests to guard against XSS attacks.
|
||||||
|
*
|
||||||
|
* See https://github.com/jquery/jquery/issues/2432
|
||||||
|
*/
|
||||||
|
if ($.ajaxPrefilter) {
|
||||||
|
// For newer versions of jQuery, use an Ajax prefilter to prevent
|
||||||
|
// auto-executing script tags from untrusted domains. This is similar to the
|
||||||
|
// fix that is built in to jQuery 3.0 and higher.
|
||||||
|
$.ajaxPrefilter(function (s) {
|
||||||
|
if (s.crossDomain) {
|
||||||
|
s.contents.script = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if ($.httpData) {
|
||||||
|
// For the version of jQuery that ships with Drupal core, override
|
||||||
|
// jQuery.httpData to prevent auto-detecting "script" data types from
|
||||||
|
// untrusted domains.
|
||||||
|
var jquery_httpData = $.httpData;
|
||||||
|
$.httpData = function (xhr, type, s) {
|
||||||
|
// @todo Consider backporting code from newer jQuery versions to check for
|
||||||
|
// a cross-domain request here, rather than using Drupal.urlIsLocal() to
|
||||||
|
// block scripts from all URLs that are not on the same site.
|
||||||
|
if (!type && !Drupal.urlIsLocal(s.url)) {
|
||||||
|
var content_type = xhr.getResponseHeader('content-type') || '';
|
||||||
|
if (content_type.indexOf('javascript') >= 0) {
|
||||||
|
// Default to a safe data type.
|
||||||
|
type = 'text';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jquery_httpData.call(this, xhr, type, s);
|
||||||
|
};
|
||||||
|
$.httpData.prototype = jquery_httpData.prototype;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach all registered behaviors to a page element.
|
* Attach all registered behaviors to a page element.
|
||||||
*
|
*
|
||||||
@@ -137,7 +173,7 @@ Drupal.detachBehaviors = function (context, settings, trigger) {
|
|||||||
*/
|
*/
|
||||||
Drupal.checkPlain = function (str) {
|
Drupal.checkPlain = function (str) {
|
||||||
var character, regex,
|
var character, regex,
|
||||||
replace = { '&': '&', '"': '"', '<': '<', '>': '>' };
|
replace = { '&': '&', "'": ''', '"': '"', '<': '<', '>': '>' };
|
||||||
str = String(str);
|
str = String(str);
|
||||||
for (character in replace) {
|
for (character in replace) {
|
||||||
if (replace.hasOwnProperty(character)) {
|
if (replace.hasOwnProperty(character)) {
|
||||||
@@ -168,6 +204,7 @@ Drupal.checkPlain = function (str) {
|
|||||||
Drupal.formatString = function(str, args) {
|
Drupal.formatString = function(str, args) {
|
||||||
// Transform arguments before inserting them.
|
// Transform arguments before inserting them.
|
||||||
for (var key in args) {
|
for (var key in args) {
|
||||||
|
if (args.hasOwnProperty(key)) {
|
||||||
switch (key.charAt(0)) {
|
switch (key.charAt(0)) {
|
||||||
// Escaped only.
|
// Escaped only.
|
||||||
case '@':
|
case '@':
|
||||||
@@ -177,14 +214,66 @@ Drupal.formatString = function(str, args) {
|
|||||||
case '!':
|
case '!':
|
||||||
break;
|
break;
|
||||||
// Escaped and placeholder.
|
// Escaped and placeholder.
|
||||||
case '%':
|
|
||||||
default:
|
default:
|
||||||
args[key] = Drupal.theme('placeholder', args[key]);
|
args[key] = Drupal.theme('placeholder', args[key]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
str = str.replace(key, args[key]);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Drupal.stringReplace(str, args, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace substring.
|
||||||
|
*
|
||||||
|
* The longest keys will be tried first. Once a substring has been replaced,
|
||||||
|
* its new value will not be searched again.
|
||||||
|
*
|
||||||
|
* @param {String} str
|
||||||
|
* A string with placeholders.
|
||||||
|
* @param {Object} args
|
||||||
|
* Key-value pairs.
|
||||||
|
* @param {Array|null} keys
|
||||||
|
* Array of keys from the "args". Internal use only.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* Returns the replaced string.
|
||||||
|
*/
|
||||||
|
Drupal.stringReplace = function (str, args, keys) {
|
||||||
|
if (str.length === 0) {
|
||||||
return str;
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the array of keys is not passed then collect the keys from the args.
|
||||||
|
if (!$.isArray(keys)) {
|
||||||
|
keys = [];
|
||||||
|
for (var k in args) {
|
||||||
|
if (args.hasOwnProperty(k)) {
|
||||||
|
keys.push(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order the keys by the character length. The shortest one is the first.
|
||||||
|
keys.sort(function (a, b) { return a.length - b.length; });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys.length === 0) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take next longest one from the end.
|
||||||
|
var key = keys.pop();
|
||||||
|
var fragments = str.split(key);
|
||||||
|
|
||||||
|
if (keys.length) {
|
||||||
|
for (var i = 0; i < fragments.length; i++) {
|
||||||
|
// Process each fragment with a copy of remaining keys.
|
||||||
|
fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragments.join(args[key]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +340,7 @@ Drupal.t = function (str, args, options) {
|
|||||||
* A translated string.
|
* A translated string.
|
||||||
*/
|
*/
|
||||||
Drupal.formatPlural = function (count, singular, plural, args, options) {
|
Drupal.formatPlural = function (count, singular, plural, args, options) {
|
||||||
var args = args || {};
|
args = args || {};
|
||||||
args['@count'] = count;
|
args['@count'] = count;
|
||||||
// Determine the index of the plural form.
|
// Determine the index of the plural form.
|
||||||
var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
|
var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ files[] = aggregator.test
|
|||||||
configure = admin/config/services/aggregator/settings
|
configure = admin/config/services/aggregator/settings
|
||||||
stylesheets[all][] = aggregator.css
|
stylesheets[all][] = aggregator.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -455,6 +455,14 @@ function aggregator_save_category($edit) {
|
|||||||
db_delete('aggregator_category')
|
db_delete('aggregator_category')
|
||||||
->condition('cid', $edit['cid'])
|
->condition('cid', $edit['cid'])
|
||||||
->execute();
|
->execute();
|
||||||
|
// Remove category from feeds.
|
||||||
|
db_delete('aggregator_category_feed')
|
||||||
|
->condition('cid', $edit['cid'])
|
||||||
|
->execute();
|
||||||
|
// Remove category from feed items.
|
||||||
|
db_delete('aggregator_category_item')
|
||||||
|
->condition('cid', $edit['cid'])
|
||||||
|
->execute();
|
||||||
// Make sure there is no active block for this category.
|
// Make sure there is no active block for this category.
|
||||||
if (module_exists('block')) {
|
if (module_exists('block')) {
|
||||||
db_delete('block')
|
db_delete('block')
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a feed and makes sure you can add more than one category to it.
|
* Creates a feed and makes sure you can add/delete categories to it.
|
||||||
*/
|
*/
|
||||||
function testCategorizeFeed() {
|
function testCategorizeFeed() {
|
||||||
|
|
||||||
@@ -448,7 +448,31 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
|
|||||||
// Assert the feed has two categories.
|
// Assert the feed has two categories.
|
||||||
$this->getFeedCategories($db_feed);
|
$this->getFeedCategories($db_feed);
|
||||||
$this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
|
$this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
|
||||||
|
|
||||||
|
// Use aggregator_save_feed() to delete a category.
|
||||||
|
$category = reset($categories);
|
||||||
|
aggregator_save_category(array('cid' => $category->cid));
|
||||||
|
|
||||||
|
// Assert that category is deleted.
|
||||||
|
$db_category = db_query("SELECT COUNT(*) FROM {aggregator_category} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField();
|
||||||
|
$this->assertFalse($db_category, format_string('The category %title has been deleted.', array('%title' => $category->title)));
|
||||||
|
|
||||||
|
// Assert that category has been removed from feed.
|
||||||
|
$categorized_feeds = db_query("SELECT COUNT(*) FROM {aggregator_category_feed} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField();
|
||||||
|
$this->assertFalse($categorized_feeds, format_string('The category %title has been removed from feed %feed_title.', array('%title' => $category->title, '%feed_title' => $feed['title'])));
|
||||||
|
|
||||||
|
// Assert that no broken links (associated with the deleted category)
|
||||||
|
// appear on one of the other category pages.
|
||||||
|
$this->createSampleNodes();
|
||||||
|
$this->drupalGet('admin/config/services/aggregator');
|
||||||
|
$this->clickLink('update items');
|
||||||
|
$categories = $this->getCategories();
|
||||||
|
$category = reset($categories);
|
||||||
|
$this->drupalGet('aggregator/categories/' . $category->cid);
|
||||||
|
global $base_path;
|
||||||
|
$this->assertNoRaw('<a href="' . $base_path . 'aggregator/categories/"></a>,');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -685,9 +709,21 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete category from feed items when category is deleted.
|
||||||
|
$cid = reset($feed->categories);
|
||||||
|
$categories = $this->getCategories();
|
||||||
|
$category_title = $categories[$cid]->title;
|
||||||
|
|
||||||
|
// Delete category.
|
||||||
|
aggregator_save_category(array('cid' => $cid));
|
||||||
|
|
||||||
|
// Assert category has been removed from feed items.
|
||||||
|
$categorized_count = db_query("SELECT COUNT(*) FROM {aggregator_category_item} WHERE cid = :cid", array(':cid' => $cid))->fetchField();
|
||||||
|
$this->assertFalse($categorized_count, format_string('The category %title has been removed from feed items.', array('%title' => $category_title)));
|
||||||
// Delete feed.
|
// Delete feed.
|
||||||
$this->deleteFeed($feed);
|
$this->deleteFeed($feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = block.test
|
files[] = block.test
|
||||||
configure = admin/structure/block
|
configure = admin/structure/block
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -432,23 +432,20 @@ function _block_rehash($theme = NULL) {
|
|||||||
drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
|
drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
|
||||||
foreach ($current_blocks as $module => $module_blocks) {
|
foreach ($current_blocks as $module => $module_blocks) {
|
||||||
foreach ($module_blocks as $delta => $block) {
|
foreach ($module_blocks as $delta => $block) {
|
||||||
if (!isset($block['pages'])) {
|
// Make sure certain attributes are set.
|
||||||
// {block}.pages is type 'text', so it cannot have a
|
$block += array(
|
||||||
// default value, and not null, so we need to provide
|
'pages' => '',
|
||||||
// value if the module did not.
|
'weight' => 0,
|
||||||
$block['pages'] = '';
|
'status' => 0,
|
||||||
}
|
);
|
||||||
// Make sure weight is set.
|
// Check for active blocks in regions that are not available.
|
||||||
if (!isset($block['weight'])) {
|
|
||||||
$block['weight'] = 0;
|
|
||||||
}
|
|
||||||
if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) {
|
if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) {
|
||||||
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning');
|
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning');
|
||||||
// Disabled modules are moved into the BLOCK_REGION_NONE later so no
|
// Disabled modules are moved into the BLOCK_REGION_NONE later so no
|
||||||
// need to move the block to another region.
|
// need to move the block to another region.
|
||||||
$block['status'] = 0;
|
$block['status'] = 0;
|
||||||
}
|
}
|
||||||
// Set region to none if not enabled and make sure status is set.
|
// Set region to none if not enabled.
|
||||||
if (empty($block['status'])) {
|
if (empty($block['status'])) {
|
||||||
$block['status'] = 0;
|
$block['status'] = 0;
|
||||||
$block['region'] = BLOCK_REGION_NONE;
|
$block['region'] = BLOCK_REGION_NONE;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ regions[footer] = Footer
|
|||||||
regions[highlighted] = Highlighted
|
regions[highlighted] = Highlighted
|
||||||
regions[help] = Help
|
regions[help] = Help
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = blog.test
|
files[] = blog.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ files[] = book.test
|
|||||||
configure = admin/content/book/settings
|
configure = admin/content/book/settings
|
||||||
stylesheets[all][] = book.css
|
stylesheets[all][] = book.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = color.test
|
files[] = color.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ files[] = comment.test
|
|||||||
configure = admin/content/comment
|
configure = admin/content/comment
|
||||||
stylesheets[all][] = comment.css
|
stylesheets[all][] = comment.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = contact.test
|
files[] = contact.test
|
||||||
configure = admin/structure/contact
|
configure = admin/structure/contact
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,14 @@ function contact_form_user_profile_form_alter(&$form, &$form_state) {
|
|||||||
* Implements hook_user_presave().
|
* Implements hook_user_presave().
|
||||||
*/
|
*/
|
||||||
function contact_user_presave(&$edit, $account, $category) {
|
function contact_user_presave(&$edit, $account, $category) {
|
||||||
$edit['data']['contact'] = isset($edit['contact']) ? $edit['contact'] : variable_get('contact_default_status', 1);
|
if (isset($edit['contact'])) {
|
||||||
|
// Set new value.
|
||||||
|
$edit['data']['contact'] = $edit['contact'];
|
||||||
|
}
|
||||||
|
elseif (!isset($account->data['contact'])) {
|
||||||
|
// Use default if none has been set.
|
||||||
|
$edit['data']['contact'] = variable_get('contact_default_status', 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -346,6 +346,28 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
|
|||||||
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
||||||
$this->assertResponse(200);
|
$this->assertResponse(200);
|
||||||
|
|
||||||
|
// Test that users can disable their contact form.
|
||||||
|
$this->drupalLogin($this->contact_user);
|
||||||
|
$edit = array('contact' => FALSE);
|
||||||
|
$this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save');
|
||||||
|
$this->drupalLogout();
|
||||||
|
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
||||||
|
$this->assertResponse(403);
|
||||||
|
|
||||||
|
// Test that user's contact status stays disabled when saving.
|
||||||
|
$contact_user_temp = user_load($this->contact_user->uid, TRUE);
|
||||||
|
user_save($contact_user_temp);
|
||||||
|
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
||||||
|
$this->assertResponse(403);
|
||||||
|
|
||||||
|
// Test that users can enable their contact form.
|
||||||
|
$this->drupalLogin($this->contact_user);
|
||||||
|
$edit = array('contact' => TRUE);
|
||||||
|
$this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save');
|
||||||
|
$this->drupalLogout();
|
||||||
|
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
|
||||||
// Revoke the personal contact permission for the anonymous user.
|
// Revoke the personal contact permission for the anonymous user.
|
||||||
user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
|
user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
|
||||||
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
$this->drupalGet('user/' . $this->contact_user->uid . '/contact');
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = contextual.test
|
files[] = contextual.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ files[] = dashboard.test
|
|||||||
dependencies[] = block
|
dependencies[] = block
|
||||||
configure = admin/dashboard/customize
|
configure = admin/dashboard/customize
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = dblog.test
|
files[] = dblog.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ dependencies[] = field_sql_storage
|
|||||||
required = TRUE
|
required = TRUE
|
||||||
stylesheets[all][] = theme/field.css
|
stylesheets[all][] = theme/field.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
files[] = field_sql_storage.test
|
files[] = field_sql_storage.test
|
||||||
required = TRUE
|
required = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
dependencies[] = options
|
dependencies[] = options
|
||||||
files[] = tests/list.test
|
files[] = tests/list.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = number.test
|
files[] = number.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = options.test
|
files[] = options.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dependencies[] = field
|
|||||||
files[] = text.test
|
files[] = text.test
|
||||||
required = TRUE
|
required = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ files[] = field_test.entity.inc
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
* @file field.tpl.php
|
* @file field.tpl.php
|
||||||
* Default template implementation to display the value of a field.
|
* Default template implementation to display the value of a field.
|
||||||
*
|
*
|
||||||
* This file is not used and is here as a starting point for customization only.
|
* This file is not used by Drupal core, which uses theme functions instead for
|
||||||
* @see theme_field()
|
* performance reasons. The markup is the same, though, so if you want to use
|
||||||
|
* template files rather than functions to extend field theming, copy this to
|
||||||
|
* your custom theme. See theme_field() for a discussion of performance.
|
||||||
*
|
*
|
||||||
* Available variables:
|
* Available variables:
|
||||||
* - $items: An array of field values. Use render() to output them.
|
* - $items: An array of field values. Use render() to output them.
|
||||||
@@ -45,7 +47,7 @@
|
|||||||
*/
|
*/
|
||||||
?>
|
?>
|
||||||
<!--
|
<!--
|
||||||
THIS FILE IS NOT USED AND IS HERE AS A STARTING POINT FOR CUSTOMIZATION ONLY.
|
This file is not used by Drupal core, which uses theme functions instead.
|
||||||
See http://api.drupal.org/api/function/theme_field/7 for details.
|
See http://api.drupal.org/api/function/theme_field/7 for details.
|
||||||
After copying this file to your theme's folder and customizing it, remove this
|
After copying this file to your theme's folder and customizing it, remove this
|
||||||
HTML comment.
|
HTML comment.
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = field_ui.test
|
files[] = field_ui.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = field
|
dependencies[] = field
|
||||||
files[] = tests/file.test
|
files[] = tests/file.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -140,14 +140,15 @@ function file_file_download($uri, $field_type = 'file') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find out which (if any) fields of this type contain the file.
|
// Find out which (if any) fields of this type contain the file.
|
||||||
$references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type);
|
$references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type, FALSE);
|
||||||
|
|
||||||
// Stop processing if there are no references in order to avoid returning
|
// Stop processing if there are no references in order to avoid returning
|
||||||
// headers for files controlled by other modules. Make an exception for
|
// headers for files controlled by other modules. Make an exception for
|
||||||
// temporary files where the host entity has not yet been saved (for example,
|
// temporary files where the host entity has not yet been saved (for example,
|
||||||
// an image preview on a node/add form) in which case, allow download by the
|
// an image preview on a node/add form) in which case, allow download by the
|
||||||
// file's owner.
|
// file's owner. For anonymous file owners, only the browser session that
|
||||||
if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid)) {
|
// uploaded the file should be granted access.
|
||||||
|
if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid || (!$user->uid && empty($_SESSION['anonymous_allowed_file_ids'][$file->fid])))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ function file_ajax_upload() {
|
|||||||
$form['#prefix'] .= theme('status_messages');
|
$form['#prefix'] .= theme('status_messages');
|
||||||
$output = drupal_render($form);
|
$output = drupal_render($form);
|
||||||
$js = drupal_add_js();
|
$js = drupal_add_js();
|
||||||
$settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
|
$settings = drupal_array_merge_deep_array($js['settings']['data']);
|
||||||
|
|
||||||
$commands[] = ajax_command_replace(NULL, $output, $settings);
|
$commands[] = ajax_command_replace(NULL, $output, $settings);
|
||||||
return array('#type' => 'ajax', '#commands' => $commands);
|
return array('#type' => 'ajax', '#commands' => $commands);
|
||||||
@@ -1066,11 +1067,18 @@ function file_icon_map($file) {
|
|||||||
* @param $field_type
|
* @param $field_type
|
||||||
* (optional) The name of a field type. If given, limits the reference check
|
* (optional) The name of a field type. If given, limits the reference check
|
||||||
* to fields of the given type.
|
* to fields of the given type.
|
||||||
|
* @param $check_access
|
||||||
|
* (optional) A boolean that specifies whether the permissions of the current
|
||||||
|
* user should be checked when retrieving references. If FALSE, all
|
||||||
|
* references to the file are returned. If TRUE, only references from
|
||||||
|
* entities that the current user has access to are returned. Defaults to
|
||||||
|
* TRUE for backwards compatibility reasons, but FALSE is recommended for
|
||||||
|
* most situations.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* An integer value.
|
* An integer value.
|
||||||
*/
|
*/
|
||||||
function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') {
|
function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file', $check_access = TRUE) {
|
||||||
$references = drupal_static(__FUNCTION__, array());
|
$references = drupal_static(__FUNCTION__, array());
|
||||||
$fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields();
|
$fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields();
|
||||||
|
|
||||||
@@ -1081,6 +1089,11 @@ function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISI
|
|||||||
$query
|
$query
|
||||||
->fieldCondition($file_field, 'fid', $file->fid)
|
->fieldCondition($file_field, 'fid', $file->fid)
|
||||||
->age($age);
|
->age($age);
|
||||||
|
if (!$check_access) {
|
||||||
|
// Neutralize the 'entity_field_access' query tag added by
|
||||||
|
// field_sql_storage_field_storage_query().
|
||||||
|
$query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
|
||||||
|
}
|
||||||
$references[$field_name] = $query->execute();
|
$references[$field_name] = $query->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1551,6 +1551,153 @@ class FilePrivateTestCase extends FileFieldTestCase {
|
|||||||
$this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
|
$this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
|
||||||
$this->drupalGet(file_create_url($node_file->uri));
|
$this->drupalGet(file_create_url($node_file->uri));
|
||||||
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
|
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
|
||||||
|
|
||||||
|
// As an anonymous user, create a temporary file with no references and
|
||||||
|
// confirm that only the session that uploaded it may view it.
|
||||||
|
$this->drupalLogout();
|
||||||
|
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array(
|
||||||
|
"create $type_name content",
|
||||||
|
'access content',
|
||||||
|
));
|
||||||
|
$test_file = $this->getTestFile('text');
|
||||||
|
$this->drupalGet('node/add/' . $type_name);
|
||||||
|
$edit = array('files[' . $field_name . '_' . LANGUAGE_NONE . '_0]' => drupal_realpath($test_file->uri));
|
||||||
|
$this->drupalPost(NULL, $edit, t('Upload'));
|
||||||
|
$files = file_load_multiple(array(), array('uid' => 0));
|
||||||
|
$this->assertEqual(1, count($files), 'Loaded one anonymous file.');
|
||||||
|
$file = end($files);
|
||||||
|
$this->assertNotEqual($file->status, FILE_STATUS_PERMANENT, 'File is temporary.');
|
||||||
|
$usage = file_usage_list($file);
|
||||||
|
$this->assertFalse($usage, 'No file usage found.');
|
||||||
|
$file_url = file_create_url($file->uri);
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the temporary file.');
|
||||||
|
// Close the prior connection and remove the session cookie.
|
||||||
|
$this->curlClose();
|
||||||
|
$this->cookies = array();
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Confirmed that another anonymous user cannot access the temporary file.');
|
||||||
|
|
||||||
|
// As an anonymous user, create a permanent file that is referenced by a
|
||||||
|
// published node and confirm that all anonymous users may view it.
|
||||||
|
$test_file = $this->getTestFile('text');
|
||||||
|
$this->drupalGet('node/add/' . $type_name);
|
||||||
|
$edit = array();
|
||||||
|
$edit['title'] = $this->randomName();
|
||||||
|
$edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
|
||||||
|
$this->drupalPost(NULL, $edit, t('Save'));
|
||||||
|
$new_node = $this->drupalGetNodeByTitle($edit['title']);
|
||||||
|
$file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
|
||||||
|
$this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
|
||||||
|
$usage = file_usage_list($file);
|
||||||
|
$this->assertTrue($usage, 'File usage found.');
|
||||||
|
$file_url = file_create_url($file->uri);
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the permanent file that is referenced by a published node.');
|
||||||
|
// Close the prior connection and remove the session cookie.
|
||||||
|
$this->curlClose();
|
||||||
|
$this->cookies = array();
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Confirmed that another anonymous user also has access to the permanent file that is referenced by a published node.');
|
||||||
|
|
||||||
|
// As an anonymous user, create a permanent file that is referenced by an
|
||||||
|
// unpublished node and confirm that no anonymous users may view it (even
|
||||||
|
// the session that uploaded the file) because they cannot view the
|
||||||
|
// unpublished node.
|
||||||
|
$test_file = $this->getTestFile('text');
|
||||||
|
$this->drupalGet('node/add/' . $type_name);
|
||||||
|
$edit = array();
|
||||||
|
$edit['title'] = $this->randomName();
|
||||||
|
$edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
|
||||||
|
$this->drupalPost(NULL, $edit, t('Save'));
|
||||||
|
$new_node = $this->drupalGetNodeByTitle($edit['title']);
|
||||||
|
$new_node->status = NODE_NOT_PUBLISHED;
|
||||||
|
node_save($new_node);
|
||||||
|
$file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
|
||||||
|
$this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
|
||||||
|
$usage = file_usage_list($file);
|
||||||
|
$this->assertTrue($usage, 'File usage found.');
|
||||||
|
$file_url = file_create_url($file->uri);
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Confirmed that the anonymous uploader cannot access the permanent file when it is referenced by an unpublished node.');
|
||||||
|
// Close the prior connection and remove the session cookie.
|
||||||
|
$this->curlClose();
|
||||||
|
$this->cookies = array();
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Confirmed that another anonymous user cannot access the permanent file when it is referenced by an unpublished node.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests file access for private nodes when file download access is granted.
|
||||||
|
*/
|
||||||
|
function testPrivateFileDownloadAccessGranted() {
|
||||||
|
// Tell file_module_test to attempt to grant access to all private files,
|
||||||
|
// and ensure that it is doing so correctly.
|
||||||
|
$test_file = $this->getTestFile('text');
|
||||||
|
$uri = file_unmanaged_move($test_file->uri, 'private://');
|
||||||
|
$file_url = file_create_url($uri);
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Access is not granted to an arbitrary private file by default.');
|
||||||
|
variable_set('file_module_test_grant_download_access', TRUE);
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Access is granted to an arbitrary private file after a module grants access to all private files in hook_file_download().');
|
||||||
|
|
||||||
|
// Create a public node with a file attached.
|
||||||
|
$type_name = 'page';
|
||||||
|
$field_name = strtolower($this->randomName());
|
||||||
|
$this->createFileField($field_name, $type_name, array('uri_scheme' => 'private'));
|
||||||
|
$test_file = $this->getTestFile('text');
|
||||||
|
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => FALSE));
|
||||||
|
$node = node_load($nid, NULL, TRUE);
|
||||||
|
$file_url = file_create_url($node->{$field_name}[LANGUAGE_NONE][0]['uri']);
|
||||||
|
|
||||||
|
// Unpublish the node and ensure that only administrators (not anonymous
|
||||||
|
// users) can access the node and download the file; the expectation is
|
||||||
|
// that the File module's hook_file_download() implementation will deny
|
||||||
|
// access and thereby override the file_module_test module's access grant.
|
||||||
|
$node->status = NODE_NOT_PUBLISHED;
|
||||||
|
node_save($node);
|
||||||
|
$this->drupalLogin($this->admin_user);
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(200, 'Administrator can access the unpublished node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Administrator can download the file attached to the unpublished node.');
|
||||||
|
$this->drupalLogOut();
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(403, 'Anonymous user cannot access the unpublished node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Anonymous user cannot download the file attached to the unpublished node.');
|
||||||
|
|
||||||
|
// Re-publish the node and ensure that the node and file can be accessed by
|
||||||
|
// everyone.
|
||||||
|
$node->status = NODE_PUBLISHED;
|
||||||
|
node_save($node);
|
||||||
|
$this->drupalLogin($this->admin_user);
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(200, 'Administrator can access the published node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Administrator can download the file attached to the published node.');
|
||||||
|
$this->drupalLogOut();
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(200, 'Anonymous user can access the published node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Anonymous user can download the file attached to the published node.');
|
||||||
|
|
||||||
|
// Make the node private via the node access system and test that only
|
||||||
|
// administrators (not anonymous users) can access the node and download
|
||||||
|
// the file.
|
||||||
|
$node->private = TRUE;
|
||||||
|
node_save($node);
|
||||||
|
$this->drupalLogin($this->admin_user);
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(200, 'Administrator can access the private node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(200, 'Administrator can download the file attached to the private node.');
|
||||||
|
$this->drupalLogOut();
|
||||||
|
$this->drupalGet("node/$nid");
|
||||||
|
$this->assertResponse(403, 'Anonymous user cannot access the private node.');
|
||||||
|
$this->drupalGet($file_url);
|
||||||
|
$this->assertResponse(403, 'Anonymous user cannot download the file attached to the private node.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -67,3 +67,18 @@ function file_module_test_form_submit($form, &$form_state) {
|
|||||||
}
|
}
|
||||||
drupal_set_message(t('The file id is %fid.', array('%fid' => $fid)));
|
drupal_set_message(t('The file id is %fid.', array('%fid' => $fid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_file_download().
|
||||||
|
*/
|
||||||
|
function file_module_test_file_download($uri) {
|
||||||
|
if (variable_get('file_module_test_grant_download_access')) {
|
||||||
|
// Mimic what file_get_content_headers() would do if we had a full $file
|
||||||
|
// object to pass to it.
|
||||||
|
return array(
|
||||||
|
'Content-Type' => mime_header_encode(file_get_mimetype($uri)),
|
||||||
|
'Content-Length' => filesize($uri),
|
||||||
|
'Cache-Control' => 'private',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ files[] = filter.test
|
|||||||
required = TRUE
|
required = TRUE
|
||||||
configure = admin/config/content/formats
|
configure = admin/config/content/formats
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ files[] = forum.test
|
|||||||
configure = admin/structure/forum
|
configure = admin/structure/forum
|
||||||
stylesheets[all][] = forum.css
|
stylesheets[all][] = forum.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = help.test
|
files[] = help.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dependencies[] = file
|
|||||||
files[] = image.test
|
files[] = image.test
|
||||||
configure = admin/config/media/image-styles
|
configure = admin/config/media/image-styles
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = image_module_test.module
|
files[] = image_module_test.module
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = locale.test
|
files[] = locale.test
|
||||||
configure = admin/config/regional/language
|
configure = admin/config/regional/language
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -819,7 +819,7 @@ class LocalePluralFormatTest extends DrupalWebTestCase {
|
|||||||
* Additional options to pass to the translation import form.
|
* Additional options to pass to the translation import form.
|
||||||
*/
|
*/
|
||||||
function importPoFile($contents, array $options = array()) {
|
function importPoFile($contents, array $options = array()) {
|
||||||
$name = tempnam('temporary://', "po_") . '.po';
|
$name = drupal_tempnam('temporary://', "po_") . '.po';
|
||||||
file_put_contents($name, $contents);
|
file_put_contents($name, $contents);
|
||||||
$options['files[file]'] = $name;
|
$options['files[file]'] = $name;
|
||||||
$this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
|
$this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
|
||||||
@@ -1113,7 +1113,7 @@ class LocaleImportFunctionalTest extends DrupalWebTestCase {
|
|||||||
* Additional options to pass to the translation import form.
|
* Additional options to pass to the translation import form.
|
||||||
*/
|
*/
|
||||||
function importPoFile($contents, array $options = array()) {
|
function importPoFile($contents, array $options = array()) {
|
||||||
$name = tempnam('temporary://', "po_") . '.po';
|
$name = drupal_tempnam('temporary://', "po_") . '.po';
|
||||||
file_put_contents($name, $contents);
|
file_put_contents($name, $contents);
|
||||||
$options['files[file]'] = $name;
|
$options['files[file]'] = $name;
|
||||||
$this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
|
$this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
|
||||||
@@ -1340,7 +1340,7 @@ class LocaleExportFunctionalTest extends DrupalWebTestCase {
|
|||||||
function testExportTranslation() {
|
function testExportTranslation() {
|
||||||
// First import some known translations.
|
// First import some known translations.
|
||||||
// This will also automatically enable the 'fr' language.
|
// This will also automatically enable the 'fr' language.
|
||||||
$name = tempnam('temporary://', "po_") . '.po';
|
$name = drupal_tempnam('temporary://', "po_") . '.po';
|
||||||
file_put_contents($name, $this->getPoFile());
|
file_put_contents($name, $this->getPoFile());
|
||||||
$this->drupalPost('admin/config/regional/translate/import', array(
|
$this->drupalPost('admin/config/regional/translate/import', array(
|
||||||
'langcode' => 'fr',
|
'langcode' => 'fr',
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = menu.test
|
files[] = menu.test
|
||||||
configure = admin/structure/menu
|
configure = admin/structure/menu
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ required = TRUE
|
|||||||
configure = admin/structure/types
|
configure = admin/structure/types
|
||||||
stylesheets[all][] = node.css
|
stylesheets[all][] = node.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Core
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = openid.test
|
files[] = openid.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = openid
|
dependencies[] = openid
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ package = Core
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
core = 7.x
|
core = 7.x
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = path.test
|
files[] = path.test
|
||||||
configure = admin/config/search/path
|
configure = admin/config/search/path
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = php.test
|
files[] = php.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = poll.test
|
files[] = poll.test
|
||||||
stylesheets[all][] = poll.css
|
stylesheets[all][] = poll.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ configure = admin/config/people/profile
|
|||||||
; See user_system_info_alter().
|
; See user_system_info_alter().
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
files[] = rdf.test
|
files[] = rdf.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
dependencies[] = blog
|
dependencies[] = blog
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ files[] = search.test
|
|||||||
configure = admin/config/search/settings
|
configure = admin/config/search/settings
|
||||||
stylesheets[all][] = search.css
|
stylesheets[all][] = search.css
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
files[] = shortcut.test
|
files[] = shortcut.test
|
||||||
configure = admin/config/user-interface/shortcut
|
configure = admin/config/user-interface/shortcut
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ abstract class DrupalTestCase {
|
|||||||
*/
|
*/
|
||||||
protected $originalFileDirectory = NULL;
|
protected $originalFileDirectory = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL to the verbose output file directory.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $verboseDirectoryUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time limit for the test.
|
* Time limit for the test.
|
||||||
*/
|
*/
|
||||||
@@ -461,8 +468,11 @@ abstract class DrupalTestCase {
|
|||||||
protected function verbose($message) {
|
protected function verbose($message) {
|
||||||
if ($id = simpletest_verbose($message)) {
|
if ($id = simpletest_verbose($message)) {
|
||||||
$class_safe = str_replace('\\', '_', get_class($this));
|
$class_safe = str_replace('\\', '_', get_class($this));
|
||||||
$url = file_create_url($this->originalFileDirectory . '/simpletest/verbose/' . $class_safe . '-' . $id . '.html');
|
$url = $this->verboseDirectoryUrl . '/' . $class_safe . '-' . $id . '.html';
|
||||||
$this->error(l(t('Verbose message'), $url, array('attributes' => array('target' => '_blank'))), 'User notice');
|
// Not using l() to avoid invoking the theme system, so that unit tests
|
||||||
|
// can use verbose() as well.
|
||||||
|
$link = '<a href="' . $url . '" target="_blank">' . t('Verbose message') . '</a>';
|
||||||
|
$this->error($link, 'User notice');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,10 +729,17 @@ class DrupalUnitTestCase extends DrupalTestCase {
|
|||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
global $conf;
|
global $conf, $language;
|
||||||
|
|
||||||
// Store necessary current values before switching to the test environment.
|
// Store necessary current values before switching to the test environment.
|
||||||
$this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
|
$this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
|
||||||
|
$this->verboseDirectoryUrl = file_create_url($this->originalFileDirectory . '/simpletest/verbose');
|
||||||
|
|
||||||
|
// Set up English language.
|
||||||
|
$this->originalLanguage = $language;
|
||||||
|
$this->originalLanguageDefault = variable_get('language_default');
|
||||||
|
unset($conf['language_default']);
|
||||||
|
$language = language_default();
|
||||||
|
|
||||||
// Reset all statics so that test is performed with a clean environment.
|
// Reset all statics so that test is performed with a clean environment.
|
||||||
drupal_static_reset();
|
drupal_static_reset();
|
||||||
@@ -764,7 +781,7 @@ class DrupalUnitTestCase extends DrupalTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
global $conf;
|
global $conf, $language;
|
||||||
|
|
||||||
// Get back to the original connection.
|
// Get back to the original connection.
|
||||||
Database::removeConnection('default');
|
Database::removeConnection('default');
|
||||||
@@ -775,6 +792,12 @@ class DrupalUnitTestCase extends DrupalTestCase {
|
|||||||
if (isset($this->originalModuleList)) {
|
if (isset($this->originalModuleList)) {
|
||||||
module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
|
module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset language.
|
||||||
|
$language = $this->originalLanguage;
|
||||||
|
if ($this->originalLanguageDefault) {
|
||||||
|
$GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1381,6 +1404,7 @@ class DrupalWebTestCase extends DrupalTestCase {
|
|||||||
$this->originalLanguageUrl = $language_url;
|
$this->originalLanguageUrl = $language_url;
|
||||||
$this->originalLanguageDefault = variable_get('language_default');
|
$this->originalLanguageDefault = variable_get('language_default');
|
||||||
$this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
|
$this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
|
||||||
|
$this->verboseDirectoryUrl = file_create_url($this->originalFileDirectory . '/simpletest/verbose');
|
||||||
$this->originalProfile = drupal_get_profile();
|
$this->originalProfile = drupal_get_profile();
|
||||||
$this->originalCleanUrl = variable_get('clean_url', 0);
|
$this->originalCleanUrl = variable_get('clean_url', 0);
|
||||||
$this->originalUser = $user;
|
$this->originalUser = $user;
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ files[] = tests/upgrade/update.trigger.test
|
|||||||
files[] = tests/upgrade/update.field.test
|
files[] = tests/upgrade/update.field.test
|
||||||
files[] = tests/upgrade/update.user.test
|
files[] = tests/upgrade/update.user.test
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class DrupalAlterTestCase extends DrupalWebTestCase {
|
|||||||
class CommonURLUnitTest extends DrupalWebTestCase {
|
class CommonURLUnitTest extends DrupalWebTestCase {
|
||||||
public static function getInfo() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
'name' => 'URL generation tests',
|
'name' => 'URL generation unit tests',
|
||||||
'description' => 'Confirm that url(), drupal_get_query_parameters(), drupal_http_build_query(), and l() work correctly with various input.',
|
'description' => 'Confirm that url(), drupal_get_query_parameters(), drupal_http_build_query(), and l() work correctly with various input.',
|
||||||
'group' => 'System',
|
'group' => 'System',
|
||||||
);
|
);
|
||||||
@@ -169,7 +169,7 @@ class CommonURLUnitTest extends DrupalWebTestCase {
|
|||||||
$this->assertEqual(drupal_http_build_query(array('a' => ' &#//+%20@۞')), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.');
|
$this->assertEqual(drupal_http_build_query(array('a' => ' &#//+%20@۞')), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.');
|
||||||
$this->assertEqual(drupal_http_build_query(array(' &#//+%20@۞' => 'a')), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.');
|
$this->assertEqual(drupal_http_build_query(array(' &#//+%20@۞' => 'a')), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.');
|
||||||
$this->assertEqual(drupal_http_build_query(array('a' => '1', 'b' => '2', 'c' => '3')), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.');
|
$this->assertEqual(drupal_http_build_query(array('a' => '1', 'b' => '2', 'c' => '3')), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.');
|
||||||
$this->assertEqual(drupal_http_build_query(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo')), 'a[b]=2&a[c]=3&d=foo', 'Nested array was properly encoded.');
|
$this->assertEqual(drupal_http_build_query(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo')), 'a%5Bb%5D=2&a%5Bc%5D=3&d=foo', 'Nested array was properly encoded.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,6 +372,38 @@ class CommonURLUnitTest extends DrupalWebTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web tests for URL generation functions.
|
||||||
|
*/
|
||||||
|
class CommonURLWebTest extends DrupalWebTestCase {
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'URL generation web tests',
|
||||||
|
'description' => 'Confirm that URL-generating functions work correctly on specific site paths.',
|
||||||
|
'group' => 'System',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
parent::setUp('common_test');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the url() function on internal paths which mimic external URLs.
|
||||||
|
*/
|
||||||
|
function testInternalPathMimicsExternal() {
|
||||||
|
// Ensure that calling url(current_path()) on "/http://example.com" (an
|
||||||
|
// internal path which mimics an external URL) always links to the internal
|
||||||
|
// path, not the external URL. This helps protect against external URL link
|
||||||
|
// injection vulnerabilities.
|
||||||
|
variable_set('common_test_link_to_current_path', TRUE);
|
||||||
|
$this->drupalGet('/http://example.com');
|
||||||
|
$this->clickLink('link which should point to the current path');
|
||||||
|
$this->assertUrl('/http://example.com');
|
||||||
|
$this->assertText('link which should point to the current path');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests url_is_external().
|
* Tests url_is_external().
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ stylesheets[all][] = common_test.css
|
|||||||
stylesheets[print][] = common_test.print.css
|
stylesheets[print][] = common_test.print.css
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ function common_test_init() {
|
|||||||
if (variable_get('common_test_redirect_current_path', FALSE)) {
|
if (variable_get('common_test_redirect_current_path', FALSE)) {
|
||||||
drupal_goto(current_path());
|
drupal_goto(current_path());
|
||||||
}
|
}
|
||||||
|
if (variable_get('common_test_link_to_current_path', FALSE)) {
|
||||||
|
drupal_set_message(l('link which should point to the current path', current_path()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ core = 7.x
|
|||||||
dependencies[] = entity_cache_test_dependency
|
dependencies[] = entity_cache_test_dependency
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ package = Testing
|
|||||||
version = VERSION
|
version = VERSION
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ version = VERSION
|
|||||||
core = 7.x
|
core = 7.x
|
||||||
hidden = TRUE
|
hidden = TRUE
|
||||||
|
|
||||||
; Information added by Drupal.org packaging script on 2017-02-01
|
; Information added by Drupal.org packaging script on 2018-03-28
|
||||||
version = "7.54"
|
version = "7.58"
|
||||||
project = "drupal"
|
project = "drupal"
|
||||||
datestamp = "1485986921"
|
datestamp = "1522264019"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user