Skip to content

Commit c92910c

Browse files
authored
Implement FROM_BASE64() and TO_BASE64() MySQL functions (#326)
## Summary This adds support for MySQL's `FROM_BASE64()` and `TO_BASE64()` functions, allowing SQL queries to encode and decode base64 data. Both functions are implemented as SQLite user-defined functions backed by PHP's `base64_encode()` and `base64_decode()`. Because they're registered through `WP_SQLite_PDO_User_Defined_Functions::register_for()`, they work with both the legacy and AST-based drivers automatically. `FROM_BASE64()` returns `NULL` for `NULL` or invalid base64 input. `TO_BASE64()` returns `NULL` for `NULL` input. ## Test plan - Run `composer run test -- --filter 'testFromBase64|testToBase64'` - Verify basic encoding/decoding, NULL handling, empty string handling, and round-trip correctness
2 parents 1a4491c + 7134c20 commit c92910c

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

tests/WP_SQLite_Driver_Tests.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11363,6 +11363,42 @@ public function testVersionFunction(): void {
1136311363
$this->assertSame( '8.0.38', $result[0]->{'VERSION()'} );
1136411364
}
1136511365

11366+
public function testFromBase64Function(): void {
11367+
// Basic decoding.
11368+
$result = $this->assertQuery( "SELECT FROM_BASE64('SGVsbG8gV29ybGQ=') AS decoded" );
11369+
$this->assertSame( 'Hello World', $result[0]->decoded );
11370+
11371+
// Empty string.
11372+
$result = $this->assertQuery( "SELECT FROM_BASE64('') AS decoded" );
11373+
$this->assertSame( '', $result[0]->decoded );
11374+
11375+
// NULL input returns NULL.
11376+
$result = $this->assertQuery( 'SELECT FROM_BASE64(NULL) AS decoded' );
11377+
$this->assertNull( $result[0]->decoded );
11378+
11379+
// Binary data round-trip.
11380+
$result = $this->assertQuery( "SELECT FROM_BASE64(TO_BASE64('binary\\0data')) AS decoded" );
11381+
$this->assertSame( "binary\0data", $result[0]->decoded );
11382+
}
11383+
11384+
public function testToBase64Function(): void {
11385+
// Basic encoding.
11386+
$result = $this->assertQuery( "SELECT TO_BASE64('Hello World') AS encoded" );
11387+
$this->assertSame( 'SGVsbG8gV29ybGQ=', $result[0]->encoded );
11388+
11389+
// Empty string.
11390+
$result = $this->assertQuery( "SELECT TO_BASE64('') AS encoded" );
11391+
$this->assertSame( '', $result[0]->encoded );
11392+
11393+
// NULL input returns NULL.
11394+
$result = $this->assertQuery( 'SELECT TO_BASE64(NULL) AS encoded' );
11395+
$this->assertNull( $result[0]->encoded );
11396+
11397+
// Round-trip: TO_BASE64(FROM_BASE64(x)) = x.
11398+
$result = $this->assertQuery( "SELECT TO_BASE64(FROM_BASE64('dGVzdA==')) AS encoded" );
11399+
$this->assertSame( 'dGVzdA==', $result[0]->encoded );
11400+
}
11401+
1136611402
public function testSubstringFunction(): void {
1136711403
$result = $this->assertQuery( "SELECT SUBSTRING('abcdef', 1, 3) AS s" );
1136811404
$this->assertSame( 'abc', $result[0]->s );

wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public static function register_for( $pdo ): self {
8080
'ucase' => 'ucase',
8181
'lcase' => 'lcase',
8282
'unhex' => 'unhex',
83+
'from_base64' => 'from_base64',
84+
'to_base64' => 'to_base64',
8385
'inet_ntoa' => 'inet_ntoa',
8486
'inet_aton' => 'inet_aton',
8587
'datediff' => 'datediff',
@@ -667,6 +669,44 @@ public function unhex( $number ) {
667669
return pack( 'H*', $number );
668670
}
669671

672+
/**
673+
* Method to emulate MySQL FROM_BASE64() function.
674+
*
675+
* Takes a base64-encoded string and returns the decoded result as a binary
676+
* string. Returns NULL if the argument is NULL or is not a valid base64 string.
677+
*
678+
* @param string|null $str The base64-encoded string.
679+
*
680+
* @return string|null Decoded binary string, or NULL.
681+
*/
682+
public function from_base64( $str ) {
683+
if ( null === $str ) {
684+
return null;
685+
}
686+
$decoded = base64_decode( $str, true );
687+
if ( false === $decoded ) {
688+
return null;
689+
}
690+
return $decoded;
691+
}
692+
693+
/**
694+
* Method to emulate MySQL TO_BASE64() function.
695+
*
696+
* Takes a string and returns a base64-encoded result.
697+
* Returns NULL if the argument is NULL.
698+
*
699+
* @param string|null $str The string to encode.
700+
*
701+
* @return string|null Base64-encoded string, or NULL.
702+
*/
703+
public function to_base64( $str ) {
704+
if ( null === $str ) {
705+
return null;
706+
}
707+
return base64_encode( $str );
708+
}
709+
670710
/**
671711
* Method to emulate MySQL INET_NTOA() function.
672712
*

0 commit comments

Comments
 (0)