Skip to content

Commit 460238a

Browse files
committed
add hardcoded ini injection on build process
1 parent 2a19748 commit 460238a

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/SPC/command/BuildCliCommand.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use SPC\builder\BuilderProvider;
88
use SPC\exception\ExceptionHandler;
99
use SPC\exception\WrongUsageException;
10+
use SPC\store\SourcePatcher;
1011
use SPC\util\DependencyUtil;
1112
use SPC\util\LicenseDumper;
1213
use Symfony\Component\Console\Attribute\AsCommand;
@@ -27,6 +28,7 @@ public function configure()
2728
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
2829
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
2930
$this->addOption('enable-zts', null, null, 'enable ZTS support');
31+
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
3032
}
3133

3234
public function handle(): int
@@ -72,6 +74,16 @@ public function handle(): int
7274
$builder->proveExts($extensions);
7375
// strip
7476
$builder->setStrip(!$this->getOption('no-strip'));
77+
// Process -I option
78+
$custom_ini = [];
79+
foreach ($this->input->getOption('with-hardcoded-ini') as $value) {
80+
[$source_name, $ini_value] = explode('=', $value, 2);
81+
$custom_ini[$source_name] = $ini_value;
82+
logger()->info('Adding hardcoded INI [' . $source_name . ' = ' . $ini_value . ']');
83+
}
84+
if (!empty($custom_ini)) {
85+
SourcePatcher::patchHardcodedINI($custom_ini);
86+
}
7587
// 构建
7688
$builder->buildPHP($rule, $this->getOption('bloat'));
7789
// 统计时间

src/SPC/store/SourcePatcher.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,56 @@ public static function patchBeforeMake(BuilderBase $builder): void
146146
}
147147
}
148148
}
149+
150+
/**
151+
* @throws FileSystemException
152+
*/
153+
public static function patchHardcodedINI(array $ini = []): bool
154+
{
155+
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
156+
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
157+
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
158+
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';
159+
160+
// Try to reverse backup file
161+
$find_pattern = 'const char HARDCODED_INI[] =';
162+
$patch_str = '';
163+
foreach ($ini as $key => $value) {
164+
$patch_str .= "\"{$key}={$value}\\n\"\n";
165+
}
166+
$patch_str = "const char HARDCODED_INI[] =\n{$patch_str}";
167+
168+
// Detect backup, if we have backup, it means we need to reverse first
169+
if (file_exists($cli_c_bak) || file_exists($micro_c_bak)) {
170+
self::unpatchHardcodedINI();
171+
}
172+
173+
// Backup it
174+
$result = file_put_contents($cli_c_bak, file_get_contents($cli_c));
175+
$result = $result && file_put_contents($micro_c_bak, file_get_contents($micro_c));
176+
if ($result === false) {
177+
return false;
178+
}
179+
180+
// Patch it
181+
FileSystem::replaceFile($cli_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
182+
FileSystem::replaceFile($micro_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
183+
return true;
184+
}
185+
186+
public static function unpatchHardcodedINI(): bool
187+
{
188+
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
189+
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
190+
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
191+
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';
192+
if (!file_exists($cli_c_bak) && !file_exists($micro_c_bak)) {
193+
return false;
194+
}
195+
$result = file_put_contents($cli_c, file_get_contents($cli_c_bak));
196+
$result = $result && file_put_contents($micro_c, file_get_contents($micro_c_bak));
197+
@unlink($cli_c_bak);
198+
@unlink($micro_c_bak);
199+
return $result;
200+
}
149201
}

0 commit comments

Comments
 (0)