Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F5981479
CommandTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
CommandTest.php
View Options
<?php
use
MediaWiki\Shell\Command
;
use
MediaWiki\Shell\Shell
;
use
Shellbox\Shellbox
;
/**
* @covers \MediaWiki\Shell\Command
* @group Shell
*/
class
CommandTest
extends
PHPUnit\Framework\TestCase
{
use
MediaWikiCoversValidator
;
use
MediaWikiTestCaseTrait
;
private
function
requirePosix
()
{
if
(
wfIsWindows
()
)
{
$this
->
markTestSkipped
(
'This test requires a POSIX environment.'
);
}
}
private
function
createCommand
()
{
return
new
Command
(
Shellbox
::
createUnboxedExecutor
()
);
}
/**
* @dataProvider provideExecute
*/
public
function
testExecute
(
$command
,
$args
,
$expectedExitCode
,
$expectedOutput
)
{
$command
=
$this
->
getPhpCommand
(
$command
);
$result
=
$command
->
params
(
$args
)
->
execute
();
$this
->
assertSame
(
$expectedExitCode
,
$result
->
getExitCode
()
);
$this
->
assertSame
(
$expectedOutput
,
$result
->
getStdout
()
);
}
public
static
function
provideExecute
()
{
return
[
'success status'
=>
[
'success_status.php'
,
[],
0
,
''
],
'failure status'
=>
[
'failure_status.php'
,
[],
1
,
''
],
'output'
=>
[
'echo_args.php'
,
[
'x'
,
'>'
,
'y'
],
0
,
'x > y'
],
];
}
public
function
testEnvironment
()
{
$command
=
$this
->
getPhpCommand
(
'echo_env.php'
);
$result
=
$command
->
params
(
[
'FOO'
]
)
->
environment
(
[
'FOO'
=>
'bar'
]
)
->
execute
();
$this
->
assertSame
(
"bar"
,
$result
->
getStdout
()
);
}
public
function
testStdout
()
{
$command
=
$this
->
getPhpCommand
(
'echo_args.php'
);
$result
=
$command
->
unsafeParams
(
'ThisIsStderr'
,
'1>&2'
)
->
execute
();
$this
->
assertStringNotContainsString
(
'ThisIsStderr'
,
$result
->
getStdout
()
);
$this
->
assertEquals
(
"ThisIsStderr"
,
$result
->
getStderr
()
);
}
public
function
testStdoutRedirection
()
{
// The double redirection doesn't work on Windows
$this
->
requirePosix
();
$command
=
$this
->
createCommand
();
$result
=
$command
->
params
(
'bash'
,
'-c'
,
'echo ThisIsStderr 1>&2'
)
->
includeStderr
(
true
)
->
execute
();
$this
->
assertEquals
(
"ThisIsStderr
\n
"
,
$result
->
getStdout
()
);
$this
->
assertSame
(
''
,
$result
->
getStderr
()
);
}
public
function
testOutput
()
{
$command
=
$this
->
getPhpCommand
(
'stdout_stderr.php'
,
[
'correct stdout'
]
);
$result
=
$command
->
execute
();
$this
->
assertSame
(
'correct stdout'
,
$result
->
getStdout
()
);
$this
->
assertSame
(
''
,
$result
->
getStderr
()
);
$command
=
$this
->
getPhpCommand
(
'stdout_stderr.php'
,
[
'correct stdout '
,
'correct stderr '
]
);
$result
=
$command
->
includeStderr
()
->
execute
();
$this
->
assertMatchesRegularExpression
(
'/correct stdout/m'
,
$result
->
getStdout
()
);
$this
->
assertMatchesRegularExpression
(
'/correct stderr/m'
,
$result
->
getStdout
()
);
$this
->
assertSame
(
''
,
$result
->
getStderr
()
);
$command
=
$this
->
getPhpCommand
(
'stdout_stderr.php'
,
[
'correct stdout'
,
'correct stderr'
]
);
$result
=
$command
->
execute
();
$this
->
assertSame
(
'correct stdout'
,
$result
->
getStdout
()
);
$this
->
assertSame
(
'correct stderr'
,
$result
->
getStderr
()
);
}
/**
* Test that null values are skipped by params() and unsafeParams()
*/
public
function
testNullsAreSkipped
()
{
$command
=
$this
->
createCommand
();
$command
->
params
(
'echo'
,
'a'
,
null
,
'b'
);
$command
->
unsafeParams
(
'c'
,
null
,
'd'
);
if
(
wfIsWindows
()
)
{
$this
->
assertEquals
(
'"echo" "a" "b" c d'
,
$command
->
getCommandString
()
);
}
else
{
$this
->
assertEquals
(
"'echo' 'a' 'b' c d"
,
$command
->
getCommandString
()
);
}
}
public
function
testT69870
()
{
// Testing for Bug T69870
// wfShellExec() cuts off stdout at multiples of 8192 bytes.
// hangs on Windows, see Bug T199989, non-blocking pipes
$this
->
requirePosix
();
// Test several times because it involves a race condition that may randomly succeed or fail
for
(
$i
=
0
;
$i
<
10
;
$i
++
)
{
$command
=
$this
->
getPhpCommand
(
'echo_333333_stars.php'
);
$output
=
$command
->
execute
()
->
getStdout
();
$this
->
assertEquals
(
333333
,
strlen
(
$output
)
);
}
}
public
function
testLogStderr
()
{
$logger
=
new
TestLogger
(
true
,
static
function
(
$message
,
$level
,
$context
)
{
return
$level
===
Psr\Log\LogLevel
::
ERROR
?
'1'
:
null
;
},
true
);
$command
=
$this
->
getPhpCommand
(
'echo_args.php'
);
$command
->
setLogger
(
$logger
);
$command
->
unsafeParams
(
'ThisIsStderr'
,
'1>&2'
);
$command
->
execute
();
$this
->
assertSame
(
[],
$logger
->
getBuffer
()
);
$command
=
$this
->
getPhpCommand
(
'echo_args.php'
);
$command
->
setLogger
(
$logger
);
$command
->
logStderr
();
$command
->
unsafeParams
(
'ThisIsStderr'
,
'1>&2'
);
$command
->
execute
();
$this
->
assertCount
(
1
,
$logger
->
getBuffer
()
);
$this
->
assertSame
(
'ThisIsStderr'
,
trim
(
$logger
->
getBuffer
()[
0
][
2
][
'error'
]
)
);
}
public
function
testInput
()
{
// hangs on Windows, see Bug T199989, non-blocking pipes
$this
->
requirePosix
();
$command
=
$this
->
getPhpCommand
(
'echo_stdin.php'
);
$command
->
input
(
'abc'
);
$result
=
$command
->
execute
();
$this
->
assertSame
(
'abc'
,
$result
->
getStdout
()
);
// now try it with something that does not fit into a single block
$command
=
$this
->
getPhpCommand
(
'echo_stdin.php'
);
$command
->
input
(
str_repeat
(
'!'
,
1000000
)
);
$result
=
$command
->
execute
();
$this
->
assertSame
(
1000000
,
strlen
(
$result
->
getStdout
()
)
);
// And try it with empty input
$command
=
$this
->
getPhpCommand
(
'echo_stdin.php'
);
$command
->
input
(
''
);
$result
=
$command
->
execute
();
$this
->
assertSame
(
''
,
$result
->
getStdout
()
);
}
/**
* Ensure that it's possible to disable the default shell restrictions
* @see T257278
*/
public
function
testDisablingRestrictions
()
{
$command
=
$this
->
createCommand
();
// As CommandFactory does for the firejail case:
$command
->
restrict
(
Shell
::
RESTRICT_DEFAULT
);
// Disable restrictions
$command
->
restrict
(
Shell
::
RESTRICT_NONE
);
$this
->
assertFalse
(
$command
->
getPrivateUserNamespace
()
);
$this
->
assertFalse
(
$command
->
getFirejailDefaultSeccomp
()
);
$this
->
assertFalse
(
$command
->
getNoNewPrivs
()
);
$this
->
assertFalse
(
$command
->
getPrivateDev
()
);
$this
->
assertFalse
(
$command
->
getDisableNetwork
()
);
$this
->
assertSame
(
[],
$command
->
getDisabledSyscalls
()
);
$this
->
assertTrue
(
$command
->
getDisableSandbox
()
);
}
/**
* Creates a command that will execute one of the PHP test scripts by its
* file name, using the current PHP_BIN binary.
*
* NOTE: the PHP test scripts are located in the sub directory
* "bin".
*
* @param string $fileName a file name in the "bin" sub-directory
* @param array $args an array of arguments to pass to the PHP script
*
* @return Command a command instance pointing to the right script
*/
private
function
getPhpCommand
(
$fileName
,
array
$args
=
[]
)
{
$command
=
new
Command
(
Shellbox
::
createUnboxedExecutor
()
);
$params
=
[
PHP_BINARY
,
__DIR__
.
DIRECTORY_SEPARATOR
.
'bin'
.
DIRECTORY_SEPARATOR
.
$fileName
];
$params
=
array_merge
(
$params
,
$args
);
$command
->
params
(
$params
);
$command
->
limits
(
[
'memory'
=>
0
]
);
return
$command
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, Oct 3, 21:54 (1 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4b/bd/b70acf14dcc1c1a380251a43ec01
Default Alt Text
CommandTest.php (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment