2014-01-03 14:29:03 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* MediaWiki math extension
|
|
|
|
*
|
2015-09-21 16:14:01 +00:00
|
|
|
* (c) 2002-2015 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz,
|
|
|
|
* and other MediaWiki contributors
|
2014-01-03 14:29:03 +00:00
|
|
|
* GPLv2 license; info in main package.
|
|
|
|
*
|
|
|
|
* @author Moritz Schubotz
|
|
|
|
*/
|
2015-04-14 19:42:48 +00:00
|
|
|
|
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
|
|
|
|
2014-01-03 14:29:03 +00:00
|
|
|
class MathInputCheckTexvc extends MathInputCheck {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts an error returned by texvc to a localized exception
|
|
|
|
*
|
|
|
|
* @param string $texvcResult error result returned by texvc
|
2014-02-09 19:02:15 +00:00
|
|
|
* @param bool|MathRenderer $errorRenderer
|
|
|
|
* @return string
|
2014-01-03 14:29:03 +00:00
|
|
|
*/
|
|
|
|
public function convertTexvcError( $texvcResult, $errorRenderer = false ) {
|
|
|
|
$texvcStatus = substr( $texvcResult, 0, 1 );
|
|
|
|
$errDetails = htmlspecialchars( substr( $texvcResult, 1 ) );
|
|
|
|
|
|
|
|
if ( $errorRenderer === false ) {
|
2017-08-11 03:57:43 +00:00
|
|
|
$errorRenderer = new MathSource( $this->inputTeX );
|
2014-01-03 14:29:03 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 19:02:15 +00:00
|
|
|
switch ( $texvcStatus ) {
|
2014-01-03 14:29:03 +00:00
|
|
|
case 'E':
|
|
|
|
$errMsg = $errorRenderer->getError( 'math_lexing_error' );
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
$errMsg = $errorRenderer->getError( 'math_syntax_error' );
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
$errMsg = $errorRenderer->getError( 'math_unknown_function', $errDetails );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$errMsg = $errorRenderer->getError( 'math_unknown_error' );
|
|
|
|
}
|
|
|
|
|
|
|
|
return $errMsg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-07-26 20:43:39 +00:00
|
|
|
* @return bool
|
2014-01-03 14:29:03 +00:00
|
|
|
*/
|
|
|
|
public function isValid() {
|
2014-02-06 22:53:45 +00:00
|
|
|
$us = $this;
|
2016-04-12 20:53:25 +00:00
|
|
|
$checkWork = new PoolCounterWorkViaCallback( 'MathTexvc-check', "", [
|
2017-06-20 07:11:57 +00:00
|
|
|
'doWork' => function () use ( $us ) {
|
2014-02-06 22:53:45 +00:00
|
|
|
return $us->doValidCheck();
|
|
|
|
}
|
2016-04-12 20:53:25 +00:00
|
|
|
] );
|
2014-02-06 22:53:45 +00:00
|
|
|
return $checkWork->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-07-26 20:43:39 +00:00
|
|
|
* @return bool
|
2014-02-06 22:53:45 +00:00
|
|
|
*/
|
|
|
|
public function doValidCheck() {
|
2014-01-03 14:29:03 +00:00
|
|
|
global $wgMathTexvcCheckExecutable;
|
2017-06-20 07:11:57 +00:00
|
|
|
if ( $wgMathTexvcCheckExecutable === false ) {
|
2015-07-22 22:10:46 +00:00
|
|
|
$texvcCheckExecutable = __DIR__ . '/texvccheck/texvccheck';
|
|
|
|
} else {
|
|
|
|
$texvcCheckExecutable = $wgMathTexvcCheckExecutable;
|
|
|
|
}
|
|
|
|
if ( !is_executable( $texvcCheckExecutable ) ) {
|
2015-02-20 00:22:46 +00:00
|
|
|
$msg = 'Missing "texvccheck" executable. Please see math/README to configure.';
|
2014-01-03 14:29:03 +00:00
|
|
|
trigger_error( $msg, E_USER_NOTICE );
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->error( $msg );
|
2014-01-03 14:29:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-07-22 22:10:46 +00:00
|
|
|
$cmd = $texvcCheckExecutable . ' ' . wfEscapeShellArg( $this->inputTeX );
|
2014-01-03 14:29:03 +00:00
|
|
|
|
|
|
|
if ( wfIsWindows() ) {
|
|
|
|
# Invoke it within cygwin sh, because texvc expects sh features in its default shell
|
2014-02-09 19:02:15 +00:00
|
|
|
$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
|
2014-01-03 14:29:03 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->debug( "TeX check command: $cmd" );
|
2016-04-19 17:29:10 +00:00
|
|
|
if ( strlen( $cmd ) > SHELL_MAX_ARG_STRLEN ) {
|
|
|
|
LoggerFactory::getInstance( 'Math' )->error(
|
|
|
|
"User input exceeded SHELL_MAX_ARG_STRLEN." );
|
|
|
|
return $this->convertTexvcError( '' );
|
|
|
|
}
|
2014-01-03 14:29:03 +00:00
|
|
|
$contents = wfShellExec( $cmd );
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->debug( "TeX check result: $contents\n---" );
|
2014-01-03 14:29:03 +00:00
|
|
|
|
2014-02-09 19:02:15 +00:00
|
|
|
if ( strlen( $contents ) === 0 ) {
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->warning( 'TeX check output was empty.' );
|
2014-12-09 04:36:29 +00:00
|
|
|
$this->lastError = $this->convertTexvcError( $contents );
|
2014-01-03 14:29:03 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$retval = substr( $contents, 0, 1 );
|
|
|
|
|
|
|
|
if ( $retval !== '+' ) {
|
|
|
|
$this->lastError = $this->convertTexvcError( $contents );
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->warning( 'checkTex failed: ' . $this->lastError );
|
2014-01-03 14:29:03 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
$this->validTeX = substr( $contents, 1 );
|
2014-12-09 13:25:23 +00:00
|
|
|
$this->isValid = true;
|
2015-04-14 19:42:48 +00:00
|
|
|
LoggerFactory::getInstance( 'Math' )->debug(
|
2015-03-16 21:43:20 +00:00
|
|
|
'checkTex successful tex is now: ' . $this->validTeX );
|
2014-01-03 14:29:03 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|