Skip to content

Commit 0fba3f5

Browse files
committed
Add support for sensitive parameters in stubs
1 parent bbc738e commit 0fba3f5

18 files changed

+153
-51
lines changed

Zend/zend_constants.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void zend_startup_constants(void)
109109

110110
void zend_register_standard_constants(void)
111111
{
112-
register_zend_constants_consts(0);
112+
register_zend_constants_symbols(0);
113113

114114
REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
115115
REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);

Zend/zend_constants_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55

6-
static void register_zend_constants_consts(int module_number)
6+
static void register_zend_constants_symbols(int module_number)
77
{
88
REGISTER_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_CS | CONST_PERSISTENT);
99
REGISTER_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_CS | CONST_PERSISTENT);

build/gen_stub.php

Lines changed: 121 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -759,21 +759,33 @@ class ArgInfo {
759759
public $phpDocType;
760760
/** @var string|null */
761761
public $defaultValue;
762+
/** @var bool */
763+
public $isSensitive;
762764

763-
public function __construct(string $name, int $sendBy, bool $isVariadic, ?Type $type, ?Type $phpDocType, ?string $defaultValue) {
765+
public function __construct(
766+
string $name,
767+
int $sendBy,
768+
bool $isVariadic,
769+
?Type $type,
770+
?Type $phpDocType,
771+
?string $defaultValue,
772+
bool $isSensitive
773+
) {
764774
$this->name = $name;
765775
$this->sendBy = $sendBy;
766776
$this->isVariadic = $isVariadic;
767777
$this->setTypes($type, $phpDocType);
768778
$this->defaultValue = $defaultValue;
779+
$this->isSensitive = $isSensitive;
769780
}
770781

771782
public function equals(ArgInfo $other): bool {
772783
return $this->name === $other->name
773784
&& $this->sendBy === $other->sendBy
774785
&& $this->isVariadic === $other->isVariadic
775786
&& Type::equals($this->type, $other->type)
776-
&& $this->defaultValue === $other->defaultValue;
787+
&& $this->defaultValue === $other->defaultValue
788+
&& $this->isSensitive === $other->isSensitive;
777789
}
778790

779791
public function getSendByString(): string {
@@ -925,6 +937,7 @@ interface FunctionOrMethodName {
925937
public function getDeclaration(): string;
926938
public function getArgInfoName(): string;
927939
public function getMethodSynopsisFilename(): string;
940+
public function getAttributeName(): string;
928941
public function __toString(): string;
929942
public function isMethod(): bool;
930943
public function isConstructor(): bool;
@@ -970,6 +983,10 @@ public function getMethodSynopsisFilename(): string {
970983
return implode('_', $this->name->parts);
971984
}
972985

986+
public function getAttributeName(): string {
987+
return $this->name->toString();
988+
}
989+
973990
public function __toString(): string {
974991
return $this->name->toString();
975992
}
@@ -989,7 +1006,7 @@ public function isDestructor(): bool {
9891006

9901007
class MethodName implements FunctionOrMethodName {
9911008
/** @var Name */
992-
private $className;
1009+
public $className;
9931010
/** @var string */
9941011
public $methodName;
9951012

@@ -1014,6 +1031,10 @@ public function getMethodSynopsisFilename(): string {
10141031
return $this->getDeclarationClassName() . "_{$this->methodName}";
10151032
}
10161033

1034+
public function getAttributeName(): string {
1035+
return $this->methodName;
1036+
}
1037+
10171038
public function __toString(): string {
10181039
return "$this->className::$this->methodName";
10191040
}
@@ -2896,7 +2917,7 @@ public function getVariableName(): string {
28962917

28972918
if ($this->name === "param") {
28982919
preg_match('/^\s*[\w\|\\\\\[\]]+\s*\$(\w+).*$/', $value, $matches);
2899-
} elseif ($this->name === "prefer-ref") {
2920+
} elseif ($this->name === "prefer-ref" || $this->name === "sensitive-param") {
29002921
preg_match('/^\s*\$(\w+).*$/', $value, $matches);
29012922
}
29022923

@@ -2946,34 +2967,61 @@ function parseFunctionLike(
29462967
if ($comment) {
29472968
$tags = parseDocComment($comment);
29482969
foreach ($tags as $tag) {
2949-
if ($tag->name === 'prefer-ref') {
2950-
$varName = $tag->getVariableName();
2951-
if (!isset($paramMeta[$varName])) {
2952-
$paramMeta[$varName] = [];
2953-
}
2954-
$paramMeta[$varName]['preferRef'] = true;
2955-
} else if ($tag->name === 'alias' || $tag->name === 'implementation-alias') {
2956-
$aliasType = $tag->name;
2957-
$aliasParts = explode("::", $tag->getValue());
2958-
if (count($aliasParts) === 1) {
2959-
$alias = new FunctionName(new Name($aliasParts[0]));
2960-
} else {
2961-
$alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]);
2962-
}
2963-
} else if ($tag->name === 'deprecated') {
2964-
$isDeprecated = true;
2965-
} else if ($tag->name === 'no-verify') {
2966-
$verify = false;
2967-
} else if ($tag->name === 'tentative-return-type') {
2968-
$tentativeReturnType = true;
2969-
} else if ($tag->name === 'return') {
2970-
$docReturnType = $tag->getType();
2971-
} else if ($tag->name === 'param') {
2972-
$docParamTypes[$tag->getVariableName()] = $tag->getType();
2973-
} else if ($tag->name === 'refcount') {
2974-
$refcount = $tag->getValue();
2975-
} else if ($tag->name === 'compile-time-eval') {
2976-
$supportsCompileTimeEval = true;
2970+
switch ($tag->name) {
2971+
case 'prefer-ref':
2972+
$varName = $tag->getVariableName();
2973+
if (!isset($paramMeta[$varName])) {
2974+
$paramMeta[$varName] = [];
2975+
}
2976+
$paramMeta[$varName]['preferRef'] = true;
2977+
break;
2978+
2979+
case 'alias':
2980+
case 'implementation-alias':
2981+
$aliasType = $tag->name;
2982+
$aliasParts = explode("::", $tag->getValue());
2983+
if (count($aliasParts) === 1) {
2984+
$alias = new FunctionName(new Name($aliasParts[0]));
2985+
} else {
2986+
$alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]);
2987+
}
2988+
break;
2989+
2990+
case 'deprecated':
2991+
$isDeprecated = true;
2992+
break;
2993+
2994+
case 'no-verify':
2995+
$verify = false;
2996+
break;
2997+
2998+
case 'tentative-return-type':
2999+
$tentativeReturnType = true;
3000+
break;
3001+
3002+
case 'return':
3003+
$docReturnType = $tag->getType();
3004+
break;
3005+
3006+
case 'param':
3007+
$docParamTypes[$tag->getVariableName()] = $tag->getType();
3008+
break;
3009+
3010+
case 'refcount':
3011+
$refcount = $tag->getValue();
3012+
break;
3013+
3014+
case 'compile-time-eval':
3015+
$supportsCompileTimeEval = true;
3016+
break;
3017+
3018+
case 'sensitive-param':
3019+
$varName = $tag->getVariableName();
3020+
if (!isset($paramMeta[$varName])) {
3021+
$paramMeta[$varName] = [];
3022+
}
3023+
$paramMeta[$varName]['sensitive'] = true;
3024+
break;
29773025
}
29783026
}
29793027
}
@@ -2985,6 +3033,7 @@ function parseFunctionLike(
29853033
foreach ($func->getParams() as $i => $param) {
29863034
$varName = $param->var->name;
29873035
$preferRef = !empty($paramMeta[$varName]['preferRef']);
3036+
$isSensitive = !empty($paramMeta[$varName]['sensitive']);
29883037
unset($paramMeta[$varName]);
29893038

29903039
if (isset($varNameSet[$varName])) {
@@ -3031,7 +3080,8 @@ function parseFunctionLike(
30313080
$param->variadic,
30323081
$type,
30333082
isset($docParamTypes[$varName]) ? Type::fromString($docParamTypes[$varName]) : null,
3034-
$param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null
3083+
$param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null,
3084+
$isSensitive
30353085
);
30363086
if (!$param->default && !$param->variadic) {
30373087
$numRequiredArgs = $i + 1;
@@ -3636,14 +3686,26 @@ function (FuncInfo $funcInfo) use($fileInfo, &$generatedFunctionDeclarations) {
36363686
}
36373687

36383688
if ($fileInfo->generateClassEntries) {
3639-
if (!empty($fileInfo->constInfos)) {
3640-
$code .= "\nstatic void register_{$stubFilenameWithoutExtension}_consts(int module_number)\n";
3689+
$classEntriesWithSensitiveParams = [];
3690+
$attributeInitializationCode = generateAttributeInitialization($fileInfo, $classEntriesWithSensitiveParams);
3691+
3692+
if ($attributeInitializationCode !== "" || !empty($fileInfo->constInfos)) {
3693+
$code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number";
3694+
foreach ($classEntriesWithSensitiveParams as $ce) {
3695+
$code .= ", zend_class_entry *$ce";
3696+
}
3697+
$code .= ")\n";
36413698
$code .= "{\n";
36423699

36433700
foreach ($fileInfo->constInfos as $constInfo) {
36443701
$code .= $constInfo->getDeclaration($allConstInfos);
36453702
}
36463703

3704+
if (!empty($attributeInitializationCode !== "" && $fileInfo->constInfos)) {
3705+
$code .= "\n";
3706+
}
3707+
3708+
$code .= $attributeInitializationCode;
36473709
$code .= "}\n";
36483710
}
36493711

@@ -3686,6 +3748,30 @@ function generateFunctionEntries(?Name $className, array $funcInfos): string {
36863748
return $code;
36873749
}
36883750

3751+
function generateAttributeInitialization(FileInfo $fileInfo, array &$classEntriesWithSensitiveParams): string {
3752+
$code = "";
3753+
3754+
foreach ($fileInfo->getAllFuncInfos() as $funcInfo) {
3755+
foreach ($funcInfo->args as $index => $arg) {
3756+
if (!$arg->isSensitive) {
3757+
continue;
3758+
}
3759+
3760+
if ($funcInfo->name instanceof MethodName) {
3761+
$classEntry = "class_entry_" . str_replace("\\", "_", $funcInfo->name->className->toString());
3762+
$functionTable = "&{$classEntry}->function_table";
3763+
$classEntriesWithSensitiveParams[] = $classEntry;
3764+
} else {
3765+
$functionTable = "CG(function_table)";
3766+
}
3767+
3768+
$code .= " zend_mark_function_parameter_as_sensitive($functionTable, \"" . $funcInfo->name->getAttributeName() . "\", $index);\n";
3769+
}
3770+
}
3771+
3772+
return $code;
3773+
}
3774+
36893775
/** @param FuncInfo<string, FuncInfo> $funcInfos */
36903776
function generateOptimizerInfo(array $funcInfos): string {
36913777

ext/calendar/calendar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ ZEND_GET_MODULE(calendar)
110110

111111
PHP_MINIT_FUNCTION(calendar)
112112
{
113-
register_calendar_consts(module_number);
113+
register_calendar_symbols(module_number);
114114

115115
return SUCCESS;
116116
}

ext/calendar/calendar_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static const zend_function_entry ext_functions[] = {
117117
ZEND_FE_END
118118
};
119119

120-
static void register_calendar_consts(int module_number)
120+
static void register_calendar_symbols(int module_number)
121121
{
122122
REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS | CONST_PERSISTENT);
123123
REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS | CONST_PERSISTENT);

ext/date/php_date_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ static const zend_function_entry class_DatePeriod_methods[] = {
748748
ZEND_FE_END
749749
};
750750

751-
static void register_php_date_consts(int module_number)
751+
static void register_php_date_symbols(int module_number)
752752
{
753753
REGISTER_STRING_CONSTANT("DATE_ATOM", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
754754
ZEND_ASSERT(strcmp(DATE_FORMAT_RFC3339, "Y-m-d\\TH:i:sP") == 0);

ext/dom/php_dom.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ PHP_MINIT_FUNCTION(dom)
789789
zend_hash_add_ptr(&classes, dom_xpath_class_entry->name, &dom_xpath_prop_handlers);
790790
#endif
791791

792-
register_php_dom_consts(module_number);
792+
register_php_dom_symbols(module_number);
793793

794794
php_libxml_register_export(dom_node_class_entry, php_dom_export_node);
795795

ext/dom/php_dom_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ static const zend_function_entry class_DOMXPath_methods[] = {
895895
ZEND_FE_END
896896
};
897897

898-
static void register_php_dom_consts(int module_number)
898+
static void register_php_dom_symbols(int module_number)
899899
{
900900
REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE", XML_ELEMENT_NODE, CONST_CS | CONST_PERSISTENT);
901901
REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NODE", XML_ATTRIBUTE_NODE, CONST_CS | CONST_PERSISTENT);

ext/enchant/enchant.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ PHP_MINIT_FUNCTION(enchant)
207207
enchant_dict_handlers.clone_obj = NULL;
208208
enchant_dict_handlers.compare = zend_objects_not_comparable;
209209

210-
register_enchant_consts(module_number);
210+
register_enchant_symbols(module_number);
211211

212212
return SUCCESS;
213213
}

ext/enchant/enchant_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ static const zend_function_entry class_EnchantDictionary_methods[] = {
158158
ZEND_FE_END
159159
};
160160

161-
static void register_enchant_consts(int module_number)
161+
static void register_enchant_symbols(int module_number)
162162
{
163163
REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_CS | CONST_PERSISTENT | CONST_DEPRECATED);
164164
REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_CS | CONST_PERSISTENT | CONST_DEPRECATED);

ext/exif/exif.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ PHP_MINIT_FUNCTION(exif)
166166
{
167167
REGISTER_INI_ENTRIES();
168168

169-
register_exif_consts(module_number);
169+
register_exif_symbols(module_number);
170170

171171
return SUCCESS;
172172
}

ext/exif/exif_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static const zend_function_entry ext_functions[] = {
3838
ZEND_FE_END
3939
};
4040

41-
static void register_exif_consts(int module_number)
41+
static void register_exif_symbols(int module_number)
4242
{
4343
REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", USE_MBSTRING, CONST_CS | CONST_PERSISTENT);
4444
}

ext/mysqli/mysqli.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "zend_exceptions.h"
3333
#include "ext/spl/spl_exceptions.h"
3434
#include "zend_interfaces.h"
35+
#include "zend_attributes.h"
3536
#include "mysqli_arginfo.h"
3637

3738
ZEND_DECLARE_MODULE_GLOBALS(mysqli)
@@ -692,6 +693,8 @@ PHP_MINIT_FUNCTION(mysqli)
692693
REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", 0, CONST_CS | CONST_PERSISTENT);
693694
#endif
694695

696+
register_mysqli_symbols(module_number, mysqli_link_class_entry);
697+
695698
mysqlnd_reverse_api_register_api(&mysqli_reverse_api);
696699

697700
return SUCCESS;

ext/mysqli/mysqli.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class mysqli
126126
*/
127127
public int $warning_count;
128128

129+
/** @sensitive-param $password */
129130
public function __construct(
130131
?string $hostname = null,
131132
?string $username = null,

ext/mysqli/mysqli_arginfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: a2f2992afd959a13215bfdfd00096f368b3bc392 */
2+
* Stub hash: 794efd97f6eac5e755bed2eb6219173a1ee45321 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
55
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@@ -1025,6 +1025,11 @@ static const zend_function_entry class_mysqli_sql_exception_methods[] = {
10251025
ZEND_FE_END
10261026
};
10271027

1028+
static void register_mysqli_symbols(int module_number, zend_class_entry *class_entry_mysqli)
1029+
{
1030+
zend_mark_function_parameter_as_sensitive(&class_entry_mysqli->function_table, "__construct", 2);
1031+
}
1032+
10281033
static zend_class_entry *register_class_mysqli_driver(void)
10291034
{
10301035
zend_class_entry ce, *class_entry;

0 commit comments

Comments
 (0)