Smarter keyword sanitization (#2682)
* Smarter keyword sanitizing, based on context * Deprecate yourls_sanitize_string() Fixes #2646. Fixes #2128.
This commit is contained in:
parent
19da8de9ec
commit
c1517f1f84
@ -351,7 +351,7 @@ $found_rows = false;
|
||||
if( $url_results ) {
|
||||
$found_rows = true;
|
||||
foreach( $url_results as $url_result ) {
|
||||
$keyword = yourls_sanitize_string( $url_result->keyword );
|
||||
$keyword = yourls_sanitize_keyword($url_result->keyword);
|
||||
$timestamp = strtotime( $url_result->timestamp );
|
||||
$url = stripslashes( $url_result->url );
|
||||
$ip = $url_result->ip;
|
||||
|
@ -192,7 +192,7 @@ function yourls_api_db_stats() {
|
||||
*/
|
||||
function yourls_api_url_stats( $shorturl ) {
|
||||
$keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc'
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
|
||||
$return = yourls_get_keyword_stats( $keyword );
|
||||
$return['simple'] = 'Need either XML or JSON format for stats';
|
||||
@ -205,7 +205,7 @@ function yourls_api_url_stats( $shorturl ) {
|
||||
*/
|
||||
function yourls_api_expand( $shorturl ) {
|
||||
$keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc'
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
|
||||
$longurl = yourls_get_keyword_longurl( $keyword );
|
||||
|
||||
|
@ -9,6 +9,17 @@
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
/**
|
||||
* The original string sanitize function
|
||||
*
|
||||
* @deprecated 1.7.10
|
||||
*
|
||||
*/
|
||||
function yourls_sanitize_string( $string, $restrict_to_shorturl_charset = false ) {
|
||||
yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_sanitize_keyword' );
|
||||
return yourls_sanitize_keyword( $string, $restrict_to_shorturl_charset );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return favicon URL (either default or custom)
|
||||
*
|
||||
|
@ -51,23 +51,28 @@ function yourls_string2htmlid( $string ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure a link keyword (ie "1fv" as in "http://sho.rt/1fv") is valid.
|
||||
* Make sure a link keyword (ie "1fv" as in "http://sho.rt/1fv") is acceptable
|
||||
*
|
||||
* If we are ADDING or EDITING a short URL, the keyword must comply to the short URL charset: every
|
||||
* character that doesn't belong to it will be removed.
|
||||
* But otherwise we must have a more conservative approach: we could be checking for a keyword that
|
||||
* was once valid but now the short URL charset. In such a case, we are treating the keyword for what
|
||||
* it is: just a part of a URL, hence sanitize it as a URL.
|
||||
*
|
||||
* @param string $keyword short URL keyword
|
||||
* @param bool $restrict_to_shorturl_charset Optional, default false. True if we want the keyword to comply to short URL charset
|
||||
* @return string The sanitized keyword
|
||||
*/
|
||||
function yourls_sanitize_string( $string ) {
|
||||
function yourls_sanitize_keyword( $keyword, $restrict_to_shorturl_charset = false ) {
|
||||
if( $restrict_to_shorturl_charset === true ) {
|
||||
// make a regexp pattern with the shorturl charset, and remove everything but this
|
||||
$pattern = yourls_make_regexp_pattern( yourls_get_shorturl_charset() );
|
||||
$valid = (string) substr( preg_replace( '![^'.$pattern.']!', '', $string ), 0, 199 );
|
||||
$valid = (string) substr( preg_replace( '![^'.$pattern.']!', '', $keyword ), 0, 199 );
|
||||
} else {
|
||||
$valid = yourls_sanitize_url( $keyword );
|
||||
}
|
||||
|
||||
return yourls_apply_filter( 'sanitize_string', $valid, $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias function. I was always getting it wrong.
|
||||
*
|
||||
*/
|
||||
function yourls_sanitize_keyword( $keyword ) {
|
||||
return yourls_sanitize_string( $keyword );
|
||||
return yourls_apply_filter( 'sanitize_string', $valid, $keyword, $restrict_to_shorturl_charset );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -484,12 +484,13 @@ function yourls_die( $message = '', $title = '', $header_code = 200 ) {
|
||||
* @return string HTML of the edit row
|
||||
*/
|
||||
function yourls_table_edit_row( $keyword ) {
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$id = yourls_string2htmlid( $keyword ); // used as HTML #id
|
||||
$url = yourls_get_keyword_longurl( $keyword );
|
||||
$title = htmlspecialchars( yourls_get_keyword_title( $keyword ) );
|
||||
$safe_url = yourls_esc_attr( rawurldecode( $url ) );
|
||||
$safe_title = yourls_esc_attr( $title );
|
||||
$safe_keyword = yourls_esc_attr( $keyword );
|
||||
|
||||
// Make strings sprintf() safe: '%' -> '%%'
|
||||
$safe_url = str_replace( '%', '%%', $safe_url );
|
||||
@ -501,7 +502,7 @@ function yourls_table_edit_row( $keyword ) {
|
||||
|
||||
if( $url ) {
|
||||
$return = <<<RETURN
|
||||
<tr id="edit-$id" class="edit-row"><td colspan="5" class="edit-row"><strong>%s</strong>:<input type="text" id="edit-url-$id" name="edit-url-$id" value="$safe_url" class="text" size="70" /><br/><strong>%s</strong>: $www<input type="text" id="edit-keyword-$id" name="edit-keyword-$id" value="$keyword" class="text" size="10" /><br/><strong>%s</strong>: <input type="text" id="edit-title-$id" name="edit-title-$id" value="$safe_title" class="text" size="60" /></td><td colspan="1"><input type="button" id="edit-submit-$id" name="edit-submit-$id" value="%s" title="%s" class="button" onclick="edit_link_save('$id');" /> <input type="button" id="edit-close-$id" name="edit-close-$id" value="%s" title="%s" class="button" onclick="edit_link_hide('$id');" /><input type="hidden" id="old_keyword_$id" value="$keyword"/><input type="hidden" id="nonce_$id" value="$nonce"/></td></tr>
|
||||
<tr id="edit-$id" class="edit-row"><td colspan="5" class="edit-row"><strong>%s</strong>:<input type="text" id="edit-url-$id" name="edit-url-$id" value="$safe_url" class="text" size="70" /><br/><strong>%s</strong>: $www<input type="text" id="edit-keyword-$id" name="edit-keyword-$id" value="$safe_keyword" class="text" size="10" /><br/><strong>%s</strong>: <input type="text" id="edit-title-$id" name="edit-title-$id" value="$safe_title" class="text" size="60" /></td><td colspan="1"><input type="button" id="edit-submit-$id" name="edit-submit-$id" value="%s" title="%s" class="button" onclick="edit_link_save('$id');" /> <input type="button" id="edit-close-$id" name="edit-close-$id" value="%s" title="%s" class="button" onclick="edit_link_hide('$id');" /><input type="hidden" id="old_keyword_$id" value="$safe_keyword"/><input type="hidden" id="nonce_$id" value="$nonce"/></td></tr>
|
||||
RETURN;
|
||||
$return = sprintf( $return, yourls__( 'Long URL' ), yourls__( 'Short URL' ), yourls__( 'Title' ), yourls__( 'Save' ), yourls__( 'Save new values' ), yourls__( 'Cancel' ), yourls__( 'Cancel editing' ) );
|
||||
} else {
|
||||
@ -519,7 +520,7 @@ RETURN;
|
||||
* @return string HTML of the edit row
|
||||
*/
|
||||
function yourls_table_add_row( $keyword, $url, $title = '', $ip, $clicks, $timestamp ) {
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$id = yourls_string2htmlid( $keyword ); // used as HTML #id
|
||||
$shorturl = yourls_link( $keyword );
|
||||
|
||||
@ -621,13 +622,8 @@ function yourls_table_add_row( $keyword, $url, $title = '', $ip, $clicks, $times
|
||||
// Row cells: the HTML. Replace every %stuff% in 'template' with 'stuff' value.
|
||||
$row = "<tr id=\"id-$id\">";
|
||||
foreach( $cells as $cell_id => $elements ) {
|
||||
$callback = new yourls_table_add_row_callback( $elements );
|
||||
$row .= sprintf( '<td class="%s" id="%s">', $cell_id, $cell_id . '-' . $id );
|
||||
$row .= preg_replace_callback( '/%([^%]+)?%/', array( $callback, 'callback' ), $elements['template'] );
|
||||
// For the record, in PHP 5.3+ we don't need to introduce a class in order to pass additional parameters
|
||||
// to the callback function. Instead, we would have used the 'use' keyword :
|
||||
// $row .= preg_replace_callback( '/%([^%]+)?%/', function( $match ) use ( $elements ) { return $elements[ $match[1] ]; }, $elements['template'] );
|
||||
|
||||
$row .= preg_replace_callback( '/%([^%]+)?%/', function( $match ) use ( $elements ) { return $elements[ $match[1] ]; }, $elements['template'] );
|
||||
$row .= '</td>';
|
||||
}
|
||||
$row .= "</tr>";
|
||||
@ -636,26 +632,6 @@ function yourls_table_add_row( $keyword, $url, $title = '', $ip, $clicks, $times
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback class for yourls_table_add_row
|
||||
*
|
||||
* See comment about PHP 5.3+ in yourls_table_add_row()
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
class yourls_table_add_row_callback {
|
||||
private $elements;
|
||||
|
||||
function __construct($elements) {
|
||||
$this->elements = $elements;
|
||||
}
|
||||
|
||||
function callback( $matches ) {
|
||||
return $this->elements[ $matches[1] ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Echo the main table head
|
||||
*
|
||||
@ -870,12 +846,12 @@ HTML;
|
||||
* @param $page PHP file to display
|
||||
*/
|
||||
function yourls_page( $page ) {
|
||||
$include = YOURLS_PAGEDIR . "/$page.php";
|
||||
if( !file_exists( $include ) ) {
|
||||
if( !yourls_is_page($page)) {
|
||||
yourls_die( yourls_s('Page "%1$s" not found', $page), yourls__('Not found'), 404 );
|
||||
}
|
||||
|
||||
yourls_do_action( 'pre_page', $page );
|
||||
include_once( $include );
|
||||
include_once( YOURLS_PAGEDIR . "/$page.php" );
|
||||
yourls_do_action( 'post_page', $page );
|
||||
}
|
||||
|
||||
|
@ -121,20 +121,29 @@ function yourls_remove_query_arg( $key, $query = false ) {
|
||||
/**
|
||||
* Converts keyword into short link (prepend with YOURLS base URL)
|
||||
*
|
||||
* This function does not check for a valid keyword
|
||||
*
|
||||
*/
|
||||
function yourls_link( $keyword = '' ) {
|
||||
$link = yourls_get_yourls_site() . '/' . yourls_sanitize_keyword( $keyword );
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$link = yourls_get_yourls_site() . '/' . $keyword;
|
||||
return yourls_apply_filter( 'yourls_link', $link, $keyword );
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts keyword into stat link (prepend with YOURLS base URL, append +)
|
||||
*
|
||||
* This function does not make sure the keyword matches an actual short URL
|
||||
*
|
||||
*/
|
||||
function yourls_statlink( $keyword = '' ) {
|
||||
$link = yourls_get_yourls_site() . '/' . yourls_sanitize_keyword( $keyword ) . '+';
|
||||
if( yourls_is_ssl() )
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$link = yourls_get_yourls_site() . '/' . $keyword . '+';
|
||||
|
||||
if( yourls_is_ssl() ) {
|
||||
$link = yourls_set_url_scheme( $link, 'https' );
|
||||
}
|
||||
|
||||
return yourls_apply_filter( 'yourls_statlink', $link, $keyword );
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,9 @@ function yourls_add_new_link( $url, $keyword = '', $title = '' ) {
|
||||
|
||||
yourls_do_action( 'add_new_link_custom_keyword', $url, $keyword, $title );
|
||||
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword, true );
|
||||
$keyword = yourls_apply_filter( 'custom_keyword', $keyword, $url, $title );
|
||||
|
||||
if ( !yourls_keyword_is_free( $keyword ) ) {
|
||||
// This shorturl either reserved or taken already
|
||||
$return['status'] = 'fail';
|
||||
@ -187,7 +188,7 @@ function yourls_is_shorturl( $shorturl ) {
|
||||
}
|
||||
|
||||
// Check if it's a valid && used keyword
|
||||
if( $keyword && $keyword == yourls_sanitize_string( $keyword ) && yourls_keyword_is_taken( $keyword ) ) {
|
||||
if( $keyword && $keyword == yourls_sanitize_keyword( $keyword ) && yourls_keyword_is_taken( $keyword ) ) {
|
||||
$is_short = true;
|
||||
}
|
||||
|
||||
@ -206,7 +207,7 @@ function yourls_keyword_is_reserved( $keyword ) {
|
||||
$reserved = false;
|
||||
|
||||
if ( in_array( $keyword, $yourls_reserved_URL)
|
||||
or file_exists( YOURLS_PAGEDIR ."/$keyword.php" )
|
||||
or yourls_is_page($keyword)
|
||||
or is_dir( YOURLS_ABSPATH ."/$keyword" )
|
||||
)
|
||||
$reserved = true;
|
||||
@ -227,7 +228,7 @@ function yourls_delete_link_by_keyword( $keyword ) {
|
||||
global $ydb;
|
||||
|
||||
$table = YOURLS_DB_TABLE_URL;
|
||||
$keyword = yourls_sanitize_string($keyword);
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$delete = $ydb->fetchAffected("DELETE FROM `$table` WHERE `keyword` = :keyword", array('keyword' => $keyword));
|
||||
yourls_do_action( 'delete_link', $keyword, $delete );
|
||||
return $delete;
|
||||
@ -302,9 +303,9 @@ function yourls_edit_link( $url, $keyword, $newkeyword='', $title='' ) {
|
||||
|
||||
$table = YOURLS_DB_TABLE_URL;
|
||||
$url = yourls_sanitize_url($url);
|
||||
$keyword = yourls_sanitize_string($keyword);
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$title = yourls_sanitize_title($title);
|
||||
$newkeyword = yourls_sanitize_string($newkeyword);
|
||||
$newkeyword = yourls_sanitize_keyword($newkeyword, true);
|
||||
$strip_url = stripslashes( $url );
|
||||
$strip_title = stripslashes( $title );
|
||||
|
||||
@ -376,24 +377,45 @@ function yourls_edit_link_title( $keyword, $title ) {
|
||||
return $update;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if keyword id is free (ie not already taken, and not reserved). Return bool.
|
||||
*
|
||||
* @param string $keyword short URL keyword
|
||||
* @return bool true if keyword is taken (ie there is a short URL for it), false otherwise
|
||||
*/
|
||||
function yourls_keyword_is_free( $keyword ) {
|
||||
$free = true;
|
||||
if ( yourls_keyword_is_reserved( $keyword ) or yourls_keyword_is_taken( $keyword ) )
|
||||
if ( yourls_keyword_is_reserved( $keyword ) or yourls_keyword_is_taken( $keyword, false ) ) {
|
||||
$free = false;
|
||||
}
|
||||
|
||||
return yourls_apply_filter( 'keyword_is_free', $free, $keyword );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a keyword matches a "page"
|
||||
*
|
||||
* @see https://github.com/YOURLS/YOURLS/wiki/Pages
|
||||
* @since 1.7.10
|
||||
* @param string $keyword Short URL $keyword
|
||||
* @return bool true if is page, false otherwise
|
||||
*/
|
||||
function yourls_is_page($keyword) {
|
||||
return yourls_apply_filter( 'is_page', file_exists( YOURLS_PAGEDIR . "/$keyword.php" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a keyword is taken (ie there is already a short URL with this id). Return bool.
|
||||
*
|
||||
*/
|
||||
function yourls_keyword_is_taken( $keyword ) {
|
||||
/**
|
||||
* Check if a keyword is taken (ie there is already a short URL with this id). Return bool.
|
||||
*
|
||||
* @param string $keyword short URL keyword
|
||||
* @param bool $use_cache optional, default true: do we want to use what is cached in memory, if any, or force a new SQL query
|
||||
* @return bool true if keyword is taken (ie there is a short URL for it), false otherwise
|
||||
*/
|
||||
function yourls_keyword_is_taken( $keyword, $use_cache = true ) {
|
||||
|
||||
// Allow plugins to short-circuit the whole function
|
||||
$pre = yourls_apply_filter( 'shunt_keyword_is_taken', false, $keyword );
|
||||
@ -401,13 +423,13 @@ function yourls_keyword_is_taken( $keyword ) {
|
||||
return $pre;
|
||||
|
||||
global $ydb;
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
$taken = false;
|
||||
$table = YOURLS_DB_TABLE_URL;
|
||||
|
||||
$already_exists = $ydb->fetchValue("SELECT COUNT(`keyword`) FROM `$table` WHERE `keyword` = :keyword;", array('keyword' => $keyword));
|
||||
if ( $already_exists )
|
||||
// To check if a keyword is already associated with a short URL, we fetch all info matching that keyword. This
|
||||
// will save a query in case of a redirection in yourls-go.php because info will be cached
|
||||
if ( yourls_get_keyword_infos($keyword, $use_cache) ) {
|
||||
$taken = true;
|
||||
}
|
||||
|
||||
return yourls_apply_filter( 'keyword_is_taken', $taken, $keyword );
|
||||
}
|
||||
@ -426,7 +448,7 @@ function yourls_keyword_is_taken( $keyword ) {
|
||||
*/
|
||||
function yourls_get_keyword_infos( $keyword, $use_cache = true ) {
|
||||
global $ydb;
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
|
||||
yourls_do_action( 'pre_get_keyword', $keyword, $use_cache );
|
||||
|
||||
@ -462,7 +484,7 @@ function yourls_get_keyword_info( $keyword, $field, $notfound = false ) {
|
||||
if ( false !== $pre )
|
||||
return $pre;
|
||||
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
$infos = yourls_get_keyword_infos( $keyword );
|
||||
|
||||
$return = $notfound;
|
||||
|
@ -91,7 +91,7 @@ function yourls_update_clicks( $keyword, $clicks = false ) {
|
||||
return $pre;
|
||||
|
||||
global $ydb;
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
$table = YOURLS_DB_TABLE_URL;
|
||||
if ( $clicks !== false && is_int( $clicks ) && $clicks >= 0 )
|
||||
$update = $ydb->fetchAffected( "UPDATE `$table` SET `clicks` = :clicks WHERE `keyword` = :keyword", [ 'clicks' => $clicks, 'keyword' => $keyword ] );
|
||||
@ -416,7 +416,7 @@ function yourls_log_redirect( $keyword ) {
|
||||
$ip = yourls_get_IP();
|
||||
$binds = [
|
||||
'now' => date( 'Y-m-d H:i:s' ),
|
||||
'keyword' => yourls_sanitize_string($keyword),
|
||||
'keyword' => yourls_sanitize_keyword($keyword),
|
||||
'referrer' => substr( yourls_get_referrer(), 0, 200 ),
|
||||
'ua' => substr(yourls_get_user_agent(), 0, 255),
|
||||
'ip' => $ip,
|
||||
@ -910,6 +910,8 @@ function yourls_get_request($yourls_site = false, $uri = false) {
|
||||
$request = current( explode( '?', $request ) );
|
||||
}
|
||||
|
||||
$request = yourls_sanitize_url( $request );
|
||||
|
||||
return (string)yourls_apply_filter( 'get_request', $request );
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ class Format_General extends PHPUnit_Framework_TestCase {
|
||||
From: http://stackoverflow.com/a/12941133/36850
|
||||
Cool to know :)
|
||||
|
||||
We're testing it as used in yourls_sanitize_string()
|
||||
We're testing it as used in yourls_sanitize_keyword()
|
||||
TODO: more random char strings to test?
|
||||
*/
|
||||
|
||||
|
@ -187,14 +187,17 @@ class Format_Sanitize extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that string2htmlid is an alphanumeric string
|
||||
* Checking that keyword are correctly sanitized
|
||||
*
|
||||
* @dataProvider keywords_to_sanitize
|
||||
* @since 0.1
|
||||
*/
|
||||
public function test_sanitize_string( $string, $expected ) {
|
||||
$this->assertSame( $expected, yourls_sanitize_string( $string ) );
|
||||
$this->assertSame( $expected, yourls_sanitize_keyword( $string ) );
|
||||
public function test_sanitize_keywords( $keyword, $expected ) {
|
||||
// the "soft" way: assume keyword can be anything we have in a URL (here, should remain unchanged)
|
||||
$this->assertSame( $keyword, yourls_sanitize_keyword( $keyword ) );
|
||||
|
||||
// the "hard" way: keyword must comply to acceptable short URL charset
|
||||
$this->assertSame( $expected, yourls_sanitize_keyword( $keyword, true ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,36 +2,27 @@
|
||||
define( 'YOURLS_GO', true );
|
||||
require_once( dirname( __FILE__ ) . '/includes/load-yourls.php' );
|
||||
|
||||
// Variables should be defined in yourls-loader.php, if not try GET request (old behavior of yourls-go.php)
|
||||
if( !isset( $keyword ) && isset( $_GET['id'] ) )
|
||||
$keyword = $_GET['id'];
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
|
||||
// First possible exit:
|
||||
if ( !isset( $keyword ) ) {
|
||||
// Variables should be defined in yourls-loader.php
|
||||
if( !isset( $keyword ) ) {
|
||||
yourls_do_action( 'redirect_no_keyword' );
|
||||
yourls_redirect( YOURLS_SITE, 301 );
|
||||
}
|
||||
|
||||
// Get URL From Database
|
||||
$url = yourls_get_keyword_longurl( $keyword );
|
||||
$keyword = yourls_sanitize_keyword($keyword);
|
||||
|
||||
// URL found
|
||||
if( !empty( $url ) ) {
|
||||
yourls_redirect_shorturl($url, $keyword);
|
||||
|
||||
// URL not found. Either reserved, or page, or doesn't exist
|
||||
} else {
|
||||
|
||||
// Do we have a page?
|
||||
if ( file_exists( YOURLS_PAGEDIR . "/$keyword.php" ) ) {
|
||||
// if we have a page, display and exit
|
||||
if( yourls_is_page($keyword) ) {
|
||||
yourls_page( $keyword );
|
||||
|
||||
// Either reserved id, or no such id
|
||||
} else {
|
||||
yourls_do_action( 'redirect_keyword_not_found', $keyword );
|
||||
|
||||
yourls_redirect( YOURLS_SITE, 302 ); // no 404 to tell browser this might change, and also to not pollute logs
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if we can get a long URL from the DB, redirect
|
||||
if( $url = yourls_get_keyword_longurl( $keyword ) ) {
|
||||
yourls_redirect_shorturl($url, $keyword);
|
||||
return;
|
||||
}
|
||||
|
||||
// Either reserved keyword, or no such keyword
|
||||
yourls_do_action( 'redirect_keyword_not_found', $keyword );
|
||||
yourls_redirect( YOURLS_SITE, 302 ); // no 404 to tell browser this might change, and also to not pollute logs
|
||||
exit();
|
||||
|
@ -2,22 +2,16 @@
|
||||
// TODO: make things cleaner. This file is an awful HTML/PHP soup.
|
||||
define( 'YOURLS_INFOS', true );
|
||||
require_once( dirname( __FILE__ ).'/includes/load-yourls.php' );
|
||||
require_once( YOURLS_INC.'/functions-infos.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
// Variables should be defined in yourls-loader.php, if not try GET request (old behavior of yourls-infos.php)
|
||||
if( !isset( $keyword ) && isset( $_GET['id'] ) )
|
||||
$keyword = $_GET['id'];
|
||||
if( !isset( $aggregate ) && isset( $_GET['all'] ) && $_GET['all'] == 1 && yourls_allow_duplicate_longurls() )
|
||||
$aggregate = true;
|
||||
|
||||
// Variables should be defined in yourls-loader.php
|
||||
if ( !isset( $keyword ) ) {
|
||||
yourls_do_action( 'infos_no_keyword' );
|
||||
yourls_redirect( YOURLS_SITE, 302 );
|
||||
}
|
||||
|
||||
// Get basic infos for this shortened URL
|
||||
$keyword = yourls_sanitize_string( $keyword );
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
$longurl = yourls_get_keyword_longurl( $keyword );
|
||||
$clicks = yourls_get_keyword_clicks( $keyword );
|
||||
$timestamp = yourls_get_keyword_timestamp( $keyword );
|
||||
|
@ -18,49 +18,54 @@ if ( '/robots.txt' == $_SERVER['REQUEST_URI'] ) {
|
||||
require_once __DIR__ . '/includes/load-yourls.php';
|
||||
|
||||
// Get request in YOURLS base (eg in 'http://sho.rt/yourls/abcd' get 'abdc')
|
||||
// At this point, $request is NOT sanitized.
|
||||
$request = yourls_get_request();
|
||||
|
||||
// Make valid regexp pattern from authorized charset in keywords
|
||||
$pattern = yourls_make_regexp_pattern( yourls_get_shorturl_charset() );
|
||||
|
||||
// Now load required template and exit
|
||||
|
||||
yourls_do_action( 'pre_load_template', $request );
|
||||
|
||||
// At this point, $request is not sanitized. Sanitize in loaded template.
|
||||
// Let's look at the request : what we want to catch here is "anything", or "anything+" / "anything+all" (stat page)
|
||||
preg_match( "@^(.+?)(\+(all)?)?/?$@", $request, $matches );
|
||||
$keyword = isset($matches[1]) ? $matches[1] : null; // 'anything' whatever the request is (keyword, bookmarklet URL...)
|
||||
$stats = isset($matches[2]) ? $matches[2] : null; // null, or '+' if request is 'anything+', '+all' if request is 'anything+all'
|
||||
$stats_all = isset($matches[3]) ? $matches[3] : null; // null, or 'all' if request is 'anything+all'
|
||||
|
||||
// Redirection:
|
||||
if( preg_match( "@^([$pattern]+)/?$@", $request, $matches ) ) {
|
||||
$keyword = isset( $matches[1] ) ? $matches[1] : '';
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
yourls_do_action( 'load_template_go', $keyword );
|
||||
require_once( YOURLS_ABSPATH.'/yourls-go.php' );
|
||||
exit;
|
||||
}
|
||||
|
||||
// Stats:
|
||||
if( preg_match( "@^([$pattern]+)\+(all)?/?$@", $request, $matches ) ) {
|
||||
$keyword = isset( $matches[1] ) ? $matches[1] : '';
|
||||
$keyword = yourls_sanitize_keyword( $keyword );
|
||||
$aggregate = isset( $matches[2] ) ? (bool)$matches[2] && yourls_allow_duplicate_longurls() : false;
|
||||
yourls_do_action( 'load_template_infos', $keyword );
|
||||
require_once( YOURLS_ABSPATH.'/yourls-infos.php' );
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prefix-n-Shorten sends to bookmarklet (doesn't work on Windows)
|
||||
if( preg_match( "@^[a-zA-Z]+://.+@", $request, $matches ) ) {
|
||||
$url = yourls_sanitize_url( $matches[0] );
|
||||
if( $parse = yourls_get_protocol_slashes_and_rest( $url, [ 'up', 'us', 'ur' ] ) ) {
|
||||
// if request has a scheme (eg scheme://uri) : "Prefix-n-Shorten" sends to bookmarklet (doesn't work on Windows)
|
||||
if ( yourls_get_protocol($keyword) ) {
|
||||
$url = yourls_sanitize_url_safe($keyword);
|
||||
$parse = yourls_get_protocol_slashes_and_rest( $url, [ 'up', 'us', 'ur' ] );
|
||||
yourls_do_action( 'load_template_redirect_admin', $url );
|
||||
$parse = array_map( 'rawurlencode', $parse );
|
||||
|
||||
yourls_do_action( 'pre_redirect_bookmarklet', $url );
|
||||
|
||||
// Redirect to /admin/index.php?up=<url protocol>&us=<url slashes>&ur=<url rest>
|
||||
yourls_redirect( yourls_add_query_arg( $parse , yourls_admin_url( 'index.php' ) ), 302 );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Past this point this is a request the loader could not understand
|
||||
// if request is an existing short URL keyword ('abc') or stat page ('abc+') or an existing page :
|
||||
if ( yourls_keyword_is_taken($keyword) or yourls_is_page($keyword) ) {
|
||||
|
||||
// we have a short URL or a page
|
||||
if( $keyword && !$stats ) {
|
||||
yourls_do_action( 'load_template_go', $keyword );
|
||||
require_once( YOURLS_ABSPATH.'/yourls-go.php' );
|
||||
exit;
|
||||
}
|
||||
|
||||
// we have a stat page
|
||||
if( $keyword && $stats ) {
|
||||
$aggregate = $stats_all && yourls_allow_duplicate_longurls();
|
||||
yourls_do_action( 'load_template_infos', $keyword );
|
||||
require_once( YOURLS_ABSPATH.'/yourls-infos.php' );
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Past this point this is a request the loader could not understand : not a valid shorturl, not a bookmarklet
|
||||
yourls_do_action( 'redirect_keyword_not_found', $keyword );
|
||||
yourls_do_action( 'loader_failed', $request );
|
||||
yourls_redirect( YOURLS_SITE, 302 );
|
||||
exit;
|
||||
|
Loading…
x
Reference in New Issue
Block a user