mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Move various mem* functions to lib/string
This commit is contained in:
parent
9e592d1dec
commit
e165c9c304
@ -131,52 +131,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
||||
#include "lib/net/address.h"
|
||||
#include "lib/sandbox/sandbox.h"
|
||||
|
||||
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
|
||||
* <b>needle</b>, return a pointer to the first occurrence of the needle
|
||||
* within the haystack, or NULL if there is no such occurrence.
|
||||
*
|
||||
* This function is <em>not</em> timing-safe.
|
||||
*
|
||||
* Requires that <b>nlen</b> be greater than zero.
|
||||
*/
|
||||
const void *
|
||||
tor_memmem(const void *_haystack, size_t hlen,
|
||||
const void *_needle, size_t nlen)
|
||||
{
|
||||
#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
|
||||
tor_assert(nlen);
|
||||
return memmem(_haystack, hlen, _needle, nlen);
|
||||
#else
|
||||
/* This isn't as fast as the GLIBC implementation, but it doesn't need to
|
||||
* be. */
|
||||
const char *p, *last_possible_start;
|
||||
const char *haystack = (const char*)_haystack;
|
||||
const char *needle = (const char*)_needle;
|
||||
char first;
|
||||
tor_assert(nlen);
|
||||
|
||||
if (nlen > hlen)
|
||||
return NULL;
|
||||
|
||||
p = haystack;
|
||||
/* Last position at which the needle could start. */
|
||||
last_possible_start = haystack + hlen - nlen;
|
||||
first = *(const char*)needle;
|
||||
while ((p = memchr(p, first, last_possible_start + 1 - p))) {
|
||||
if (fast_memeq(p, needle, nlen))
|
||||
return p;
|
||||
if (++p > last_possible_start) {
|
||||
/* This comparison shouldn't be necessary, since if p was previously
|
||||
* equal to last_possible_start, the next memchr call would be
|
||||
* "memchr(p, first, 0)", which will return NULL. But it clarifies the
|
||||
* logic. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
|
||||
}
|
||||
|
||||
/** Represents a lockfile on which we hold the lock. */
|
||||
struct tor_lockfile_t {
|
||||
/** Name of the file */
|
||||
|
@ -63,16 +63,6 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
|
||||
size_t nlen) ATTR_NONNULL((1,3));
|
||||
static const void *tor_memstr(const void *haystack, size_t hlen,
|
||||
const char *needle) ATTR_NONNULL((1,3));
|
||||
static inline const void *
|
||||
tor_memstr(const void *haystack, size_t hlen, const char *needle)
|
||||
{
|
||||
return tor_memmem(haystack, hlen, needle, strlen(needle));
|
||||
}
|
||||
|
||||
/* ===== Time compatibility */
|
||||
|
||||
struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
|
||||
|
@ -240,54 +240,6 @@ hex_str(const char *from, size_t fromlen)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Compare the value of the string <b>prefix</b> with the start of the
|
||||
* <b>memlen</b>-byte memory chunk at <b>mem</b>. Return as for strcmp.
|
||||
*
|
||||
* [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
|
||||
* less than strlen(prefix).]
|
||||
*/
|
||||
int
|
||||
fast_memcmpstart(const void *mem, size_t memlen,
|
||||
const char *prefix)
|
||||
{
|
||||
size_t plen = strlen(prefix);
|
||||
if (memlen < plen)
|
||||
return -1;
|
||||
return fast_memcmp(mem, prefix, plen);
|
||||
}
|
||||
|
||||
/** Return true iff the 'len' bytes at 'mem' are all zero. */
|
||||
int
|
||||
tor_mem_is_zero(const char *mem, size_t len)
|
||||
{
|
||||
static const char ZERO[] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
|
||||
};
|
||||
while (len >= sizeof(ZERO)) {
|
||||
/* It's safe to use fast_memcmp here, since the very worst thing an
|
||||
* attacker could learn is how many initial bytes of a secret were zero */
|
||||
if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
|
||||
return 0;
|
||||
len -= sizeof(ZERO);
|
||||
mem += sizeof(ZERO);
|
||||
}
|
||||
/* Deal with leftover bytes. */
|
||||
if (len)
|
||||
return fast_memeq(mem, ZERO, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
|
||||
int
|
||||
tor_digest_is_zero(const char *digest)
|
||||
{
|
||||
static const uint8_t ZERO_DIGEST[] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** Return true if <b>string</b> is a valid 'key=[value]' string.
|
||||
* "value" is optional, to indicate the empty string. Log at logging
|
||||
* <b>severity</b> if something ugly happens. */
|
||||
@ -436,13 +388,6 @@ string_is_valid_nonrfc_hostname(const char *string)
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
|
||||
int
|
||||
tor_digest256_is_zero(const char *digest)
|
||||
{
|
||||
return tor_mem_is_zero(digest, DIGEST256_LEN);
|
||||
}
|
||||
|
||||
/** Return a newly allocated string equal to <b>string</b>, except that every
|
||||
* character in <b>chars_to_escape</b> is preceded by a backslash. */
|
||||
char *
|
||||
|
@ -78,10 +78,6 @@ int string_is_valid_nonrfc_hostname(const char *string);
|
||||
int string_is_valid_ipv4_address(const char *string);
|
||||
int string_is_valid_ipv6_address(const char *string);
|
||||
|
||||
int tor_mem_is_zero(const char *mem, size_t len);
|
||||
int tor_digest_is_zero(const char *digest);
|
||||
int tor_digest256_is_zero(const char *digest);
|
||||
|
||||
char *tor_escape_str_for_pt_args(const char *string,
|
||||
const char *chars_to_escape);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
orconfig.h
|
||||
lib/cc/*.h
|
||||
lib/defs/*.h
|
||||
lib/err/*.h
|
||||
lib/malloc/*.h
|
||||
lib/ctime/*.h
|
||||
|
@ -7,10 +7,102 @@
|
||||
#include "lib/string/compat_ctype.h"
|
||||
#include "lib/err/torerr.h"
|
||||
#include "lib/ctime/di_ops.h"
|
||||
#include "lib/defs/digest_sizes.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
|
||||
* <b>needle</b>, return a pointer to the first occurrence of the needle
|
||||
* within the haystack, or NULL if there is no such occurrence.
|
||||
*
|
||||
* This function is <em>not</em> timing-safe.
|
||||
*
|
||||
* Requires that <b>nlen</b> be greater than zero.
|
||||
*/
|
||||
const void *
|
||||
tor_memmem(const void *_haystack, size_t hlen,
|
||||
const void *_needle, size_t nlen)
|
||||
{
|
||||
#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
|
||||
raw_assert(nlen);
|
||||
return memmem(_haystack, hlen, _needle, nlen);
|
||||
#else
|
||||
/* This isn't as fast as the GLIBC implementation, but it doesn't need to
|
||||
* be. */
|
||||
const char *p, *last_possible_start;
|
||||
const char *haystack = (const char*)_haystack;
|
||||
const char *needle = (const char*)_needle;
|
||||
char first;
|
||||
raw_assert(nlen);
|
||||
|
||||
if (nlen > hlen)
|
||||
return NULL;
|
||||
|
||||
p = haystack;
|
||||
/* Last position at which the needle could start. */
|
||||
last_possible_start = haystack + hlen - nlen;
|
||||
first = *(const char*)needle;
|
||||
while ((p = memchr(p, first, last_possible_start + 1 - p))) {
|
||||
if (fast_memeq(p, needle, nlen))
|
||||
return p;
|
||||
if (++p > last_possible_start) {
|
||||
/* This comparison shouldn't be necessary, since if p was previously
|
||||
* equal to last_possible_start, the next memchr call would be
|
||||
* "memchr(p, first, 0)", which will return NULL. But it clarifies the
|
||||
* logic. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
|
||||
}
|
||||
|
||||
const void *
|
||||
tor_memstr(const void *haystack, size_t hlen, const char *needle)
|
||||
{
|
||||
return tor_memmem(haystack, hlen, needle, strlen(needle));
|
||||
}
|
||||
|
||||
/** Return true iff the 'len' bytes at 'mem' are all zero. */
|
||||
int
|
||||
tor_mem_is_zero(const char *mem, size_t len)
|
||||
{
|
||||
static const char ZERO[] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
|
||||
};
|
||||
while (len >= sizeof(ZERO)) {
|
||||
/* It's safe to use fast_memcmp here, since the very worst thing an
|
||||
* attacker could learn is how many initial bytes of a secret were zero */
|
||||
if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
|
||||
return 0;
|
||||
len -= sizeof(ZERO);
|
||||
mem += sizeof(ZERO);
|
||||
}
|
||||
/* Deal with leftover bytes. */
|
||||
if (len)
|
||||
return fast_memeq(mem, ZERO, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
|
||||
int
|
||||
tor_digest_is_zero(const char *digest)
|
||||
{
|
||||
static const uint8_t ZERO_DIGEST[] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
|
||||
int
|
||||
tor_digest256_is_zero(const char *digest)
|
||||
{
|
||||
return tor_mem_is_zero(digest, DIGEST256_LEN);
|
||||
}
|
||||
|
||||
/** Remove from the string <b>s</b> every character which appears in
|
||||
* <b>strip</b>. */
|
||||
void
|
||||
@ -140,6 +232,22 @@ strcasecmpstart(const char *s1, const char *s2)
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
||||
/** Compare the value of the string <b>prefix</b> with the start of the
|
||||
* <b>memlen</b>-byte memory chunk at <b>mem</b>. Return as for strcmp.
|
||||
*
|
||||
* [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
|
||||
* less than strlen(prefix).]
|
||||
*/
|
||||
int
|
||||
fast_memcmpstart(const void *mem, size_t memlen,
|
||||
const char *prefix)
|
||||
{
|
||||
size_t plen = strlen(prefix);
|
||||
if (memlen < plen)
|
||||
return -1;
|
||||
return fast_memcmp(mem, prefix, plen);
|
||||
}
|
||||
|
||||
/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
|
||||
* strcmp.
|
||||
*/
|
||||
|
@ -11,6 +11,14 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
|
||||
size_t nlen) ATTR_NONNULL((1,3));
|
||||
const void *tor_memstr(const void *haystack, size_t hlen,
|
||||
const char *needle) ATTR_NONNULL((1,3));
|
||||
int tor_mem_is_zero(const char *mem, size_t len);
|
||||
int tor_digest_is_zero(const char *digest);
|
||||
int tor_digest256_is_zero(const char *digest);
|
||||
|
||||
/** Allowable characters in a hexadecimal string. */
|
||||
#define HEX_CHARACTERS "0123456789ABCDEFabcdef"
|
||||
void tor_strlower(char *s) ATTR_NONNULL((1));
|
||||
|
Loading…
Reference in New Issue
Block a user