diff options
author | Bruce Momjian <bruce@momjian.us> | 2020-12-24 17:25:48 -0500 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2020-12-24 17:25:48 -0500 |
commit | c3826f831e6e63e13a749fd3ab9fd7106707b549 (patch) | |
tree | a060a73607136f8bd58000ffc0b14410f136f986 /src/common/hex_decode.c | |
parent | 7519bd16d1a2a2007b3604f6740611c0b75a6cd0 (diff) | |
download | postgresql-c3826f831e6e63e13a749fd3ab9fd7106707b549.tar.gz postgresql-c3826f831e6e63e13a749fd3ab9fd7106707b549.zip |
move hex_decode() to /common so it can be called from frontend
This allows removal of a copy of hex_decode() from ecpg, and will be
used by the soon-to-be added pg_alterckey command.
Backpatch-through: master
Diffstat (limited to 'src/common/hex_decode.c')
-rw-r--r-- | src/common/hex_decode.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/common/hex_decode.c b/src/common/hex_decode.c new file mode 100644 index 00000000000..3ecdc73b5cd --- /dev/null +++ b/src/common/hex_decode.c @@ -0,0 +1,106 @@ +/*------------------------------------------------------------------------- + * + * hex_decode.c + * hex decoding + * + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/common/hex_decode.c + * + *------------------------------------------------------------------------- + */ + + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#ifdef FRONTEND +#include "common/logging.h" +#else +#include "mb/pg_wchar.h" +#endif +#include "common/hex_decode.h" + + +static const int8 hexlookup[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +static inline char +get_hex(const char *cp) +{ + unsigned char c = (unsigned char) *cp; + int res = -1; + + if (c < 127) + res = hexlookup[c]; + + if (res < 0) + { +#ifdef FRONTEND + pg_log_fatal("invalid hexadecimal digit"); + exit(EXIT_FAILURE); +#else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid hexadecimal digit: \"%.*s\"", + pg_mblen(cp), cp))); +#endif + } + + return (char) res; +} + +uint64 +hex_decode(const char *src, size_t len, char *dst) +{ + const char *s, + *srcend; + char v1, + v2, + *p; + + srcend = src + len; + s = src; + p = dst; + while (s < srcend) + { + if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') + { + s++; + continue; + } + v1 = get_hex(s) << 4; + s++; + if (s >= srcend) + { +#ifdef FRONTEND + pg_log_fatal("invalid hexadecimal data: odd number of digits"); + exit(EXIT_FAILURE); +#else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid hexadecimal data: odd number of digits"))); +#endif + } + v2 = get_hex(s); + s++; + *p++ = v1 | v2; + } + + return p - dst; +} |