Skip to content

Commit 7a575a4

Browse files
vianaswclaude
andauthored
Forms: Validate field type format in get_field_type_icon (#47965)
Add a format check at the top of get_field_type_icon(): the $field_type argument must be a non-empty string of lowercase letters, digits, and hyphens, starting with a letter. Anything else returns the same empty string the helper already returns when an icon file is missing, so the caller flow is unchanged for legitimate types. Tests cover the rejected formats (non-strings, uppercase, leading digits, leading hyphens, internal whitespace, empty string) and a positive set of legitimate field types including the hyphenated entries that go through the existing exception map. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0dc3e76 commit 7a575a4

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fixed
3+
4+
Forms: Validate the field type before resolving the block icon path.

projects/packages/forms/src/contact-form/class-contact-form.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,13 @@ private static function get_rating( $value ) {
17431743
* @return string The SVG icon HTML.
17441744
*/
17451745
private static function get_field_type_icon( $field_type ) {
1746+
// Reject field types that don't fit the expected 'field-{type}' naming
1747+
// convention. Valid types are non-empty strings of lowercase letters,
1748+
// digits, and hyphens starting with a letter.
1749+
if ( ! is_string( $field_type ) || ! preg_match( '/^[a-z][a-z0-9-]*$/', $field_type ) ) {
1750+
return '';
1751+
}
1752+
17461753
// Map field types that don't follow the 'field-{type}' naming convention.
17471754
static $type_exceptions = array(
17481755
'phone' => 'field-telephone',

projects/packages/forms/tests/php/contact-form/Contact_Form_Test.php

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4096,4 +4096,135 @@ public function test_get_block_container_classes() {
40964096
$this->assertContains( 'jetpack-contact-form-container', $classes_array );
40974097
$this->assertContains( 'alignwide', $classes_array );
40984098
}
4099+
4100+
/**
4101+
* Test that get_field_type_icon rejects field types that don't match the
4102+
* required format (lowercase letter prefix, then lowercase letters, digits,
4103+
* or hyphens).
4104+
*
4105+
* @dataProvider data_provider_get_field_type_icon_invalid
4106+
*
4107+
* @param mixed $field_type The field type to test.
4108+
* @param string $description Human-readable description of the case.
4109+
*/
4110+
#[DataProvider( 'data_provider_get_field_type_icon_invalid' )]
4111+
public function test_get_field_type_icon_rejects_invalid_field_type_format( $field_type, $description ) {
4112+
$reflection = new \ReflectionClass( Contact_Form::class );
4113+
$method = $reflection->getMethod( 'get_field_type_icon' );
4114+
if ( PHP_VERSION_ID < 80100 ) {
4115+
$method->setAccessible( true );
4116+
}
4117+
4118+
$result = $method->invoke( null, $field_type );
4119+
4120+
$this->assertSame( '', $result, $description );
4121+
}
4122+
4123+
/**
4124+
* Data provider for invalid field type format cases.
4125+
*
4126+
* @return array[]
4127+
*/
4128+
public static function data_provider_get_field_type_icon_invalid() {
4129+
return array(
4130+
'contains parent directory segment' => array(
4131+
'../../../../etc/passwd',
4132+
'Field type containing ../ should be rejected',
4133+
),
4134+
'contains url-encoded path segment' => array(
4135+
'..%2F..%2Fetc%2Fpasswd',
4136+
'Field type with url-encoded path segment should be rejected',
4137+
),
4138+
'contains backslash path segment' => array(
4139+
'..\\..\\windows\\system32',
4140+
'Field type with backslash path segment should be rejected',
4141+
),
4142+
'leading slash' => array(
4143+
'/etc/passwd',
4144+
'Field type beginning with a forward slash should be rejected',
4145+
),
4146+
'contains null byte' => array(
4147+
"text\0.svg",
4148+
'Field type with embedded null byte should be rejected',
4149+
),
4150+
'uppercase letters' => array(
4151+
'TEXT',
4152+
'Uppercase field type should be rejected (strict format)',
4153+
),
4154+
'starts with digit' => array(
4155+
'1text',
4156+
'Field type starting with digit should be rejected',
4157+
),
4158+
'starts with hyphen' => array(
4159+
'-text',
4160+
'Field type starting with hyphen should be rejected',
4161+
),
4162+
'contains space' => array(
4163+
'text field',
4164+
'Field type with space should be rejected',
4165+
),
4166+
'non-string array' => array(
4167+
array( 'text' ),
4168+
'Array field type should be rejected',
4169+
),
4170+
'non-string integer' => array(
4171+
123,
4172+
'Integer field type should be rejected',
4173+
),
4174+
'non-string null' => array(
4175+
null,
4176+
'Null field type should be rejected',
4177+
),
4178+
'empty string' => array(
4179+
'',
4180+
'Empty field type should be rejected',
4181+
),
4182+
);
4183+
}
4184+
4185+
/**
4186+
* Test that get_field_type_icon returns valid SVG markup for known field types.
4187+
*
4188+
* Companion to test_get_field_type_icon_rejects_invalid_field_type_format —
4189+
* ensures the format check does not break legitimate field types.
4190+
*
4191+
* @dataProvider data_provider_get_field_type_icon_valid
4192+
*
4193+
* @param string $field_type The valid field type to test.
4194+
*/
4195+
#[DataProvider( 'data_provider_get_field_type_icon_valid' )]
4196+
public function test_get_field_type_icon_accepts_valid_types( $field_type ) {
4197+
$reflection = new \ReflectionClass( Contact_Form::class );
4198+
$method = $reflection->getMethod( 'get_field_type_icon' );
4199+
if ( PHP_VERSION_ID < 80100 ) {
4200+
$method->setAccessible( true );
4201+
}
4202+
4203+
$result = $method->invoke( null, $field_type );
4204+
4205+
// Valid field types either return SVG markup (when the icon file exists)
4206+
// or an empty string (when the block directory exists but has no icon.svg yet).
4207+
$this->assertIsString( $result, "Field type '$field_type' should return a string" );
4208+
if ( $result !== '' ) {
4209+
$this->assertStringContainsString( '<svg', $result, "Field type '$field_type' should return SVG markup" );
4210+
}
4211+
}
4212+
4213+
/**
4214+
* Data provider for valid field type acceptance test cases.
4215+
*
4216+
* @return array[]
4217+
*/
4218+
public static function data_provider_get_field_type_icon_valid() {
4219+
return array(
4220+
'text' => array( 'text' ),
4221+
'email' => array( 'email' ),
4222+
'textarea' => array( 'textarea' ),
4223+
'phone (via exception map)' => array( 'phone' ),
4224+
'telephone (via exception map)' => array( 'telephone' ),
4225+
'radio (via exception map)' => array( 'radio' ),
4226+
'checkbox-multiple (hyphenated)' => array( 'checkbox-multiple' ),
4227+
'image-select (hyphenated)' => array( 'image-select' ),
4228+
);
4229+
}
40994230
}

0 commit comments

Comments
 (0)