Skip to content

Commit

Permalink
add hardcoded ini injection on build process
Browse files Browse the repository at this point in the history
  • Loading branch information
crazywhalecc committed Aug 2, 2023
1 parent 2a19748 commit 460238a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/SPC/command/BuildCliCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use SPC\builder\BuilderProvider;
use SPC\exception\ExceptionHandler;
use SPC\exception\WrongUsageException;
use SPC\store\SourcePatcher;
use SPC\util\DependencyUtil;
use SPC\util\LicenseDumper;
use Symfony\Component\Console\Attribute\AsCommand;
Expand All @@ -27,6 +28,7 @@ public function configure()
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
$this->addOption('enable-zts', null, null, 'enable ZTS support');
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
}

public function handle(): int
Expand Down Expand Up @@ -72,6 +74,16 @@ public function handle(): int
$builder->proveExts($extensions);
// strip
$builder->setStrip(!$this->getOption('no-strip'));
// Process -I option
$custom_ini = [];
foreach ($this->input->getOption('with-hardcoded-ini') as $value) {
[$source_name, $ini_value] = explode('=', $value, 2);
$custom_ini[$source_name] = $ini_value;
logger()->info('Adding hardcoded INI [' . $source_name . ' = ' . $ini_value . ']');
}
if (!empty($custom_ini)) {
SourcePatcher::patchHardcodedINI($custom_ini);
}
// 构建
$builder->buildPHP($rule, $this->getOption('bloat'));
// 统计时间
Expand Down
52 changes: 52 additions & 0 deletions src/SPC/store/SourcePatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,56 @@ public static function patchBeforeMake(BuilderBase $builder): void
}
}
}

/**
* @throws FileSystemException
*/
public static function patchHardcodedINI(array $ini = []): bool
{
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';

// Try to reverse backup file
$find_pattern = 'const char HARDCODED_INI[] =';
$patch_str = '';
foreach ($ini as $key => $value) {
$patch_str .= "\"{$key}={$value}\\n\"\n";
}
$patch_str = "const char HARDCODED_INI[] =\n{$patch_str}";

// Detect backup, if we have backup, it means we need to reverse first
if (file_exists($cli_c_bak) || file_exists($micro_c_bak)) {
self::unpatchHardcodedINI();
}

// Backup it
$result = file_put_contents($cli_c_bak, file_get_contents($cli_c));
$result = $result && file_put_contents($micro_c_bak, file_get_contents($micro_c));
if ($result === false) {
return false;
}

// Patch it
FileSystem::replaceFile($cli_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
FileSystem::replaceFile($micro_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
return true;
}

public static function unpatchHardcodedINI(): bool
{
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';
if (!file_exists($cli_c_bak) && !file_exists($micro_c_bak)) {
return false;
}
$result = file_put_contents($cli_c, file_get_contents($cli_c_bak));
$result = $result && file_put_contents($micro_c, file_get_contents($micro_c_bak));
@unlink($cli_c_bak);
@unlink($micro_c_bak);
return $result;
}
}

0 comments on commit 460238a

Please sign in to comment.