if ( strpos( $path, $prefix ) === 0 ) {
$be = FileBackendGroup::singleton()->backendFromPath( $storageDir );
$filename = $storageDir . substr( $path, strlen( $prefix ) ); // strip prefix
+ // Check basic user authorization
+ if ( !RequestContext::getMain()->getUser()->isAllowed( 'read' ) ) {
+ wfForbidden( 'img-auth-accessdenied', 'img-auth-noread', $path );
+ return;
+ }
if ( $be->fileExists( array( 'src' => $filename ) ) ) {
wfDebugLog( 'img_auth', "Streaming `" . $filename . "`." );
$be->streamFile( array( 'src' => $filename ),
array( 'Cache-Control: private', 'Vary: Cookie' ) );
} else {
- wfForbidden( 'img-auth-accessdenied', 'img-auth-nofile', $filename );
+ wfForbidden( 'img-auth-accessdenied', 'img-auth-nofile', $path );
}
return;
}
// Normalize Halfwidth and Fullwidth Unicode block that IE6 might treat as ascii
$value = preg_replace_callback(
- '/[ï¼\81-ï½\9a]/u', // U+FF01 to U+FF5A
+ '/[ï¼\81-[]-ï½\9a]/u', // U+FF01 to U+FF5A, excluding U+FF3C (bug 58088)
function ( $matches ) {
$cp = utf8ToCodepoint( $matches[0] );
if ( $cp === false ) {
if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ) {
return '/* invalid control char */';
} elseif ( preg_match(
- '! expression | filter\s*: | accelerator\s*: | url\s*\( | image\s*\( | image-set\s*\( !ix',
- $value
- ) ) {
+ '! expression
+ | filter\s*:
+ | accelerator\s*:
+ | -o-link\s*:
+ | -o-link-source\s*:
+ | -o-replace\s*:
+ | url\s*\(
+ | image\s*\(
+ | image-set\s*\(
+ !ix', $value ) ) {
return '/* insecure input */';
}
return $value;
if ( $this->fld_ids ) {
$vals['logid'] = intval( $row->log_id );
- $vals['pageid'] = intval( $row->page_id );
}
if ( $this->fld_title || $this->fld_parsedcomment ) {
$title = Title::makeTitle( $row->log_namespace, $row->log_title );
}
- if ( $this->fld_title ) {
+ if ( $this->fld_title || $this->fld_ids ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
$vals['actionhidden'] = '';
} else {
- ApiQueryBase::addTitleInfo( $vals, $title );
+ if ( $this->fld_title ) {
+ ApiQueryBase::addTitleInfo( $vals, $title );
+ }
+ if ( $this->fld_ids ) {
+ $vals['pageid'] = intval( $row->page_id );
+ }
}
}
if ( $block[0]->mAttribs['rc_log_type'] ) {
# Log entry
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
- . $block[0]->mAttribs['rc_log_type'] . '-' . $block[0]->mAttribs['rc_title'] );
+ . $block[0]->mAttribs['rc_log_type'] );
} else {
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns'
. $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
$classes = array( 'mw-enhanced-rc' );
if ( $logType ) {
# Log entry
- $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
- . $logType . '-' . $rcObj->mAttribs['rc_title'] );
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType );
} else {
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' .
$rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
}
$val = dba_fetch( $key, $handle );
+ $casToken = $val;
list( $val, $expiry ) = $this->decode( $val );
# Must close ASAP because locks are held
$val = false;
}
- $casToken = $val;
-
wfProfileOut( __METHOD__ );
return $val;
// DBA is locked to any other write connection, so we can safely
// compare the current & previous value before saving new value
$val = dba_fetch( $key, $handle );
- list( $val, $exptime ) = $this->decode( $val );
if ( $casToken !== $val ) {
dba_close( $handle );
wfProfileOut( __METHOD__ );
return false;
}
- $casToken = $this->bag[$key][0];
+ $casToken = serialize( $this->bag[$key][0] );
return $this->bag[$key][0];
}
* @return bool
*/
function cas( $casToken, $key, $value, $exptime = 0 ) {
- if ( $this->get( $key ) === $casToken ) {
+ if ( serialize( $this->get( $key ) ) === $casToken ) {
return $this->set( $key, $value, $exptime );
}
return false;
}
try {
- $result = $this->unserialize( $conn->get( $key ) );
+ $value = $conn->get( $key );
+ $casToken = $value;
+ $result = $this->unserialize( $value );
} catch ( RedisException $e ) {
$result = false;
$this->handleException( $server, $conn, $e );
}
- $casToken = $result;
$this->logRequest( 'get', $key, $server, $result );
return $result;
try {
$conn->watch( $key );
- if ( $this->get( $key ) !== $casToken ) {
+ if ( $this->serialize( $this->get( $key ) ) !== $casToken ) {
$conn->unwatch();
return false;
}
}
}
+ // Log entries with DELETED_ACTION must not show up unless the user has
+ // the necessary rights.
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $bitmask = LogPage::DELETED_ACTION;
+ } elseif ( !$user->isAllowed( 'suppressrevision' ) ) {
+ $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
+ } else {
+ $bitmask = 0;
+ }
+ if ( $bitmask ) {
+ $conds[] = $dbr->makeList( array(
+ 'rc_type != ' . RC_LOG,
+ $dbr->bitAnd( 'rc_deleted', $bitmask ) . " != $bitmask",
+ ), LIST_OR );
+ }
+
+
ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields, $opts ) );
return array( 'uploadscripted' );
}
if ( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
- if ( $this->detectScriptInSvg( $this->mTempPath ) ) {
+ $svgStatus = $this->detectScriptInSvg( $this->mTempPath );
+ if ( $svgStatus !== false ) {
wfProfileOut( __METHOD__ );
- return array( 'uploadscripted' );
+ return $svgStatus;
}
}
}
/**
* @param $filename string
- * @return bool
+ * @return mixed false of the file is verified (does not contain scripts), array otherwise.
*/
protected function detectScriptInSvg( $filename ) {
$check = new XmlTypeCheck(
true,
array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' )
);
- return $check->filterMatch;
+ if ( $check->wellFormed !== true ) {
+ // Invalid xml (bug 58553)
+ return array( 'uploadinvalidxml' );
+ } elseif ( $check->filterMatch ) {
+ return array( 'uploadscripted' );
+ }
+ return false;
}
/**
'php-uploaddisabledtext' => 'File uploads are disabled in PHP.
Please check the file_uploads setting.',
'uploadscripted' => 'This file contains HTML or script code that may be erroneously interpreted by a web browser.',
+'uploadinvalidxml' => 'The XML in the uploaded file could not be parsed.',
'uploadvirus' => 'The file contains a virus!
Details: $1',
'uploadjava' => 'The file is a ZIP file that contains a Java .class file.
* {{msg-mw|zip-wrong-format}}
* {{msg-mw|uploadjava}}
* {{msg-mw|uploadvirus}}',
+'uploadinvalidxml' => 'Error message displayed when the uploaded file contains XML that cannot be properly parsed and checked.',
'uploadvirus' => 'Error message displayed when uploaded file contains a virus.
Parameters:
!! end
+!! test
+Opera -o-link CSS
+!! input
+<div
+title="data:text/html,<img src=1 onerror=alert(1)>"
+style="-o-link:attr(title);-o-link-source:current">X</div>
+!! result
+<div title="data:text/html,<img src=1 onerror=alert(1)>" style="/* insecure input */">X</div>
+
+!! end
+
!! test
MSIE CSS safety test: Repetition markers
!! input