From fbc7899cabefa92d58cc98cd084fd8042ea43961 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 1 May 2024 13:49:58 +0200 Subject: [PATCH 1/3] Avoid double allocation in _bc_new_num_ex Since the two allocations are tied together anyway, we can just use a single allocation. Moreover, this actually seemed like the intention because the bc_struct allocation already accounted for the length and scale. --- ext/bcmath/libbcmath/src/init.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index cef55324689f9..3c82af5821c71 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -39,13 +39,12 @@ bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent) { /* PHP Change: malloc() -> pemalloc(), removed free_list code */ - bc_num temp = (bc_num) safe_pemalloc(1, sizeof(bc_struct) + length, scale, persistent); + bc_num temp = safe_pemalloc(1, sizeof(bc_struct) + length, scale, persistent); temp->n_sign = PLUS; temp->n_len = length; temp->n_scale = scale; temp->n_refs = 1; - /* PHP Change: malloc() -> pemalloc() */ - temp->n_ptr = (char *) safe_pemalloc(1, length, scale, persistent); + temp->n_ptr = (char *) temp + sizeof(bc_struct); temp->n_value = temp->n_ptr; memset(temp->n_ptr, 0, length + scale); return temp; @@ -61,10 +60,6 @@ void _bc_free_num_ex(bc_num *num, bool persistent) } (*num)->n_refs--; if ((*num)->n_refs == 0) { - if ((*num)->n_ptr) { - /* PHP Change: free() -> pefree(), removed free_list code */ - pefree((*num)->n_ptr, persistent); - } pefree(*num, persistent); } *num = NULL; From 7a03c196062201346d81c4d40b2e27dba914e672 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 1 May 2024 13:59:38 +0200 Subject: [PATCH 2/3] Merge n_value and n_ptr --- ext/bcmath/libbcmath/src/bcmath.h | 7 +------ ext/bcmath/libbcmath/src/init.c | 7 +++---- ext/bcmath/libbcmath/src/recmul.c | 2 -- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 3e005e2072cc3..4b3f3510095a4 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -41,12 +41,7 @@ typedef struct bc_struct *bc_num; typedef struct bc_struct { size_t n_len; /* The number of digits before the decimal point. */ size_t n_scale; /* The number of digits after the decimal point. */ - char *n_ptr; /* The pointer to the actual storage. - If NULL, n_value points to the inside of another number - (bc_multiply...) and should not be "freed." */ - char *n_value; /* The number. Not zero char terminated. - May not point to the same place as n_ptr as - in the case of leading zeros generated. */ + char *n_value; /* The number. Not zero char terminated. */ int n_refs; /* The number of pointers to this number. */ sign n_sign; } bc_struct; diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 3c82af5821c71..959f47c21aa06 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -38,15 +38,14 @@ /* new_num allocates a number and sets fields to known values. */ bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent) { - /* PHP Change: malloc() -> pemalloc(), removed free_list code */ + /* PHP Change: malloc() -> pemalloc(), removed free_list code, merged n_ptr and n_value */ bc_num temp = safe_pemalloc(1, sizeof(bc_struct) + length, scale, persistent); temp->n_sign = PLUS; temp->n_len = length; temp->n_scale = scale; temp->n_refs = 1; - temp->n_ptr = (char *) temp + sizeof(bc_struct); - temp->n_value = temp->n_ptr; - memset(temp->n_ptr, 0, length + scale); + temp->n_value = (char *) temp + sizeof(bc_struct); + memset(temp->n_value, 0, length + scale); return temp; } diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index ec89c461fa188..fe6a34817d99b 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -56,7 +56,6 @@ static bc_num new_sub_num(size_t length, size_t scale, char *value) temp->n_len = length; temp->n_scale = scale; temp->n_refs = 1; - temp->n_ptr = NULL; temp->n_value = value; return temp; } @@ -273,7 +272,6 @@ void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale) /* Assign to prod and clean up the number. */ pval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - pval->n_value = pval->n_ptr; pval->n_len = len2 + len1 + 1 - full_scale; pval->n_scale = prod_scale; _bc_rm_leading_zeros(pval); From a7d1863701a2d8aebff1c0f7336c86eca43da512 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 1 May 2024 13:59:59 +0200 Subject: [PATCH 3/3] Use an unsigned number for the refcount of bcmath objects --- ext/bcmath/libbcmath/src/bcmath.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 4b3f3510095a4..9cd611a6fd5b3 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -39,11 +39,11 @@ typedef enum {PLUS, MINUS} sign; typedef struct bc_struct *bc_num; typedef struct bc_struct { - size_t n_len; /* The number of digits before the decimal point. */ - size_t n_scale; /* The number of digits after the decimal point. */ - char *n_value; /* The number. Not zero char terminated. */ - int n_refs; /* The number of pointers to this number. */ - sign n_sign; + size_t n_len; /* The number of digits before the decimal point. */ + size_t n_scale; /* The number of digits after the decimal point. */ + char *n_value; /* The number. Not zero char terminated. */ + unsigned int n_refs; /* The number of pointers to this number. */ + sign n_sign; } bc_struct; #ifdef HAVE_CONFIG_H