Skip to content

Commit b3c447d

Browse files
committed
add $padding option to base64_encode
1 parent 530e0d6 commit b3c447d

File tree

5 files changed

+83
-56
lines changed

5 files changed

+83
-56
lines changed

ext/standard/base64.c

+36-29
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static zend_always_inline unsigned char *neon_base64_encode(const unsigned char
120120
}
121121
#endif /* defined(__aarch64__) || defined(_M_ARM64) */
122122

123-
static zend_always_inline unsigned char *php_base64_encode_impl(const unsigned char *in, size_t inl, unsigned char *out) /* {{{ */
123+
static zend_always_inline unsigned char *php_base64_encode_impl(const unsigned char *in, size_t inl, unsigned char *out, zend_long flags) /* {{{ */
124124
{
125125
#if defined(__aarch64__) || defined(_M_ARM64)
126126
if (inl >= 16 * 3) {
@@ -147,11 +147,15 @@ static zend_always_inline unsigned char *php_base64_encode_impl(const unsigned c
147147
if (inl > 1) {
148148
*out++ = base64_table[((in[0] & 0x03) << 4) + (in[1] >> 4)];
149149
*out++ = base64_table[(in[1] & 0x0f) << 2];
150-
*out++ = base64_pad;
150+
if ((flags & PHP_BASE64_NO_PADDING) == 0) {
151+
*out++ = base64_pad;
152+
}
151153
} else {
152154
*out++ = base64_table[(in[0] & 0x03) << 4];
153-
*out++ = base64_pad;
154-
*out++ = base64_pad;
155+
if ((flags & PHP_BASE64_NO_PADDING) == 0) {
156+
*out++ = base64_pad;
157+
*out++ = base64_pad;
158+
}
155159
}
156160
}
157161

@@ -381,32 +385,32 @@ static zend_always_inline int php_base64_decode_impl(const unsigned char *in, si
381385
# include "Zend/zend_cpuinfo.h"
382386

383387
# if BASE64_INTRIN_AVX512_FUNC_PROTO || BASE64_INTRIN_AVX512_FUNC_PTR
384-
ZEND_INTRIN_AVX512_FUNC_DECL(zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length));
388+
ZEND_INTRIN_AVX512_FUNC_DECL(zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length, zend_long flags));
385389
ZEND_INTRIN_AVX512_FUNC_DECL(zend_string *php_base64_decode_ex_avx512(const unsigned char *str, size_t length, bool strict));
386390
# endif
387391
# if BASE64_INTRIN_AVX512_VBMI_FUNC_PROTO || BASE64_INTRIN_AVX512_VBMI_FUNC_PTR
388-
ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t length));
392+
ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t length, zend_long flags));
389393
ZEND_INTRIN_AVX512_VBMI_FUNC_DECL(zend_string *php_base64_decode_ex_avx512_vbmi(const unsigned char *str, size_t length, bool strict));
390394
# endif
391395

392396
# if ZEND_INTRIN_AVX2_RESOLVER
393-
ZEND_INTRIN_AVX2_FUNC_DECL(zend_string *php_base64_encode_avx2(const unsigned char *str, size_t length));
397+
ZEND_INTRIN_AVX2_FUNC_DECL(zend_string *php_base64_encode_avx2(const unsigned char *str, size_t length, zend_long flags));
394398
ZEND_INTRIN_AVX2_FUNC_DECL(zend_string *php_base64_decode_ex_avx2(const unsigned char *str, size_t length, bool strict));
395399
# endif
396400

397401
# if ZEND_INTRIN_SSSE3_RESOLVER
398-
ZEND_INTRIN_SSSE3_FUNC_DECL(zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length));
402+
ZEND_INTRIN_SSSE3_FUNC_DECL(zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length, zend_long flags));
399403
ZEND_INTRIN_SSSE3_FUNC_DECL(zend_string *php_base64_decode_ex_ssse3(const unsigned char *str, size_t length, bool strict));
400404
# endif
401405

402-
zend_string *php_base64_encode_default(const unsigned char *str, size_t length);
406+
zend_string *php_base64_encode_default(const unsigned char *str, size_t length, zend_long flags);
403407
zend_string *php_base64_decode_ex_default(const unsigned char *str, size_t length, bool strict);
404408

405409
# if (ZEND_INTRIN_AVX2_FUNC_PROTO || ZEND_INTRIN_SSSE3_FUNC_PROTO || BASE64_INTRIN_AVX512_FUNC_PROTO || BASE64_INTRIN_AVX512_VBMI_FUNC_PROTO)
406-
PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) __attribute__((ifunc("resolve_base64_encode")));
410+
PHPAPI zend_string *php_base64_encode_ex(const unsigned char *str, size_t length, zend_long flags) __attribute__((ifunc("resolve_base64_encode")));
407411
PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, bool strict) __attribute__((ifunc("resolve_base64_decode")));
408412

409-
typedef zend_string *(*base64_encode_func_t)(const unsigned char *, size_t);
413+
typedef zend_string *(*base64_encode_func_t)(const unsigned char *, size_t, zend_long flags);
410414
typedef zend_string *(*base64_decode_func_t)(const unsigned char *, size_t, bool);
411415

412416
ZEND_NO_SANITIZE_ADDRESS
@@ -462,11 +466,11 @@ static base64_decode_func_t resolve_base64_decode(void) {
462466
}
463467
# else /* (ZEND_INTRIN_AVX2_FUNC_PROTO || ZEND_INTRIN_SSSE3_FUNC_PROTO) */
464468

465-
PHPAPI zend_string *(*php_base64_encode_ptr)(const unsigned char *str, size_t length) = NULL;
469+
PHPAPI zend_string *(*php_base64_encode_ptr)(const unsigned char *str, size_t length, zend_long flags) = NULL;
466470
PHPAPI zend_string *(*php_base64_decode_ex_ptr)(const unsigned char *str, size_t length, bool strict) = NULL;
467471

468-
PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) {
469-
return php_base64_encode_ptr(str, length);
472+
PHPAPI zend_string *php_base64_encode_ex(const unsigned char *str, size_t length, zend_long flags) {
473+
return php_base64_encode_ptr(str, length, flags);
470474
}
471475
PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, bool strict) {
472476
return php_base64_decode_ex_ptr(str, length, strict);
@@ -508,7 +512,7 @@ PHP_MINIT_FUNCTION(base64_intrin)
508512
#endif /* ZEND_INTRIN_AVX2_NATIVE */
509513

510514
#if BASE64_INTRIN_AVX512_VBMI_FUNC_PROTO || BASE64_INTRIN_AVX512_VBMI_FUNC_PTR
511-
zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t length)
515+
zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t length, zend_long flags)
512516
{
513517
const unsigned char *c = str;
514518
unsigned char *o;
@@ -545,7 +549,7 @@ zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t leng
545549
length -= 48;
546550
}
547551

548-
o = php_base64_encode_impl(c, length, o);
552+
o = php_base64_encode_impl(c, length, o, flags);
549553

550554
ZSTR_LEN(result) = (o - (unsigned char *)ZSTR_VAL(result));
551555

@@ -618,7 +622,7 @@ zend_string *php_base64_decode_ex_avx512_vbmi(const unsigned char *str, size_t l
618622
#endif
619623

620624
#if BASE64_INTRIN_AVX512_FUNC_PROTO || BASE64_INTRIN_AVX512_FUNC_PTR
621-
zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length)
625+
zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length, zend_long flags)
622626
{
623627
const unsigned char *c = str;
624628
unsigned char *o;
@@ -665,7 +669,7 @@ zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length)
665669
length -= 48;
666670
}
667671

668-
o = php_base64_encode_impl(c, length, o);
672+
o = php_base64_encode_impl(c, length, o, flags);
669673

670674
ZSTR_LEN(result) = (o - (unsigned char *)ZSTR_VAL(result));
671675

@@ -900,11 +904,11 @@ static __m128i php_base64_encode_ssse3_translate(__m128i in)
900904

901905
#if ZEND_INTRIN_AVX2_NATIVE || ZEND_INTRIN_AVX2_RESOLVER || ZEND_INTRIN_SSSE3_NATIVE || ZEND_INTRIN_SSSE3_RESOLVER
902906
# if ZEND_INTRIN_AVX2_NATIVE || ZEND_INTRIN_SSSE3_NATIVE
903-
PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length)
907+
PHPAPI zend_string *php_base64_encode_ex(const unsigned char *str, size_t length, zend_long flags)
904908
# elif ZEND_INTRIN_AVX2_RESOLVER
905-
zend_string *php_base64_encode_avx2(const unsigned char *str, size_t length)
909+
zend_string *php_base64_encode_avx2(const unsigned char *str, size_t length, zend_long flags)
906910
# else /* ZEND_INTRIN_SSSE3_RESOLVER */
907-
zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length)
911+
zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length, zend_long flags)
908912
# endif
909913
{
910914
const unsigned char *c = str;
@@ -938,15 +942,15 @@ zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length)
938942
PHP_BASE64_ENCODE_SSSE3_LOOP;
939943
# endif
940944

941-
o = php_base64_encode_impl(c, length, o);
945+
o = php_base64_encode_impl(c, length, o, flags);
942946

943947
ZSTR_LEN(result) = (o - (unsigned char *)ZSTR_VAL(result));
944948

945949
return result;
946950
}
947951

948952
# if ZEND_INTRIN_SSSE3_RESOLVER && ZEND_INTRIN_AVX2_RESOLVER
949-
zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length)
953+
zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length, zend_long flags)
950954
{
951955
const unsigned char *c = str;
952956
unsigned char *o;
@@ -957,7 +961,7 @@ zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length)
957961

958962
PHP_BASE64_ENCODE_SSSE3_LOOP;
959963

960-
o = php_base64_encode_impl(c, length, o);
964+
o = php_base64_encode_impl(c, length, o, flags);
961965

962966
ZSTR_LEN(result) = (o - (unsigned char *)ZSTR_VAL(result));
963967

@@ -1180,9 +1184,9 @@ zend_string *php_base64_decode_ex_ssse3(const unsigned char *str, size_t length,
11801184

11811185
#if !ZEND_INTRIN_AVX2_NATIVE && !ZEND_INTRIN_SSSE3_NATIVE
11821186
#if ZEND_INTRIN_AVX2_RESOLVER || ZEND_INTRIN_SSSE3_RESOLVER
1183-
zend_string *php_base64_encode_default(const unsigned char *str, size_t length)
1187+
zend_string *php_base64_encode_default(const unsigned char *str, size_t length, zend_long flags)
11841188
#else
1185-
PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length)
1189+
PHPAPI zend_string *php_base64_encode_ex(const unsigned char *str, size_t length, zend_long flags)
11861190
#endif
11871191
{
11881192
unsigned char *p;
@@ -1191,7 +1195,7 @@ PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length)
11911195
result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
11921196
p = (unsigned char *)ZSTR_VAL(result);
11931197

1194-
p = php_base64_encode_impl(str, length, p);
1198+
p = php_base64_encode_impl(str, length, p, flags);
11951199

11961200
ZSTR_LEN(result) = (p - (unsigned char *)ZSTR_VAL(result));
11971201

@@ -1229,12 +1233,15 @@ PHP_FUNCTION(base64_encode)
12291233
char *str;
12301234
size_t str_len;
12311235
zend_string *result;
1236+
bool padding = true;
12321237

1233-
ZEND_PARSE_PARAMETERS_START(1, 1)
1238+
ZEND_PARSE_PARAMETERS_START(1, 2)
12341239
Z_PARAM_STRING(str, str_len)
1240+
Z_PARAM_OPTIONAL
1241+
Z_PARAM_BOOL(padding)
12351242
ZEND_PARSE_PARAMETERS_END();
12361243

1237-
result = php_base64_encode((unsigned char*)str, str_len);
1244+
result = php_base64_encode_ex((unsigned char*)str, str_len, (padding ? 0 : PHP_BASE64_NO_PADDING));
12381245
RETURN_STR(result);
12391246
}
12401247
/* }}} */

ext/standard/base64.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,15 @@
6161
PHP_MINIT_FUNCTION(base64_intrin);
6262
#endif
6363

64-
PHPAPI extern zend_string *php_base64_encode(const unsigned char *, size_t);
64+
/* php_base64_encode_ex flags */
65+
#define PHP_BASE64_NO_PADDING 1
66+
67+
PHPAPI extern zend_string *php_base64_encode_ex(const unsigned char *, size_t, zend_long flags);
6568
PHPAPI extern zend_string *php_base64_decode_ex(const unsigned char *, size_t, bool);
6669

70+
static inline zend_string *php_base64_encode(const unsigned char *str, size_t len) {
71+
return php_base64_encode_ex(str, len, 0);
72+
}
6773
static inline zend_string *php_base64_encode_str(const zend_string *str) {
6874
return php_base64_encode((const unsigned char*)(ZSTR_VAL(str)), ZSTR_LEN(str));
6975
}

ext/standard/basic_functions.stub.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1930,7 +1930,7 @@ function array_is_list(array $array): bool {}
19301930
* @compile-time-eval
19311931
* @refcount 1
19321932
*/
1933-
function base64_encode(string $string): string {}
1933+
function base64_encode(string $string, bool $padding = true): string {}
19341934

19351935
/**
19361936
* @compile-time-eval

ext/standard/basic_functions_arginfo.h

+28-25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)