Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_hex.c

n_hex regression: hexadecimal encode/decode round-trips and error paths.

n_hex regression: hexadecimal encode/decode round-trips and error paths.

Author
Castagnier Mickael
Version
1.0
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "nilorea/n_hex.h"
#include "nilorea/n_log.h"
#include "nilorea/n_str.h"
#include <stdio.h>
#include <string.h>
static int failures = 0;
/* Parse the -V LOG_LEVEL verbosity argument. */
void process_args(int argc, char** argv) {
int opt = 0;
while ((opt = getopt(argc, argv, "hvV:")) != EOF) {
switch (opt) {
case 'V':
if (!strncmp("LOG_NULL", optarg, 8))
else if (!strncmp("LOG_NOTICE", optarg, 10))
else if (!strncmp("LOG_INFO", optarg, 8))
else if (!strncmp("LOG_ERR", optarg, 7))
else if (!strncmp("LOG_DEBUG", optarg, 9))
else {
fprintf(stderr, "Unknown log level %s\n", optarg);
exit(1);
}
break;
case 'v':
fprintf(stderr, "ex_hex\n");
exit(1);
case 'h':
default:
fprintf(stderr, "usage: %s [-V LOG_LEVEL]\n", argv[0]);
break;
}
}
}
static void expect_encode(const unsigned char* data, size_t len, const char* want) {
N_STR* out = n_hex_encode(data, len);
if (!out) {
n_log(LOG_ERR, "n_hex_encode returned NULL for expected '%s'", want);
return;
}
if (out->written != strlen(want) || strcmp(out->data, want) != 0) {
n_log(LOG_ERR, "n_hex_encode: got '%s' (written %zu) expected '%s'", out->data, out->written, want);
}
free_nstr(&out);
}
static void test_encode(void) {
const unsigned char a[] = {0x00, 0x01, 0xff, 0xab};
expect_encode(a, sizeof(a), "0001ffab");
const unsigned char b[] = {0xDE, 0xAD, 0xBE, 0xEF};
expect_encode(b, sizeof(b), "deadbeef");
/* zero length yields an empty string */
expect_encode((const unsigned char*)"", 0, "");
/* NULL data with len 0 is allowed and yields an empty string */
expect_encode(NULL, 0, "");
}
static void test_decode_roundtrip(void) {
size_t n = 123;
unsigned char* buf = n_hex_decode("0001ffab", &n);
if (!buf || n != 4) {
n_log(LOG_ERR, "decode '0001ffab': got len %zu expected 4", n);
} else if (buf[0] != 0x00 || buf[1] != 0x01 || buf[2] != 0xff || buf[3] != 0xab) {
n_log(LOG_ERR, "decode '0001ffab': wrong bytes");
}
Free(buf);
/* uppercase and whitespace are tolerated and produce the same bytes */
n = 0;
buf = n_hex_decode(" DE AD\tBE\nEF ", &n);
if (!buf || n != 4 || buf[0] != 0xde || buf[1] != 0xad || buf[2] != 0xbe || buf[3] != 0xef) {
n_log(LOG_ERR, "decode with whitespace/upper failed (len %zu)", n);
}
Free(buf);
/* round-trip a buffer containing an embedded NUL */
const unsigned char payload[] = {0x00, 0x41, 0x00, 0x42};
N_STR* enc = n_hex_encode(payload, sizeof(payload));
if (!enc || strcmp(enc->data, "00410042") != 0) {
n_log(LOG_ERR, "encode with embedded NUL failed");
} else {
n = 0;
unsigned char* dec = n_hex_decode(enc->data, &n);
if (!dec || n != sizeof(payload) || memcmp(dec, payload, sizeof(payload)) != 0) {
n_log(LOG_ERR, "round-trip with embedded NUL failed (len %zu)", n);
}
Free(dec);
}
free_nstr(&enc);
}
static void test_decode_errors(void) {
size_t n = 7;
unsigned char* buf = n_hex_decode("abc", &n); /* odd digit count */
if (buf || n != 0) {
n_log(LOG_ERR, "decode odd-length should fail");
Free(buf);
}
n = 7;
buf = n_hex_decode("0g", &n); /* invalid character */
if (buf || n != 0) {
n_log(LOG_ERR, "decode invalid char should fail");
Free(buf);
}
/* empty input decodes to a zero-length, non-NULL buffer */
n = 7;
buf = n_hex_decode("", &n);
if (!buf || n != 0) {
n_log(LOG_ERR, "decode empty should yield len 0 buffer (len %zu)", n);
}
Free(buf);
/* NULL input is rejected */
if (n_hex_decode(NULL, &n) != NULL) {
n_log(LOG_ERR, "decode NULL should fail");
}
}
int main(int argc, char** argv) {
process_args(argc, argv);
if (failures) {
n_log(LOG_ERR, "ex_hex: %d failure(s)", failures);
return 1;
}
n_log(LOG_NOTICE, "ex_hex: all checks passed");
return 0;
}
static int failures
int main(void)
void process_args(int argc, char **argv)
Definition ex_common.c:48
static void test_encode(void)
Definition ex_hex.c:83
static void expect_encode(const unsigned char *data, size_t len, const char *want)
Definition ex_hex.c:69
static void test_decode_errors(void)
Definition ex_hex.c:135
static void test_decode_roundtrip(void)
Definition ex_hex.c:96
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:80
#define LOG_NULL
no log output
Definition n_log.h:46
#define LOG_INFO
informational
Definition n_log.h:82
unsigned char * n_hex_decode(const char *hex, size_t *out_len)
decode a hex string (ASCII whitespace between digits is ignored) into a freshly allocated,...
Definition n_hex.c:71
N_STR * n_hex_encode(const unsigned char *data, size_t len)
encode len bytes of data as a lowercase hex N_STR (2*len characters); free with free_nstr.
Definition n_hex.c:48
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
Definition n_str.h:68
char * data
the string
Definition n_str.h:63
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
A box including a string and his lenght.
Definition n_str.h:61
Common headers and low-level functions & define.
Hexadecimal encode/decode helpers.
Generic log system.
N_STR and string function declaration.