Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion includes/fields/class-acf-field-url.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ public function validate_value( $valid, $value, $field, $input ) {
return $valid;
}

// A non-string value (e.g. an array from a crafted submission) is never a valid URL.
if ( ! is_string( $value ) ) {
return __( 'Value must be a valid URL', 'secure-custom-fields' );
}

if ( strpos( $value, '://' ) !== false ) {

// url
Expand Down Expand Up @@ -156,7 +161,8 @@ public function validate_value( $valid, $value, $field, $input ) {
*/
public function format_value( $value, $post_id, $field, $escape_html ) {
if ( $escape_html ) {
return esc_url( $value );
// esc_url() expects a string; treat a non-string value as empty.
return is_string( $value ) ? esc_url( $value ) : '';
}
return $value;
}
Expand Down
29 changes: 29 additions & 0 deletions tests/php/includes/fields/test-class-acf-field-url.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,35 @@ public function test_validate_value_empty_required() {
$this->assertTrue( $valid );
}

/**
* Test validate_value does not crash on a non-scalar value.
*
* A crafted form submission can deliver an array (e.g. acf[field_key][])
* as the value. The field should treat it as invalid rather than raising
* a TypeError from strpos().
*/
public function test_validate_value_non_scalar() {
$field = $this->get_field( array( 'required' => 1 ) );

$valid = $this->field_instance->validate_value( true, array( 'a' => 'b' ), $field, 'acf[field_url_test]' );

$this->assertEquals( __( 'Value must be a valid URL', 'secure-custom-fields' ), $valid );
}

/**
* Test format_value does not crash on a non-scalar value when escaping.
*
* Calling esc_url() on an array would raise a TypeError. The field should
* return an empty string, matching how it treats an empty value.
*/
public function test_format_value_non_scalar_escaped() {
$field = $this->get_field();

$result = $this->field_instance->format_value( array( 'a' => 'b' ), $this->post_id, $field, true );

$this->assertEquals( '', $result );
}

/**
* Test get_rest_schema returns valid schema.
*/
Expand Down
Loading