return l + OPENSSL_strlcpy(dst, src, size);
}
+/**
+ * @brief Converts a string to an unsigned long integer.
+ *
+ * This function attempts to convert a string representation of a number
+ * to an unsigned long integer, given a specified base. It also provides
+ * error checking and reports whether the conversion was successful.
+ * This function is just a wrapper around the POSIX strtoul function with
+ * additional error checking. This implies that errno for the caller is set
+ * on calls to this function.
+ *
+ * @param str The string containing the representation of the number.
+ * @param endptr A pointer to a pointer to character. If not NULL, it is set
+ * to the character immediately following the number in the
+ * string.
+ * @param base The base to use for the conversion, which must be between 2,
+ * and 36 inclusive, or be the special value 0. If the base is 0,
+ * the actual base is determined by the format of the initial
+ * characters of the string.
+ * @param num A pointer to an unsigned long where the result of the
+ * conversion is stored.
+ *
+ * @return 1 if the conversion was successful, 0 otherwise. Conversion is
+ * considered unsuccessful if no digits were consumed or if an error
+ * occurred during conversion.
+ *
+ * @note It is the caller's responsibility to check if the conversion is
+ * correct based on the expected consumption of the string as reported
+ * by endptr.
+ */
+int OPENSSL_strtoul(const char *str, char **endptr, int base,
+ unsigned long *num)
+{
+ char *tmp_endptr;
+ char **internal_endptr = endptr == NULL ? &tmp_endptr : endptr;
+
+ errno = 0;
+
+ *internal_endptr = (char *)str;
+
+ if (num == NULL)
+ return 0;
+
+ if (str == NULL)
+ return 0;
+
+ /* Fail on negative input */
+ if (*str == '-')
+ return 0;
+
+ *num = strtoul(str, internal_endptr, base);
+ /*
+ * We return error from this function under the following conditions
+ * 1) If strtoul itself returned an error in translation
+ * 2) If the caller didn't pass in an endptr value, and **internal_endptr
+ * doesn't point to '\0'. The implication here is that if the caller
+ * doesn't care how much of a string is consumed, they expect the entire
+ * string to be consumed. As such, no pointing to the NULL terminator
+ * means there was some part of the string left over after translation
+ * 3) If no bytes of the string were consumed
+ */
+ if (errno != 0 ||
+ (endptr == NULL && **internal_endptr != '\0') ||
+ (str == *internal_endptr))
+ return 0;
+
+ return 1;
+}
+
int OPENSSL_hexchar2int(unsigned char c)
{
#ifdef CHARSET_EBCDIC
OPENSSL_free, OPENSSL_clear_realloc, OPENSSL_clear_free, OPENSSL_cleanse,
CRYPTO_malloc, CRYPTO_aligned_alloc, CRYPTO_zalloc, CRYPTO_realloc, CRYPTO_free,
OPENSSL_strdup, OPENSSL_strndup,
-OPENSSL_memdup, OPENSSL_strlcpy, OPENSSL_strlcat,
+OPENSSL_memdup, OPENSSL_strlcpy, OPENSSL_strlcat, OPENSSL_strtoul,
CRYPTO_strdup, CRYPTO_strndup,
OPENSSL_mem_debug_push, OPENSSL_mem_debug_pop,
CRYPTO_mem_debug_push, CRYPTO_mem_debug_pop,
char *OPENSSL_strndup(const char *str, size_t s);
size_t OPENSSL_strlcat(char *dst, const char *src, size_t size);
size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size);
+ int OPENSSL_strtoul(char *src, char **endptr, int base, unsigned long *num);
void *OPENSSL_memdup(void *data, size_t s);
void *OPENSSL_clear_realloc(void *p, size_t old_len, size_t num);
void OPENSSL_clear_free(void *str, size_t num);
OPENSSL_strlcat() and OPENSSL_strnlen() are equivalents of the common C
library functions and are provided for portability.
+OPENSSL_strtoul() is a wrapper around the POSIX function strtoul, with the same
+behaviors listed in the POSIX documentation, with the additional behavior that
+it validates the input I<str> and I<num> parameters for not being NULL, and confirms
+that at least a single byte of input has been consumed in the translation,
+returning an error in the event that no bytes were consumed.
+
If no allocations have been done, it is possible to "swap out" the default
implementations for OPENSSL_malloc(), OPENSSL_realloc() and OPENSSL_free()
and replace them with alternate versions.
CRYPTO_mem_debug_push(), and CRYPTO_mem_debug_pop()
are deprecated and are no-ops that always return 0.
+OPENSSL_strtoul() returns 1 on success and 0 in the event that an error has
+occured. Specifically, 0 is returned in the following events:
+
+=over 4
+
+=item *
+
+If the underlying call to strtoul returned a non zero errno value
+
+=item *
+
+If the translation did not consume the entire input string, and the passed
+endptr value was NULL
+
+=item *
+
+If no characters were consumed in the translation
+
+=back
+
+Note that a success condition does not imply that the expected
+translation has been preformed. For instance calling
+
+ OPENSSL_strtoul("0x12345", &endptr, 10, &num);
+
+will result in a successful translation with num having the value 0, and
+*endptr = 'x'. Be sure to validate how much data was consumed when calling this
+function.
+
=head1 HISTORY
OPENSSL_mem_debug_push(), OPENSSL_mem_debug_pop(),
size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz);
size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz);
size_t OPENSSL_strnlen(const char *str, size_t maxlen);
+int OPENSSL_strtoul(const char *str, char **endptr, int base, unsigned long *num);
int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlength,
const unsigned char *buf, size_t buflen,
const char sep);
OSSL_USER_NOTICE_SYNTAX_it ? 3_4_0 EXIST::FUNCTION:
OSSL_INDICATOR_set_callback ? 3_4_0 EXIST::FUNCTION:
OSSL_INDICATOR_get_callback ? 3_4_0 EXIST::FUNCTION:
+OPENSSL_strtoul ? 3_4_0 EXIST::FUNCTION: