[DATABASE] Always quote identifiers

The code used to operate under the assumption that MariaDB doesn't support
quoting identifiers. Not only is that not exactly true, but MariaDB has
reserved keywords that cannot be used as table or column names unquoted.
This commit is contained in:
Alexei Sorokin
2019-09-11 08:15:16 +03:00
parent b89f1ad7d8
commit 5b797328f2
18 changed files with 1335 additions and 1191 deletions

View File

@@ -1,23 +1,20 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
if (!defined('GNUSOCIAL')) { exit(1); }
defined('GNUSOCIAL') || die();
/**
* Table Definition for file_redirection
@@ -59,12 +56,13 @@ class File_redirection extends Managed_DataObject
);
}
static public function getByUrl($url)
public static function getByUrl($url)
{
return self::getByPK(array('urlhash' => File::hashurl($url)));
}
static function _commonHttp($url, $redirs) {
public static function _commonHttp($url, $redirs)
{
$request = new HTTPClient($url);
$request->setConfig(array(
'connect_timeout' => 10, // # seconds to wait
@@ -96,10 +94,13 @@ class File_redirection extends Managed_DataObject
* size (optional): byte size from Content-Length header
* time (optional): timestamp from Last-Modified header
*/
static function lookupWhere($short_url, $redirs = 10, $protected = false) {
if ($redirs < 0) return false;
public static function lookupWhere($short_url, $redirs = 10, $protected = false)
{
if ($redirs < 0) {
return false;
}
if(strpos($short_url,'://') === false){
if (strpos($short_url, '://') === false) {
return $short_url;
}
try {
@@ -128,13 +129,13 @@ class File_redirection extends Managed_DataObject
common_log(LOG_ERR, "Error while following redirects for $short_url: " . $e->getMessage());
return $short_url;
}
// if last url after all redirections is protected,
// use the url before it in the redirection chain
// if last url after all redirections is protected,
// use the url before it in the redirection chain
if ($response->getRedirectCount() && File::isProtected($response->getEffectiveUrl())) {
$return_url = $response->redirUrls[$response->getRedirectCount()-1];
$return_url = $response->redirUrls[$response->getRedirectCount() - 1];
} else {
$return_url = $response->getEffectiveUrl();
$return_url = $response->getEffectiveUrl();
}
$ret = array('code' => $response->getStatus()
@@ -142,12 +143,20 @@ class File_redirection extends Managed_DataObject
, 'url' => $return_url);
$type = $response->getHeader('Content-Type');
if ($type) $ret['type'] = $type;
if ($protected) $ret['protected'] = true;
if ($type) {
$ret['type'] = $type;
}
if ($protected) {
$ret['protected'] = true;
}
$size = $response->getHeader('Content-Length'); // @fixme bytes?
if ($size) $ret['size'] = $size;
if ($size) {
$ret['size'] = $size;
}
$time = $response->getHeader('Last-Modified');
if ($time) $ret['time'] = strtotime($time);
if ($time) {
$ret['time'] = strtotime($time);
}
return $ret;
}
@@ -164,7 +173,8 @@ class File_redirection extends Managed_DataObject
* @param boolean $discover true to attempt dereferencing the redirect if we don't know it already
* @return File_redirection
*/
static function where($in_url, $discover=true) {
public static function where($in_url, $discover = true)
{
$redir = new File_redirection();
$redir->url = $in_url;
$redir->urlhash = File::hashurl($redir->url);
@@ -179,14 +189,16 @@ class File_redirection extends Managed_DataObject
$r->redir_url = $f->url;
} catch (NoResultException $e) {
// Invalid entry, delete and run again
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and and trying again...");
common_log(
LOG_ERR,
'Could not find File with id=' . $r->file_id . ' referenced in File_redirection, deleting File redirection entry and and trying again...'
);
$r->delete();
return self::where($in_url);
return self::where($in_url);
}
// File_redirecion and File record found, return both
return $r;
} catch (NoResultException $e) {
// File_redirecion record not found, but this might be a direct link to a file
try {
@@ -194,15 +206,15 @@ class File_redirection extends Managed_DataObject
$redir->file_id = $f->id;
$redir->file = $f;
return $redir;
} catch (NoResultException $e) {
} catch (NoResultException $e) {
// nope, this was not a direct link to a file either, let's keep going
}
}
if ($discover) {
// try to follow redirects and get the final url
if ($discover) {
// try to follow redirects and get the final url
$redir_info = File_redirection::lookupWhere($in_url);
if(is_string($redir_info)) {
if (is_string($redir_info)) {
$redir_info = array('url' => $redir_info);
}
@@ -212,29 +224,32 @@ class File_redirection extends Managed_DataObject
try {
$r = File_redirection::getByUrl($redir_info['url']);
$f = File::getKV('id',$r->file_id);
$f = File::getKV('id', $r->file_id);
if($f instanceof File) {
if ($f instanceof File) {
$redir->file = $f;
$redir->redir_url = $f->url;
$redir->redir_url = $f->url;
} else {
// Invalid entry in File_redirection, delete and run again
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File_redirection entry and trying again...");
common_log(
LOG_ERR,
'Could not find File with id=' . $r->file_id . ' referenced in File_redirection, deleting File_redirection entry and trying again...'
);
$r->delete();
return self::where($in_url);
return self::where($in_url);
}
} catch (NoResultException $e) {
// save the file now when we know that we don't have it in File_redirection
try {
$redir->file = File::saveNew($redir_info,$redir_info['url']);
$redir->file = File::saveNew($redir_info, $redir_info['url']);
} catch (ServerException $e) {
common_log(LOG_ERR, $e);
}
}
}
// If this is a redirection and we have a file to redirect to, save it
// (if it doesn't exist in File_redirection already)
if($redir->file instanceof File && $redir_info['url'] != $in_url) {
// (if it doesn't exist in File_redirection already)
if ($redir->file instanceof File && $redir_info['url'] != $in_url) {
try {
$file_redir = File_redirection::getByUrl($in_url);
} catch (NoResultException $e) {
@@ -243,12 +258,12 @@ class File_redirection extends Managed_DataObject
$file_redir->url = $in_url;
$file_redir->file_id = $redir->file->getID();
$file_redir->insert();
$file_redir->redir_url = $redir->file->url;
}
$file_redir->redir_url = $redir->file->url;
}
$file_redir->file = $redir->file;
return $file_redir;
}
$file_redir->file = $redir->file;
return $file_redir;
}
}
return $redir;
@@ -268,7 +283,7 @@ class File_redirection extends Managed_DataObject
* @param User $user whose shortening options to use; defaults to the current web session user
* @return string
*/
static function makeShort($long_url, $user=null)
public static function makeShort($long_url, $user = null)
{
$canon = File_redirection::_canonUrl($long_url);
@@ -293,7 +308,7 @@ class File_redirection extends Managed_DataObject
* @return string
*/
static function forceShort($long_url, $user)
public static function forceShort($long_url, $user)
{
$canon = File_redirection::_canonUrl($long_url);
@@ -303,7 +318,8 @@ class File_redirection extends Managed_DataObject
return !empty($short_url) ? $short_url : $long_url;
}
static function _userMakeShort($long_url, User $user=null, $force = false) {
public static function _userMakeShort($long_url, User $user = null, $force = false)
{
$short_url = common_shorten_url($long_url, $user, $force);
if (!empty($short_url) && $short_url != $long_url) {
$short_url = (string)$short_url;
@@ -343,8 +359,11 @@ class File_redirection extends Managed_DataObject
* @param string $default_scheme if given a bare link; defaults to 'http://'
* @return string
*/
static function _canonUrl($in_url, $default_scheme = 'http://') {
if (empty($in_url)) return false;
public static function _canonUrl($in_url, $default_scheme = 'http://')
{
if (empty($in_url)) {
return false;
}
$out_url = $in_url;
$p = parse_url($out_url);
if (empty($p['host']) || empty($p['scheme'])) {
@@ -377,13 +396,17 @@ class File_redirection extends Managed_DataObject
default:
$out_url = $default_scheme . ltrim($out_url, '/');
$p = parse_url($out_url);
if (empty($p['scheme'])) return false;
if (empty($p['scheme'])) {
return false;
}
break;
}
}
if (('ftp' == $p['scheme']) || ('ftps' == $p['scheme']) || ('http' == $p['scheme']) || ('https' == $p['scheme'])) {
if (empty($p['host'])) return false;
if (empty($p['host'])) {
return false;
}
if (empty($p['path'])) {
$out_url .= '/';
}
@@ -392,7 +415,8 @@ class File_redirection extends Managed_DataObject
return $out_url;
}
static function saveNew($data, $file_id, $url) {
public static function saveNew($data, $file_id, $url)
{
$file_redir = new File_redirection;
$file_redir->urlhash = File::hashurl($url);
$file_redir->url = $url;
@@ -402,7 +426,7 @@ class File_redirection extends Managed_DataObject
$file_redir->insert();
}
static public function beforeSchemaUpdate()
public static function beforeSchemaUpdate()
{
$table = strtolower(get_called_class());
$schema = Schema::get();
@@ -416,16 +440,16 @@ class File_redirection extends Managed_DataObject
echo "\nFound old $table table, upgrading it to contain 'urlhash' field...";
// We have to create a urlhash that is _not_ the primary key,
// transfer data and THEN run checkSchema
$schemadef['fields']['urlhash'] = array (
'type' => 'varchar',
'length' => 64,
'not null' => true,
'description' => 'sha256 hash of the URL',
);
$schemadef['fields']['url'] = array (
'type' => 'text',
'description' => 'short URL (or any other kind of redirect) for file (id)',
);
$schemadef['fields']['urlhash'] = [
'type' => 'varchar',
'length' => 64,
'not null' => true,
'description' => 'sha256 hash of the URL',
];
$schemadef['fields']['url'] = [
'type' => 'text',
'description' => 'short URL (or any other kind of redirect) for file (id)',
];
unset($schemadef['primary key']);
$schema->ensureTable($table, $schemadef);
echo "DONE.\n";
@@ -435,16 +459,18 @@ class File_redirection extends Managed_DataObject
// urlhash is hash('sha256', $url) in the File table
echo "Updating urlhash fields in $table table...";
// Maybe very MySQL specific :(
$tablefix->query(sprintf('UPDATE %1$s SET %2$s=%3$s;',
$schema->quoteIdentifier($table),
'urlhash',
// The line below is "result of sha256 on column `url`"
'SHA2(url, 256)'));
$tablefix->query(sprintf(
'UPDATE %1$s SET urlhash = %2$s;',
$tablefix->escapedTableName(),
// The line below is "result of sha256 on column `url`"
'sha2(url, 256)'
));
echo "DONE.\n";
echo "Resuming core schema upgrade...";
}
public function getFile() {
public function getFile()
{
if (!$this->file instanceof File) {
$this->file = File::getByID($this->file_id);
}