From d8927362a2cadd1be09b4d0a1be0049bf63d44cf Mon Sep 17 00:00:00 2001 From: Jesse Overright Date: Wed, 3 Sep 2014 22:21:50 -0500 Subject: [PATCH 1/5] Adds fallback for mb_strlen, fixes #1370 --- lib/cli/cli.php | 4 +++- lib/cli/table/Ascii.php | 47 +++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/lib/cli/cli.php b/lib/cli/cli.php index 5fe2604..c63ff58 100755 --- a/lib/cli/cli.php +++ b/lib/cli/cli.php @@ -159,7 +159,9 @@ function menu( $items, $default = null, $title = 'Choose an item' ) { * @return int Numeric value that represents the string's length */ function safe_strlen( $str ) { - return mb_strlen( $str, mb_detect_encoding( $str ) ); + if ( function_exists( 'mb_strlen' ) ) + return mb_strlen( $str, mb_detect_encoding( $str ) ); + else return strlen( $str ); } /** diff --git a/lib/cli/table/Ascii.php b/lib/cli/table/Ascii.php index 2270a5d..3ce07d9 100644 --- a/lib/cli/table/Ascii.php +++ b/lib/cli/table/Ascii.php @@ -132,21 +132,40 @@ public function row( array $row ) { $col_width = $this->_widths[ $col ]; $original_val_width = Colors::length( $value ); if ( $original_val_width > $col_width ) { - $row[ $col ] = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); - $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); - $i = 0; - do { - $extra_value = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); - $val_width = mb_strlen( $extra_value, mb_detect_encoding( $extra_value ) ); - if ( $val_width ) { - $extra_rows[ $col ][] = $extra_value; - $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); - $i++; - if ( $i > $extra_row_count ) { - $extra_row_count = $i; + if ( function_exists( 'mb_substr' ) ) { + $row[ $col ] = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); + $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); + $i = 0; + do { + $extra_value = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); + $val_width = mb_strlen( $extra_value, mb_detect_encoding( $extra_value ) ); + if ( $val_width ) { + $extra_rows[ $col ][] = $extra_value; + $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); + $i++; + if ( $i > $extra_row_count ) { + $extra_row_count = $i; + } } - } - } while( $value ); + } while( $value ); + } else { + $row[ $col ] = substr( $value, 0, $col_width ); + $value = substr( $value, $col_width, $original_val_width ); + $i = 0; + do { + $extra_value = substr( $value, 0, $col_width ); + $val_width = strlen( $extra_value ); + if ( $val_width ) { + $extra_rows[ $col ][] = $extra_value; + $value = substr( $value, $col_width, $original_val_width ); + $i++; + if ( $i > $extra_row_count ) { + $extra_row_count = $i; + } + } + } while( $value ); + } + } } From 5a28151d8e132d96cd880e479ce349a2ba978c3c Mon Sep 17 00:00:00 2001 From: Jesse Overright Date: Thu, 4 Sep 2014 21:36:13 -0500 Subject: [PATCH 2/5] Added safe_strlen wrapper function and updated to wordpress coding standards --- lib/cli/cli.php | 28 +++++++++++++++++++++--- lib/cli/table/Ascii.php | 47 ++++++++++++----------------------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/lib/cli/cli.php b/lib/cli/cli.php index c63ff58..e552865 100755 --- a/lib/cli/cli.php +++ b/lib/cli/cli.php @@ -159,9 +159,31 @@ function menu( $items, $default = null, $title = 'Choose an item' ) { * @return int Numeric value that represents the string's length */ function safe_strlen( $str ) { - if ( function_exists( 'mb_strlen' ) ) - return mb_strlen( $str, mb_detect_encoding( $str ) ); - else return strlen( $str ); + if ( function_exists( 'mb_strlen' ) ) { + $length = mb_strlen( $str, mb_detect_encoding( $str ) ); + } else { + $length = strlen( $str ); + } + + return $length; +} + +/** + * An encoding-safe way of getting a substring. + * + * @param string $string The input string + * @param int $start The starting position of the substring + * @param boolean $length Maximum length of the substring + * @return string Substring of string specified by start and length parameters + */ +function safe_substr( $string, $start, $length = false ) { + if ( function_exists( 'mb_substr' ) ) { + $substr = mb_substr( $string, $start, $length, mb_detect_encoding( $string ) ); + } else { + $substr = substr( $string, $start, $length ); + } + + return $substr; } /** diff --git a/lib/cli/table/Ascii.php b/lib/cli/table/Ascii.php index 3ce07d9..faf2278 100644 --- a/lib/cli/table/Ascii.php +++ b/lib/cli/table/Ascii.php @@ -132,40 +132,21 @@ public function row( array $row ) { $col_width = $this->_widths[ $col ]; $original_val_width = Colors::length( $value ); if ( $original_val_width > $col_width ) { - if ( function_exists( 'mb_substr' ) ) { - $row[ $col ] = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); - $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); - $i = 0; - do { - $extra_value = mb_substr( $value, 0, $col_width, mb_detect_encoding( $value ) ); - $val_width = mb_strlen( $extra_value, mb_detect_encoding( $extra_value ) ); - if ( $val_width ) { - $extra_rows[ $col ][] = $extra_value; - $value = mb_substr( $value, $col_width, $original_val_width, mb_detect_encoding( $value ) ); - $i++; - if ( $i > $extra_row_count ) { - $extra_row_count = $i; - } + $row[ $col ] = \cli\safe_substr( $value, 0, $col_width ); + $value = \cli\safe_substr( $value, $col_width, $original_val_width ); + $i = 0; + do { + $extra_value = \cli\safe_substr( $value, 0, $col_width ); + $val_width = \cli\safe_strlen( $extra_value ); + if ( $val_width ) { + $extra_rows[ $col ][] = $extra_value; + $value = \cli\safe_substr( $value, $col_width, $original_val_width ); + $i++; + if ( $i > $extra_row_count ) { + $extra_row_count = $i; } - } while( $value ); - } else { - $row[ $col ] = substr( $value, 0, $col_width ); - $value = substr( $value, $col_width, $original_val_width ); - $i = 0; - do { - $extra_value = substr( $value, 0, $col_width ); - $val_width = strlen( $extra_value ); - if ( $val_width ) { - $extra_rows[ $col ][] = $extra_value; - $value = substr( $value, $col_width, $original_val_width ); - $i++; - if ( $i > $extra_row_count ) { - $extra_row_count = $i; - } - } - } while( $value ); - } - + } + } while( $value ); } } From 4d67f6ef1c03541aa335d58198fc645864549de7 Mon Sep 17 00:00:00 2001 From: Jesse Overright Date: Sun, 7 Sep 2014 16:25:03 -0500 Subject: [PATCH 3/5] Updated safe_strlen & safe_substr to trigger PHP notice if mb_string extensions are missing and encoding is present --- lib/cli/cli.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/cli/cli.php b/lib/cli/cli.php index e552865..f449727 100755 --- a/lib/cli/cli.php +++ b/lib/cli/cli.php @@ -153,7 +153,8 @@ function menu( $items, $default = null, $title = 'Choose an item' ) { } /** - * An encoding-safe way of getting string length. + * Attempts an encoding-safe way of getting string length. If mb_string extensions aren't + * installed, falls back to basic strlen if no encoding is present * * @param string The string to check * @return int Numeric value that represents the string's length @@ -162,6 +163,9 @@ function safe_strlen( $str ) { if ( function_exists( 'mb_strlen' ) ) { $length = mb_strlen( $str, mb_detect_encoding( $str ) ); } else { + // iconv will return PHP notice if non-ascii characters are present in input string + $str = iconv( 'ASCII' , 'ASCII', $str ); + $length = strlen( $str ); } @@ -169,18 +173,22 @@ function safe_strlen( $str ) { } /** - * An encoding-safe way of getting a substring. + * Attempts an encoding-safe way of getting a substring. If mb_string extensions aren't + * installed, falls back to ascii substring if no encoding is present * - * @param string $string The input string + * @param string $str The input string * @param int $start The starting position of the substring * @param boolean $length Maximum length of the substring * @return string Substring of string specified by start and length parameters */ -function safe_substr( $string, $start, $length = false ) { +function safe_substr( $str, $start, $length = false ) { if ( function_exists( 'mb_substr' ) ) { - $substr = mb_substr( $string, $start, $length, mb_detect_encoding( $string ) ); + $substr = mb_substr( $str, $start, $length, mb_detect_encoding( $str ) ); } else { - $substr = substr( $string, $start, $length ); + // iconv will return PHP notice if non-ascii characters are present in input string + $str = iconv( 'ASCII' , 'ASCII', $str ); + + $substr = substr( $str, $start, $length ); } return $substr; From 71bf7a704e17937cd70b9464b8bb1e96bf89fefb Mon Sep 17 00:00:00 2001 From: Jesse Overright Date: Sun, 7 Sep 2014 16:25:35 -0500 Subject: [PATCH 4/5] Added tests for cli/safe_substr() --- tests/test-cli.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test-cli.php b/tests/test-cli.php index 36b823f..eb7e338 100644 --- a/tests/test-cli.php +++ b/tests/test-cli.php @@ -24,6 +24,13 @@ function test_encoded_string_length() { } + function test_encoded_substr() { + + $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'hello', 0, 2 ) ), 'he' ); + $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'óra' , 0, 2 ) ), 'ór' ); + + } + function test_colorized_string_length() { $this->assertEquals( \cli\Colors::length( \cli\Colors::colorize( '%Gx%n', true ) ), 1 ); } From 3a3adb48a24952ab832983418d789cfcc66e0803 Mon Sep 17 00:00:00 2001 From: Jesse Overright Date: Sun, 7 Sep 2014 16:43:33 -0500 Subject: [PATCH 5/5] Fixed typo in test_encoded_substr --- tests/test-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-cli.php b/tests/test-cli.php index eb7e338..06540f3 100644 --- a/tests/test-cli.php +++ b/tests/test-cli.php @@ -26,9 +26,9 @@ function test_encoded_string_length() { function test_encoded_substr() { - $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'hello', 0, 2 ) ), 'he' ); - $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'óra' , 0, 2 ) ), 'ór' ); - + $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'hello', 6), 0, 2 ), 'he' ); + $this->assertEquals( \cli\safe_substr( \cli\Colors::pad( 'óra', 6), 0, 2 ), 'ór' ); + } function test_colorized_string_length() {