mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
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
107 lines
2.2 KiB
C
107 lines
2.2 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* 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;
|
|
}
|