diff --git a/src/backend/replication/backup_manifest.c b/src/backend/replication/backup_manifest.c index 8882444025..921de47a6c 100644 --- a/src/backend/replication/backup_manifest.c +++ b/src/backend/replication/backup_manifest.c @@ -13,11 +13,11 @@ #include "postgres.h" #include "access/timeline.h" -#include "common/hex.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "mb/pg_wchar.h" #include "replication/backup_manifest.h" +#include "utils/builtins.h" #include "utils/json.h" static void AppendStringToManifest(backup_manifest_info *manifest, char *s); @@ -150,12 +150,10 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, } else { - uint64 dstlen = pg_hex_enc_len(pathlen); - appendStringInfoString(&buf, "{ \"Encoded-Path\": \""); - enlargeStringInfo(&buf, dstlen); - buf.len += pg_hex_encode(pathname, pathlen, - &buf.data[buf.len], dstlen); + enlargeStringInfo(&buf, 2 * pathlen); + buf.len += hex_encode(pathname, pathlen, + &buf.data[buf.len]); appendStringInfoString(&buf, "\", "); } @@ -178,7 +176,6 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, { uint8 checksumbuf[PG_CHECKSUM_MAX_LENGTH]; int checksumlen; - uint64 dstlen; checksumlen = pg_checksum_final(checksum_ctx, checksumbuf); if (checksumlen < 0) @@ -188,10 +185,9 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, appendStringInfo(&buf, ", \"Checksum-Algorithm\": \"%s\", \"Checksum\": \"", pg_checksum_type_name(checksum_ctx->type)); - dstlen = pg_hex_enc_len(checksumlen); - enlargeStringInfo(&buf, dstlen); - buf.len += pg_hex_encode((char *) checksumbuf, checksumlen, - &buf.data[buf.len], dstlen); + enlargeStringInfo(&buf, 2 * checksumlen); + buf.len += hex_encode((char *) checksumbuf, checksumlen, + &buf.data[buf.len]); appendStringInfoChar(&buf, '"'); } @@ -311,9 +307,8 @@ SendBackupManifest(backup_manifest_info *manifest) { StringInfoData protobuf; uint8 checksumbuf[PG_SHA256_DIGEST_LENGTH]; - char *checksumstringbuf; + char checksumstringbuf[PG_SHA256_DIGEST_STRING_LENGTH]; size_t manifest_bytes_done = 0; - uint64 dstlen; if (!IsManifestEnabled(manifest)) return; @@ -334,11 +329,10 @@ SendBackupManifest(backup_manifest_info *manifest) sizeof(checksumbuf)) < 0) elog(ERROR, "failed to finalize checksum of backup manifest"); AppendStringToManifest(manifest, "\"Manifest-Checksum\": \""); - dstlen = pg_hex_enc_len(sizeof(checksumbuf)); - checksumstringbuf = palloc0(dstlen + 1); /* includes \0 */ - pg_hex_encode((char *) checksumbuf, sizeof(checksumbuf), - checksumstringbuf, dstlen); - checksumstringbuf[dstlen] = '\0'; + + hex_encode((char *) checksumbuf, sizeof checksumbuf, checksumstringbuf); + checksumstringbuf[PG_SHA256_DIGEST_STRING_LENGTH - 1] = '\0'; + AppendStringToManifest(manifest, checksumstringbuf); AppendStringToManifest(manifest, "\"}\n"); diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index 8449aaac56..6dd93f9a32 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -15,7 +15,6 @@ #include -#include "common/hex.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -32,12 +31,10 @@ */ struct pg_encoding { - uint64 (*encode_len) (const char *src, size_t srclen); - uint64 (*decode_len) (const char *src, size_t srclen); - uint64 (*encode) (const char *src, size_t srclen, - char *dst, size_t dstlen); - uint64 (*decode) (const char *src, size_t srclen, - char *dst, size_t dstlen); + uint64 (*encode_len) (const char *data, size_t dlen); + uint64 (*decode_len) (const char *data, size_t dlen); + uint64 (*encode) (const char *data, size_t dlen, char *res); + uint64 (*decode) (const char *data, size_t dlen, char *res); }; static const struct pg_encoding *pg_find_encoding(const char *name); @@ -83,7 +80,11 @@ binary_encode(PG_FUNCTION_ARGS) result = palloc(VARHDRSZ + resultlen); - res = enc->encode(dataptr, datalen, VARDATA(result), resultlen); + res = enc->encode(dataptr, datalen, VARDATA(result)); + + /* Make this FATAL 'cause we've trodden on memory ... */ + if (res > resultlen) + elog(FATAL, "overflow - encode estimate too small"); SET_VARSIZE(result, VARHDRSZ + res); @@ -127,7 +128,11 @@ binary_decode(PG_FUNCTION_ARGS) result = palloc(VARHDRSZ + resultlen); - res = enc->decode(dataptr, datalen, VARDATA(result), resultlen); + res = enc->decode(dataptr, datalen, VARDATA(result)); + + /* Make this FATAL 'cause we've trodden on memory ... */ + if (res > resultlen) + elog(FATAL, "overflow - decode estimate too small"); SET_VARSIZE(result, VARHDRSZ + res); @@ -139,20 +144,95 @@ binary_decode(PG_FUNCTION_ARGS) * HEX */ -/* - * Those two wrappers are still needed to match with the layer of - * src/common/. - */ +static const char hextbl[] = "0123456789abcdef"; + +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, +}; + +uint64 +hex_encode(const char *src, size_t len, char *dst) +{ + const char *end = src + len; + + while (src < end) + { + *dst++ = hextbl[(*src >> 4) & 0xF]; + *dst++ = hextbl[*src & 0xF]; + src++; + } + return (uint64) len * 2; +} + +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) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid hexadecimal digit: \"%.*s\"", + pg_mblen(cp), cp))); + + 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) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid hexadecimal data: odd number of digits"))); + + v2 = get_hex(s); + s++; + *p++ = v1 | v2; + } + + return p - dst; +} + static uint64 hex_enc_len(const char *src, size_t srclen) { - return pg_hex_enc_len(srclen); + return (uint64) srclen << 1; } static uint64 hex_dec_len(const char *src, size_t srclen) { - return pg_hex_dec_len(srclen); + return (uint64) srclen >> 1; } /* @@ -174,12 +254,12 @@ static const int8 b64lookup[128] = { }; static uint64 -pg_base64_encode(const char *src, size_t srclen, char *dst, size_t dstlen) +pg_base64_encode(const char *src, size_t len, char *dst) { char *p, *lend = dst + 76; const char *s, - *end = src + srclen; + *end = src + len; int pos = 2; uint32 buf = 0; @@ -195,8 +275,6 @@ pg_base64_encode(const char *src, size_t srclen, char *dst, size_t dstlen) /* write it out */ if (pos < 0) { - if ((p - dst + 4) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = _base64[(buf >> 6) & 0x3f]; @@ -207,30 +285,25 @@ pg_base64_encode(const char *src, size_t srclen, char *dst, size_t dstlen) } if (p >= lend) { - if ((p - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = '\n'; lend = p + 76; } } if (pos != 2) { - if ((p - dst + 4) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; *p++ = '='; } - Assert((p - dst) <= dstlen); return p - dst; } static uint64 -pg_base64_decode(const char *src, size_t srclen, char *dst, size_t dstlen) +pg_base64_decode(const char *src, size_t len, char *dst) { - const char *srcend = src + srclen, + const char *srcend = src + len, *s = src; char *p = dst; char c; @@ -278,21 +351,11 @@ pg_base64_decode(const char *src, size_t srclen, char *dst, size_t dstlen) pos++; if (pos == 4) { - if ((p - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = (buf >> 16) & 255; if (end == 0 || end > 1) - { - if ((p - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = (buf >> 8) & 255; - } if (end == 0 || end > 2) - { - if ((p - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = buf & 255; - } buf = 0; pos = 0; } @@ -304,7 +367,6 @@ pg_base64_decode(const char *src, size_t srclen, char *dst, size_t dstlen) errmsg("invalid base64 end sequence"), errhint("Input data is missing padding, is truncated, or is otherwise corrupted."))); - Assert((p - dst) <= dstlen); return p - dst; } @@ -340,7 +402,7 @@ pg_base64_dec_len(const char *src, size_t srclen) #define DIG(VAL) ((VAL) + '0') static uint64 -esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) +esc_encode(const char *src, size_t srclen, char *dst) { const char *end = src + srclen; char *rp = dst; @@ -352,8 +414,6 @@ esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) if (c == '\0' || IS_HIGHBIT_SET(c)) { - if ((rp - dst + 4) > dstlen) - elog(ERROR, "overflow of destination buffer in escape encoding"); rp[0] = '\\'; rp[1] = DIG(c >> 6); rp[2] = DIG((c >> 3) & 7); @@ -363,8 +423,6 @@ esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) } else if (c == '\\') { - if ((rp - dst + 2) > dstlen) - elog(ERROR, "overflow of destination buffer in escape encoding"); rp[0] = '\\'; rp[1] = '\\'; rp += 2; @@ -372,8 +430,6 @@ esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) } else { - if ((rp - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in escape encoding"); *rp++ = c; len++; } @@ -381,12 +437,11 @@ esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) src++; } - Assert((rp - dst) <= dstlen); return len; } static uint64 -esc_decode(const char *src, size_t srclen, char *dst, size_t dstlen) +esc_decode(const char *src, size_t srclen, char *dst) { const char *end = src + srclen; char *rp = dst; @@ -395,11 +450,7 @@ esc_decode(const char *src, size_t srclen, char *dst, size_t dstlen) while (src < end) { if (src[0] != '\\') - { - if ((rp - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = *src++; - } else if (src + 3 < end && (src[1] >= '0' && src[1] <= '3') && (src[2] >= '0' && src[2] <= '7') && @@ -411,16 +462,12 @@ esc_decode(const char *src, size_t srclen, char *dst, size_t dstlen) val <<= 3; val += VAL(src[2]); val <<= 3; - if ((rp - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = val + VAL(src[3]); src += 4; } else if (src + 1 < end && (src[1] == '\\')) { - if ((rp - dst + 1) > dstlen) - elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = '\\'; src += 2; } @@ -438,7 +485,6 @@ esc_decode(const char *src, size_t srclen, char *dst, size_t dstlen) len++; } - Assert((rp - dst) <= dstlen); return len; } @@ -520,7 +566,7 @@ static const struct { "hex", { - hex_enc_len, hex_dec_len, pg_hex_encode, pg_hex_decode + hex_enc_len, hex_dec_len, hex_encode, hex_decode } }, { diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index d2a11b1b5d..8253ced0c5 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -22,7 +22,6 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/hashfn.h" -#include "common/hex.h" #include "common/int.h" #include "common/unicode_norm.h" #include "lib/hyperloglog.h" @@ -305,12 +304,10 @@ byteain(PG_FUNCTION_ARGS) if (inputText[0] == '\\' && inputText[1] == 'x') { size_t len = strlen(inputText); - uint64 dstlen = pg_hex_dec_len(len - 2); - bc = dstlen + VARHDRSZ; /* maximum possible length */ + bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */ result = palloc(bc); - - bc = pg_hex_decode(inputText + 2, len - 2, VARDATA(result), dstlen); + bc = hex_decode(inputText + 2, len - 2, VARDATA(result)); SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */ PG_RETURN_BYTEA_P(result); @@ -399,15 +396,11 @@ byteaout(PG_FUNCTION_ARGS) if (bytea_output == BYTEA_OUTPUT_HEX) { - uint64 dstlen = pg_hex_enc_len(VARSIZE_ANY_EXHDR(vlena)); - /* Print hex format */ - rp = result = palloc(dstlen + 2 + 1); + rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1); *rp++ = '\\'; *rp++ = 'x'; - - rp += pg_hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp, - dstlen); + rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp); } else if (bytea_output == BYTEA_OUTPUT_ESCAPE) { diff --git a/src/common/Makefile b/src/common/Makefile index 38a8599337..880722fcf5 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -58,7 +58,6 @@ OBJS_COMMON = \ file_perm.o \ file_utils.o \ hashfn.o \ - hex.o \ ip.o \ jsonapi.o \ keywords.o \ diff --git a/src/common/hex.c b/src/common/hex.c deleted file mode 100644 index 3b1bc8fa75..0000000000 --- a/src/common/hex.c +++ /dev/null @@ -1,192 +0,0 @@ -/*------------------------------------------------------------------------- - * - * hex.c - * Encoding and decoding routines for hex. - * - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/hex.c - * - *------------------------------------------------------------------------- - */ - - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/hex.h" -#ifdef FRONTEND -#include "common/logging.h" -#endif -#include "mb/pg_wchar.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 const char hextbl[] = "0123456789abcdef"; - -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; -} - -/* - * pg_hex_encode - * - * Encode into hex the given string. Returns the length of the encoded - * string. - */ -uint64 -pg_hex_encode(const char *src, size_t srclen, char *dst, size_t dstlen) -{ - const char *end = src + srclen; - char *p; - - p = dst; - - while (src < end) - { - /* - * Leave if there is an overflow in the area allocated for the encoded - * string. - */ - if ((p - dst + 2) > dstlen) - { -#ifdef FRONTEND - pg_log_fatal("overflow of destination buffer in hex encoding"); - exit(EXIT_FAILURE); -#else - elog(ERROR, "overflow of destination buffer in hex encoding"); -#endif - } - - *p++ = hextbl[(*src >> 4) & 0xF]; - *p++ = hextbl[*src & 0xF]; - src++; - } - - Assert((p - dst) <= dstlen); - return p - dst; -} - -/* - * pg_hex_decode - * - * Decode the given hex string. Returns the length of the decoded string. - */ -uint64 -pg_hex_decode(const char *src, size_t srclen, char *dst, size_t dstlen) -{ - const char *s, - *srcend; - char v1, - v2, - *p; - - srcend = src + srclen; - 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++; - - /* overflow check */ - if ((p - dst + 1) > dstlen) - { -#ifdef FRONTEND - pg_log_fatal("overflow of destination buffer in hex decoding"); - exit(EXIT_FAILURE); -#else - elog(ERROR, "overflow of destination buffer in hex decoding"); -#endif - } - - *p++ = v1 | v2; - } - - Assert((p - dst) <= dstlen); - return p - dst; -} - -/* - * pg_hex_enc_len - * - * Returns to caller the length of the string if it were encoded with - * hex based on the length provided by caller. This is useful to estimate - * how large a buffer allocation needs to be done before doing the actual - * encoding. - */ -uint64 -pg_hex_enc_len(size_t srclen) -{ - return (uint64) srclen << 1; -} - -/* - * pg_hex_dec_len - * - * Returns to caller the length of the string if it were to be decoded - * with hex, based on the length given by caller. This is useful to - * estimate how large a buffer allocation needs to be done before doing - * the actual decoding. - */ -uint64 -pg_hex_dec_len(size_t srclen) -{ - return (uint64) srclen >> 1; -} diff --git a/src/include/common/hex.h b/src/include/common/hex.h deleted file mode 100644 index 150771a14d..0000000000 --- a/src/include/common/hex.h +++ /dev/null @@ -1,25 +0,0 @@ -/*------------------------------------------------------------------------ - * - * hex.h - * Encoding and decoding routines for hex strings. - * - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/common/hex.h - * - *------------------------------------------------------------------------ - */ - -#ifndef COMMON_HEX_H -#define COMMON_HEX_H - -extern uint64 pg_hex_decode(const char *src, size_t srclen, - char *dst, size_t dstlen); -extern uint64 pg_hex_encode(const char *src, size_t srclen, - char *dst, size_t dstlen); -extern uint64 pg_hex_enc_len(size_t srclen); -extern uint64 pg_hex_dec_len(size_t srclen); - -#endif /* COMMON_HEX_H */ diff --git a/src/include/common/sha2.h b/src/include/common/sha2.h index dfeee6bceb..f4bae35af1 100644 --- a/src/include/common/sha2.h +++ b/src/include/common/sha2.h @@ -18,11 +18,15 @@ /*** SHA224/256/384/512 Various Length Definitions ***********************/ #define PG_SHA224_BLOCK_LENGTH 64 #define PG_SHA224_DIGEST_LENGTH 28 +#define PG_SHA224_DIGEST_STRING_LENGTH (PG_SHA224_DIGEST_LENGTH * 2 + 1) #define PG_SHA256_BLOCK_LENGTH 64 #define PG_SHA256_DIGEST_LENGTH 32 +#define PG_SHA256_DIGEST_STRING_LENGTH (PG_SHA256_DIGEST_LENGTH * 2 + 1) #define PG_SHA384_BLOCK_LENGTH 128 #define PG_SHA384_DIGEST_LENGTH 48 +#define PG_SHA384_DIGEST_STRING_LENGTH (PG_SHA384_DIGEST_LENGTH * 2 + 1) #define PG_SHA512_BLOCK_LENGTH 128 #define PG_SHA512_DIGEST_LENGTH 64 +#define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1) #endif /* _PG_SHA2_H_ */ diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index f3ce4fb173..40fcb0ab6d 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -31,6 +31,10 @@ extern void domain_check(Datum value, bool isnull, Oid domainType, extern int errdatatype(Oid datatypeOid); extern int errdomainconstraint(Oid datatypeOid, const char *conname); +/* encode.c */ +extern uint64 hex_encode(const char *src, size_t len, char *dst); +extern uint64 hex_decode(const char *src, size_t len, char *dst); + /* int.c */ extern int2vector *buildint2vector(const int16 *int2s, int n); diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index 233ddbf4c2..05ff67e693 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -129,7 +129,7 @@ sub mkvcbuild our @pgcommonallfiles = qw( archive.c base64.c checksum_helper.c config_info.c controldata_utils.c d2s.c encnames.c exec.c - f2s.c file_perm.c file_utils.c hashfn.c hex.c ip.c jsonapi.c + f2s.c file_perm.c file_utils.c hashfn.c ip.c jsonapi.c keywords.c kwlookup.c link-canary.c md5_common.c pg_get_line.c pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c saslprep.c scram-common.c string.c stringinfo.c unicode_norm.c username.c