diff --git a/ext/standard/tests/strings/uuencode_error.phpt b/ext/standard/tests/strings/uuencode_error.phpt new file mode 100644 index 000000000000..f58eb8752c5f --- /dev/null +++ b/ext/standard/tests/strings/uuencode_error.phpt @@ -0,0 +1,40 @@ +--TEST-- +convert_uudecode() with invalid data +--FILE-- + '', + 'length character only' => '!', + 'truncated group' => '!80', + 'full line announced, no data' => 'M', + 'maximum line announced, no data' => '_', + 'full line announced, short data' => 'M' . str_repeat('abcd', 5), + 'plain text' => 'not uuencoded', + 'multi-line, cut inside first line' => substr($encoded100, 0, 30), + 'multi-line, cut inside second line' => substr($encoded100, 0, 92), + 'multi-line, cut inside last line' => substr($encoded100, 0, 132), +]; +foreach ($invalid as $label => $input) { + $warning = 'no warning'; + $result = convert_uudecode($input); + echo $label, ": ", var_export($result, true), ", ", $warning, "\n"; +} +?> +--EXPECT-- +empty string: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +length character only: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +truncated group: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +full line announced, no data: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +maximum line announced, no data: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +full line announced, short data: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +plain text: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +multi-line, cut inside first line: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +multi-line, cut inside second line: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string +multi-line, cut inside last line: false, convert_uudecode(): Argument #1 ($string) is not a valid uuencoded string diff --git a/ext/standard/tests/strings/uuencode_rt.phpt b/ext/standard/tests/strings/uuencode_rt.phpt new file mode 100644 index 000000000000..e9354734eb85 --- /dev/null +++ b/ext/standard/tests/strings/uuencode_rt.phpt @@ -0,0 +1,48 @@ +--TEST-- +convert_uuencode() and convert_uudecode() round trip +--FILE-- + ["", ['`']], + '1 byte' => ["a", ['!80``', '`']], + '2 bytes' => ["ab", ['"86(`', '`']], + '3 bytes' => ["abc", ['#86)C', '`']], + '4 bytes' => ["abcd", ['$86)C9```', '`']], + '5 bytes' => ["abcde", ['%86)C9&4`', '`']], + '6 bytes' => ["abcdef", ['&86)C9&5F', '`']], + '1 NUL' => ["\x00", ['!````', '`']], + '2 NULs' => ["\x00\x00", ['"````', '`']], + '3 NULs' => ["\x00\x00\x00", ['#````', '`']], + '4 NULs' => ["\x00\x00\x00\x00", ['$````````', '`']], + '1 x 0xFF' => ["\xff", ['!_P``', '`']], + '2 x 0xFF' => ["\xff\xff", ['"__\\`', '`']], + '3 x 0xFF' => ["\xff\xff\xff", ['#____', '`']], + '4 x 0xFF' => ["\xff\xff\xff\xff", ['$_____P``', '`']], + '5 x 0xFF' => ["\xff\xff\xff\xff\xff", ['%______\\`', '`']], + 'manual example' => ["test\x0atext text\x0d\x0a", ['0=&5S=`IT97AT(\'1E>\'0-"@``', '`']], + '44 bytes' => [str_repeat('a', 44), ['L86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86$`', '`']], + '45 bytes (one full line)' => [str_repeat('a', 45), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '`']], + '46 bytes' => [str_repeat('a', 46), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '!80``', '`']], + '47 bytes' => [str_repeat('a', 47), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '"86$`', '`']], + '48 bytes' => [str_repeat('a', 48), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '#86%A', '`']], + '90 bytes (two full lines)' => [str_repeat('a', 90), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', 'M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '`']], + '93 bytes' => [str_repeat('a', 93), ['M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', 'M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A', '#86%A', '`']], +]; + +$failures = []; +foreach ($vectors as $label => [$input, $lines]) { + $expected = implode("\n", $lines) . "\n"; + if (convert_uuencode($input) !== $expected) { + $failures[] = "encode: $label"; + } + if (convert_uudecode($expected) !== $input) { + $failures[] = "decode: $label"; + } +} +var_dump($failures); + +?> +--EXPECT-- +array(0) { +} \ No newline at end of file diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c index 6dc2848fec0f..762fd32329b3 100644 --- a/ext/standard/uuencode.c +++ b/ext/standard/uuencode.c @@ -48,8 +48,6 @@ * SUCH DAMAGE. */ -#include - #include "php.h" #include "php_uuencode.h" @@ -80,7 +78,7 @@ PHPAPI zend_string *php_uuencode(const char *src, size_t src_len) /* {{{ */ ee = e; len = ee - s; if (len % 3) { - ee = s + (int) (floor((double)len / 3) * 3); + ee = s + (len / 3) * 3; } } *p++ = PHP_UU_ENC(len); @@ -135,7 +133,7 @@ PHPAPI zend_string *php_uudecode(const char *src, size_t src_len) /* {{{ */ return NULL; } - dest = zend_string_alloc((size_t) ceil(src_len * 0.75), 0); + dest = zend_string_alloc(src_len - src_len / 4, 0); p = ZSTR_VAL(dest); s = src; e = src + src_len; @@ -151,7 +149,7 @@ PHPAPI zend_string *php_uudecode(const char *src, size_t src_len) /* {{{ */ total_len += len; - ee = s + (len == 45 ? 60 : (int) floor(len * 1.33)); + ee = s + ((len + 2) / 3) * 4; /* sanity check */ if (ee > e) { goto err;