From 4c11d0eea734aa30336a9500901a32b3232ac2d7 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Sun, 1 Sep 2024 23:46:23 +0200 Subject: [PATCH] Generate boundary by choosing a random character Instead of rejecting random characters that are not in the boundary character set, draw a random index and select the character at that position. The probability distribution is not perfectly uniform with this method, but reduces the number of calls to rand() by 4 times on average. --- src/form.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/form.cc b/src/form.cc index 4a401a917..2ad743b51 100644 --- a/src/form.cc +++ b/src/form.cc @@ -2,6 +2,7 @@ * File: form.cc * * Copyright 2008 Jorge Arellano Cid + * Copyright 2024 Rodrigo Arias Mallo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1246,20 +1247,23 @@ Dstr *DilloHtmlForm::buildQueryData(DilloHtmlInput *active_submit) return DataStr; } +/** + * Generate a random boundary. + * + * Using 70 random characters makes the probability that it collides + * with a 1 TiB random file less than 1e-117, so there is no need for + * checking for collisions. */ static void generate_boundary(Dstr *boundary) { - for (int i = 0; i < 70; i++) { - /* Extracted from RFC 2046, section 5.1.1. */ - static const char set[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - char s[sizeof " "] = {0}; + /* Extracted from RFC 2046, section 5.1.1. */ + static const char set[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + static const size_t n = strlen(set); - do { - *s = rand(); - } while (!strspn(s, set)); - - dStr_append(boundary, s); + for (int i = 0; i < 70; i++) { + int c = (unsigned char) set[rand() % n]; + dStr_append_c(boundary, c); } }