Skip to content

Commit e8433be

Browse files
committed
Pad HEX literals to full bytes as required in SQLite
1 parent 0700853 commit e8433be

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

tests/WP_SQLite_Driver_Tests.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6883,6 +6883,22 @@ public function testBinaryLiterals(): void {
68836883

68846884
$result = $this->assertQuery( "SELECT B'0100000101111010'" );
68856885
$this->assertEquals( array( (object) array( "B'0100000101111010'" => 'Az' ) ), $result );
6886+
6887+
// Verify correct padding (0b1 === 0b01 === 0b001 ... === 0x00000001).
6888+
$result = $this->assertQuery( 'SELECT 0b1' );
6889+
$this->assertEquals( array( (object) array( '0b1' => pack( 'H*', '01' ) ) ), $result );
6890+
6891+
$result = $this->assertQuery( 'SELECT 0b01' );
6892+
$this->assertEquals( array( (object) array( '0b01' => pack( 'H*', '01' ) ) ), $result );
6893+
6894+
$result = $this->assertQuery( 'SELECT 0b001' );
6895+
$this->assertEquals( array( (object) array( '0b001' => pack( 'H*', '01' ) ) ), $result );
6896+
6897+
$result = $this->assertQuery( 'SELECT 0b00000001' );
6898+
$this->assertEquals( array( (object) array( '0b00000001' => pack( 'H*', '01' ) ) ), $result );
6899+
6900+
$result = $this->assertQuery( 'SELECT 0b000000001' );
6901+
$this->assertEquals( array( (object) array( '0b000000001' => pack( 'H*', '0001' ) ) ), $result );
68866902
}
68876903

68886904
public function testHexadecimalLiterals(): void {

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2873,7 +2873,18 @@ private function translate_token( WP_MySQL_Token $token ): ?string {
28732873
// b'...' or B'...'
28742874
$value = substr( $value, 2, -1 );
28752875
}
2876-
return sprintf( "x'%s'", base_convert( $value, 2, 16 ) );
2876+
2877+
// Convert the binary string to HEX.
2878+
$hex = base_convert( $value, 2, 16 );
2879+
2880+
/*
2881+
* The "base_convert()" function doesn't add or preserve padding.
2882+
* Let's compute how many bytes we expect and pad the HEX value
2883+
* to full bytes (SQLite requires HEX strings of even length).
2884+
*/
2885+
$byte_count = (int) ceil( strlen( $value ) / 8 );
2886+
$hex = str_pad( $hex, $byte_count * 2, '0', STR_PAD_LEFT );
2887+
return sprintf( "x'%s'", $hex );
28772888
case WP_MySQL_Lexer::HEX_NUMBER:
28782889
/*
28792890
* In MySQL, "0x" prefixed values represent binary literal values,

0 commit comments

Comments
 (0)