Skip to content

Instantly share code, notes, and snippets.

@nielsdos
Created April 30, 2024 21:16
Show Gist options
  • Save nielsdos/a485ace9471c56ea6515dbf8962ce250 to your computer and use it in GitHub Desktop.
Save nielsdos/a485ace9471c56ea6515dbf8962ce250 to your computer and use it in GitHub Desktop.
diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
index 1e91840ab9f..59abeeffcaa 100644
--- a/ext/bcmath/libbcmath/src/str2num.c
+++ b/ext/bcmath/libbcmath/src/str2num.c
@@ -35,6 +35,32 @@
/* Convert strings to bc numbers. Base 10 only.*/
+#define SWAR_ONES (~((size_t) 0) / 0xFF)
+#define SWAR_REPEAT(x) (SWAR_ONES * (x))
+
+static char *bc_copy_number_values(char *dest, const char *source, const char *source_end)
+{
+ while (source + sizeof(size_t) <= source_end) {
+ size_t bytes;
+ memcpy(&bytes, source, sizeof(bytes));
+
+ size_t mask = SWAR_REPEAT('0');
+ bytes -= mask;
+ memcpy(dest, &bytes, sizeof(bytes));
+
+ source += sizeof(size_t);
+ dest += sizeof(size_t);
+ }
+
+ while (source < source_end) {
+ *dest = CH_VAL(*source);
+ dest++;
+ source++;
+ }
+
+ return dest;
+}
+
bool bc_str2num(bc_num *num, char *str, size_t scale)
{
size_t digits = 0;
@@ -109,25 +135,13 @@ bool bc_str2num(bc_num *num, char *str, size_t scale)
if (zero_int) {
nptr++;
if (str_scale > 0) {
- while (fractional_ptr < fractional_end) {
- *nptr = CH_VAL(*fractional_ptr);
- nptr++;
- fractional_ptr++;
- }
+ nptr = bc_copy_number_values(nptr, fractional_ptr, fractional_end);
}
} else {
- integer_end = integer_ptr + digits - 1;
- while (integer_ptr <= integer_end) {
- *nptr = CH_VAL(*integer_ptr);
- nptr++;
- integer_ptr++;
- }
+ integer_end = integer_ptr + digits;
+ nptr = bc_copy_number_values(nptr, integer_ptr, integer_end);
if (str_scale > 0) {
- while (fractional_ptr < fractional_end) {
- *nptr = CH_VAL(*fractional_ptr);
- nptr++;
- fractional_ptr++;
- }
+ nptr = bc_copy_number_values(nptr, fractional_ptr, fractional_end);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment