Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
33.33% covered (danger)
33.33%
1 / 3
CRAP
39.29% covered (danger)
39.29%
11 / 28
BashWrapper
0.00% covered (danger)
0.00%
0 / 1
33.33% covered (danger)
33.33%
1 / 3
38.08
39.29% covered (danger)
39.29%
11 / 28
 __construct
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 wrap
0.00% covered (danger)
0.00%
0 / 1
23.81
30.00% covered (danger)
30.00%
6 / 20
 getPriority
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 3
<?php
namespace Shellbox\Command;
use Shellbox\Shellbox;
/**
 * A ulimit/cgroup wrapper implemented as a bash script
 */
class BashWrapper extends Wrapper {
    /** @var bool|string */
    private $cgroup;
    /**
     * @param string|false $cgroup Under Linux: a cgroup directory used to constrain
     *   memory usage of shell commands. The directory must be writable by the
     *   web server. If this is false, no memory limit will be applied.
     */
    public function __construct( $cgroup = false ) {
        parent::__construct();
        if ( strval( $cgroup ) === '' ) {
            $cgroup = '';
        }
        $this->cgroup = $cgroup;
    }
    public function wrap( Command $command ) {
        $time = intval( $command->getCpuTimeLimit() );
        $wallTime = intval( $command->getWallTimeLimit() );
        $mem = intval( $command->getMemoryLimit() );
        $filesize = intval( $command->getFileSizeLimit() );
        if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
            $cmd = '/bin/bash ' . Shellbox::escape( __DIR__ . '/limit.sh' ) . ' ' .
                Shellbox::escape( $command->getCommandString() ) . ' ' .
                Shellbox::escape(
                    "SB_INCLUDE_STDERR=" . ( $command->getIncludeStderr() ? '1' : '' ) . ';' .
                    "SB_CPU_LIMIT=$time" .
                    'SB_CGROUP=' . Shellbox::escape( $this->cgroup ) . '; ' .
                    "SB_MEM_LIMIT=$mem" .
                    "SB_FILE_SIZE_LIMIT=$filesize" .
                    "SB_WALL_CLOCK_LIMIT=$wallTime" .
                    "SB_USE_LOG_PIPE=yes"
                );
            $command->unsafeCommand( $cmd )
                ->useLogPipe();
            if ( $command->getAllowedPaths() ) {
                // If specific paths have been allowed, make sure we explicitly
                // allow limit.sh. We don't do this unconditionally because it
                // doesn't work as expected in firejail, see T274474, T182486
                $command->allowPath( __DIR__ . '/limit.sh' );
            }
        }
    }
    /**
     * If a cgroup is used, it is a system-level container. Otherwise it is
     * just setrlimit() and can run inside firejail etc. (T274942)
     *
     * @return int
     */
    public function getPriority() {
        if ( strlen( $this->cgroup ) ) {
            return 60;
        } else {
            return 20;
        }
    }
}