Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 1168 additions and 170 deletions
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-or-later
# $1 == udp/tcp/tls, it selects configuration file to use
# respdiff scripts must be present in /var/opt/respdiff
set -o errexit -o nounset -o xtrace
NDIFFREPRO=3
wget -qO- https://gitlab.nic.cz/knot/respdiff/snippets/238/raw?inline=false | head -n 5000 > /tmp/queries.txt
mkdir results
rm -rf respdiff.db
CONFIG="$(pwd)/ci/respdiff/respdiff-${1}.conf"
/var/opt/respdiff/qprep.py respdiff.db < /tmp/queries.txt
time /var/opt/respdiff/orchestrator.py respdiff.db -c "${CONFIG}"
time /var/opt/respdiff/msgdiff.py respdiff.db -c "${CONFIG}"
for i in $(seq $NDIFFREPRO); do
time /var/opt/respdiff/diffrepro.py -c "${CONFIG}" respdiff.db
done
/var/opt/respdiff/diffsum.py respdiff.db -c "${CONFIG}" > results/respdiff.txt
/var/opt/respdiff/histogram.py respdiff.db -c "${CONFIG}" -o results/histogram.svg
: minimize LMDB and log size so they can be effectively archived
mkdir results/respdiff.db
mdb_copy -c respdiff.db results/respdiff.db
xz -9 results/respdiff.db/data.mdb
xz kresd.log
# SPDX-License-Identifier: GPL-3.0-or-later
#run unbound
service unbound start && service unbound status;
# dig @localhost -p 53535
#run bind
service named start && service named status;
# dig @localhost -p 53533
#run kresd
$PREFIX/sbin/kresd -n -q -c $(pwd)/ci/respdiff/kresd.config &>kresd.log &
# dig @localhost -p 5353
# Project
MAJOR := 15
MINOR := 07
PATCH := 0
# Paths
PREFIX := /usr/local
BINDIR := /bin
LIBDIR := /lib
INCLUDEDIR := /include
MODULEDIR := $(LIBDIR)/kdns_modules
# Tools
CC ?= cc
CFLAGS += -std=c99 -D_GNU_SOURCE -fPIC -Wall -I$(abspath .) -I$(abspath lib/generic) -I$(abspath contrib)
CFLAGS += -DPACKAGE_VERSION="\"$(MAJOR).$(MINOR)\"" -DPREFIX="\"$(PREFIX)\"" -DMODULEDIR="\"$(MODULEDIR)\""
RM := rm -f
LN := ln -s
XXD := ./scripts/embed.sh
INSTALL := install
PYTHON := python
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "base32hex.h"
#include <stdlib.h>
#include <stdint.h>
/*! \brief Maximal length of binary input to Base32hex encoding. */
#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5)
/*! \brief Base32hex padding character. */
static const uint8_t base32hex_pad = '=';
/*! \brief Base32hex alphabet. Beware: original code was upper-case. */
static const uint8_t base32hex_enc[] = "0123456789abcdefghijklmnopqrstuv";
/*! \brief Indicates bad Base32hex character. */
#define KO 255
/*! \brief Indicates Base32hex padding character. */
#define PD 32
/*! \brief Transformation and validation table for decoding Base32hex. */
static const uint8_t base32hex_dec[256] = {
[ 0] = KO, [ 43] = KO, ['V'] = 31, [129] = KO, [172] = KO, [215] = KO,
[ 1] = KO, [ 44] = KO, ['W'] = KO, [130] = KO, [173] = KO, [216] = KO,
[ 2] = KO, [ 45] = KO, ['X'] = KO, [131] = KO, [174] = KO, [217] = KO,
[ 3] = KO, [ 46] = KO, ['Y'] = KO, [132] = KO, [175] = KO, [218] = KO,
[ 4] = KO, [ 47] = KO, ['Z'] = KO, [133] = KO, [176] = KO, [219] = KO,
[ 5] = KO, ['0'] = 0, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
[ 6] = KO, ['1'] = 1, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
[ 7] = KO, ['2'] = 2, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
[ 8] = KO, ['3'] = 3, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
[ 9] = KO, ['4'] = 4, [ 95] = KO, [138] = KO, [181] = KO, [224] = KO,
[ 10] = KO, ['5'] = 5, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
[ 11] = KO, ['6'] = 6, ['a'] = 10, [140] = KO, [183] = KO, [226] = KO,
[ 12] = KO, ['7'] = 7, ['b'] = 11, [141] = KO, [184] = KO, [227] = KO,
[ 13] = KO, ['8'] = 8, ['c'] = 12, [142] = KO, [185] = KO, [228] = KO,
[ 14] = KO, ['9'] = 9, ['d'] = 13, [143] = KO, [186] = KO, [229] = KO,
[ 15] = KO, [ 58] = KO, ['e'] = 14, [144] = KO, [187] = KO, [230] = KO,
[ 16] = KO, [ 59] = KO, ['f'] = 15, [145] = KO, [188] = KO, [231] = KO,
[ 17] = KO, [ 60] = KO, ['g'] = 16, [146] = KO, [189] = KO, [232] = KO,
[ 18] = KO, ['='] = PD, ['h'] = 17, [147] = KO, [190] = KO, [233] = KO,
[ 19] = KO, [ 62] = KO, ['i'] = 18, [148] = KO, [191] = KO, [234] = KO,
[ 20] = KO, [ 63] = KO, ['j'] = 19, [149] = KO, [192] = KO, [235] = KO,
[ 21] = KO, [ 64] = KO, ['k'] = 20, [150] = KO, [193] = KO, [236] = KO,
[ 22] = KO, ['A'] = 10, ['l'] = 21, [151] = KO, [194] = KO, [237] = KO,
[ 23] = KO, ['B'] = 11, ['m'] = 22, [152] = KO, [195] = KO, [238] = KO,
[ 24] = KO, ['C'] = 12, ['n'] = 23, [153] = KO, [196] = KO, [239] = KO,
[ 25] = KO, ['D'] = 13, ['o'] = 24, [154] = KO, [197] = KO, [240] = KO,
[ 26] = KO, ['E'] = 14, ['p'] = 25, [155] = KO, [198] = KO, [241] = KO,
[ 27] = KO, ['F'] = 15, ['q'] = 26, [156] = KO, [199] = KO, [242] = KO,
[ 28] = KO, ['G'] = 16, ['r'] = 27, [157] = KO, [200] = KO, [243] = KO,
[ 29] = KO, ['H'] = 17, ['s'] = 28, [158] = KO, [201] = KO, [244] = KO,
[ 30] = KO, ['I'] = 18, ['t'] = 29, [159] = KO, [202] = KO, [245] = KO,
[ 31] = KO, ['J'] = 19, ['u'] = 30, [160] = KO, [203] = KO, [246] = KO,
[ 32] = KO, ['K'] = 20, ['v'] = 31, [161] = KO, [204] = KO, [247] = KO,
[ 33] = KO, ['L'] = 21, ['w'] = KO, [162] = KO, [205] = KO, [248] = KO,
[ 34] = KO, ['M'] = 22, ['x'] = KO, [163] = KO, [206] = KO, [249] = KO,
[ 35] = KO, ['N'] = 23, ['y'] = KO, [164] = KO, [207] = KO, [250] = KO,
[ 36] = KO, ['O'] = 24, ['z'] = KO, [165] = KO, [208] = KO, [251] = KO,
[ 37] = KO, ['P'] = 25, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
[ 38] = KO, ['Q'] = 26, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
[ 39] = KO, ['R'] = 27, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
[ 40] = KO, ['S'] = 28, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
[ 41] = KO, ['T'] = 29, [127] = KO, [170] = KO, [213] = KO,
[ 42] = KO, ['U'] = 30, [128] = KO, [171] = KO, [214] = KO,
};
int32_t base32hex_decode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return -1;
}
if (in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) {
return -1;
}
if ((in_len % 8) != 0) {
return -1;
}
const uint8_t *stop = in + in_len;
uint8_t *bin = out;
uint8_t pad_len = 0;
uint8_t c1, c2, c3, c4, c5, c6, c7, c8;
// Decoding loop takes 8 characters and creates 5 bytes.
while (in < stop) {
// Filling and transforming 8 Base32hex chars.
c1 = base32hex_dec[in[0]];
c2 = base32hex_dec[in[1]];
c3 = base32hex_dec[in[2]];
c4 = base32hex_dec[in[3]];
c5 = base32hex_dec[in[4]];
c6 = base32hex_dec[in[5]];
c7 = base32hex_dec[in[6]];
c8 = base32hex_dec[in[7]];
// Check 8. char if is bad or padding.
if (c8 >= PD) {
if (c8 == PD && pad_len == 0) {
pad_len = 1;
} else {
return -1;
}
}
// Check 7. char if is bad or padding (if so, 6. must be too).
if (c7 >= PD) {
if (c7 == PD && c6 == PD && pad_len == 1) {
pad_len = 3;
} else {
return -1;
}
}
// Check 6. char if is bad or padding.
if (c6 >= PD) {
if (!(c6 == PD && pad_len == 3)) {
return -1;
}
}
// Check 5. char if is bad or padding.
if (c5 >= PD) {
if (c5 == PD && pad_len == 3) {
pad_len = 4;
} else {
return -1;
}
}
// Check 4. char if is bad or padding (if so, 3. must be too).
if (c4 >= PD) {
if (c4 == PD && c3 == PD && pad_len == 4) {
pad_len = 6;
} else {
return -1;
}
}
// Check 3. char if is bad or padding.
if (c3 >= PD) {
if (!(c3 == PD && pad_len == 6)) {
return -1;
}
}
// 1. and 2. chars must not be padding.
if (c2 >= PD || c1 >= PD) {
return -1;
}
// Computing of output data based on padding length.
switch (pad_len) {
case 0:
bin[4] = (c7 << 5) + c8;
case 1:
bin[3] = (c5 << 7) + (c6 << 2) + (c7 >> 3);
case 3:
bin[2] = (c4 << 4) + (c5 >> 1);
case 4:
bin[1] = (c2 << 6) + (c3 << 1) + (c4 >> 4);
case 6:
bin[0] = (c1 << 3) + (c2 >> 2);
}
// Update output end.
switch (pad_len) {
case 0:
bin += 5;
break;
case 1:
bin += 4;
break;
case 3:
bin += 3;
break;
case 4:
bin += 2;
break;
case 6:
bin += 1;
break;
}
in += 8;
}
return (bin - out);
}
int32_t base32hex_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return -1;
}
if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 4) / 5) * 8) {
return -1;
}
uint8_t rest_len = in_len % 5;
const uint8_t *stop = in + in_len - rest_len;
uint8_t *text = out;
// Encoding loop takes 5 bytes and creates 8 characters.
while (in < stop) {
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
text[4] = base32hex_enc[(in[2] & 0x0F) << 1 | in[3] >> 7];
text[5] = base32hex_enc[(in[3] & 0x7C) >> 2];
text[6] = base32hex_enc[(in[3] & 0x03) << 3 | in[4] >> 5];
text[7] = base32hex_enc[in[4] & 0x1F];
text += 8;
in += 5;
}
// Processing of padding, if any.
switch (rest_len) {
case 4:
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
text[4] = base32hex_enc[(in[2] & 0x0F) << 1 | in[3] >> 7];
text[5] = base32hex_enc[(in[3] & 0x7C) >> 2];
text[6] = base32hex_enc[(in[3] & 0x03) << 3];
text[7] = base32hex_pad;
text += 8;
break;
case 3:
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
text[4] = base32hex_enc[(in[2] & 0x0F) << 1];
text[5] = base32hex_pad;
text[6] = base32hex_pad;
text[7] = base32hex_pad;
text += 8;
break;
case 2:
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4];
text[4] = base32hex_pad;
text[5] = base32hex_pad;
text[6] = base32hex_pad;
text[7] = base32hex_pad;
text += 8;
break;
case 1:
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2];
text[2] = base32hex_pad;
text[3] = base32hex_pad;
text[4] = base32hex_pad;
text[5] = base32hex_pad;
text[6] = base32hex_pad;
text[7] = base32hex_pad;
text += 8;
break;
}
return (text - out);
}
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
/*!
* \file
*
* \brief Base32hex implementation (RFC 4648).
*
* \note Input Base32hex string can contain a-v characters. These characters
* are considered as A-V equivalent.
*
* \addtogroup contrib
* @{
*/
#pragma once
#include <stdint.h>
/*!
* \brief Decodes text data using Base32hex.
*
* \note Input data needn't be terminated with '\0'.
*
* \note Input data must be continuous Base32hex string!
*
* \param in Input text data.
* \param in_len Length of input string.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
* \retval KNOT_E* if error.
*/
int32_t base32hex_decode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*!
* \brief Encodes binary data using Base32hex. Lower case is used!
*
* \note Output data buffer contains Base32hex text string which isn't
* terminated with '\0'!
*
* \param in Input binary data.
* \param in_len Length of input data.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
* \retval <0 if error.
*/
int32_t base32hex_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*! @} */
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: knotdns-base32hex
DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-4f29f08d-5fbf-4793-934c-9a6a2e6d5517
PackageName: knotdns-base32hex
PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@2b3c828a4cb8d9595318552483d4947345426c30#src/libknot/internal/base32hex.c
PackageOriginator: Organization: Knot DNS contributors
PackageLicenseDeclared: GPL-3.0-or-later
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "base64.h"
#include "libknot/errcode.h"
#include <stdlib.h>
#include <stdint.h>
/*! \brief Maximal length of binary input to Base64 encoding. */
#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3)
/*! \brief Base64 padding character. */
static const uint8_t base64_pad = '=';
/*! \brief Base64 alphabet. */
static const uint8_t base64_enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*! \brief Indicates bad Base64 character. */
#define KO 255
/*! \brief Indicates Base64 padding character. */
#define PD 64
/*! \brief Transformation and validation table for decoding Base64. */
static const uint8_t base64_dec[256] = {
[ 0] = KO, ['+'] = 62, ['V'] = 21, [129] = KO, [172] = KO, [215] = KO,
[ 1] = KO, [ 44] = KO, ['W'] = 22, [130] = KO, [173] = KO, [216] = KO,
[ 2] = KO, [ 45] = KO, ['X'] = 23, [131] = KO, [174] = KO, [217] = KO,
[ 3] = KO, [ 46] = KO, ['Y'] = 24, [132] = KO, [175] = KO, [218] = KO,
[ 4] = KO, ['/'] = 63, ['Z'] = 25, [133] = KO, [176] = KO, [219] = KO,
[ 5] = KO, ['0'] = 52, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
[ 6] = KO, ['1'] = 53, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
[ 7] = KO, ['2'] = 54, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
[ 8] = KO, ['3'] = 55, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
[ 9] = KO, ['4'] = 56, [ 95] = KO, [138] = KO, [181] = KO, [224] = KO,
[ 10] = KO, ['5'] = 57, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
[ 11] = KO, ['6'] = 58, ['a'] = 26, [140] = KO, [183] = KO, [226] = KO,
[ 12] = KO, ['7'] = 59, ['b'] = 27, [141] = KO, [184] = KO, [227] = KO,
[ 13] = KO, ['8'] = 60, ['c'] = 28, [142] = KO, [185] = KO, [228] = KO,
[ 14] = KO, ['9'] = 61, ['d'] = 29, [143] = KO, [186] = KO, [229] = KO,
[ 15] = KO, [ 58] = KO, ['e'] = 30, [144] = KO, [187] = KO, [230] = KO,
[ 16] = KO, [ 59] = KO, ['f'] = 31, [145] = KO, [188] = KO, [231] = KO,
[ 17] = KO, [ 60] = KO, ['g'] = 32, [146] = KO, [189] = KO, [232] = KO,
[ 18] = KO, ['='] = PD, ['h'] = 33, [147] = KO, [190] = KO, [233] = KO,
[ 19] = KO, [ 62] = KO, ['i'] = 34, [148] = KO, [191] = KO, [234] = KO,
[ 20] = KO, [ 63] = KO, ['j'] = 35, [149] = KO, [192] = KO, [235] = KO,
[ 21] = KO, [ 64] = KO, ['k'] = 36, [150] = KO, [193] = KO, [236] = KO,
[ 22] = KO, ['A'] = 0, ['l'] = 37, [151] = KO, [194] = KO, [237] = KO,
[ 23] = KO, ['B'] = 1, ['m'] = 38, [152] = KO, [195] = KO, [238] = KO,
[ 24] = KO, ['C'] = 2, ['n'] = 39, [153] = KO, [196] = KO, [239] = KO,
[ 25] = KO, ['D'] = 3, ['o'] = 40, [154] = KO, [197] = KO, [240] = KO,
[ 26] = KO, ['E'] = 4, ['p'] = 41, [155] = KO, [198] = KO, [241] = KO,
[ 27] = KO, ['F'] = 5, ['q'] = 42, [156] = KO, [199] = KO, [242] = KO,
[ 28] = KO, ['G'] = 6, ['r'] = 43, [157] = KO, [200] = KO, [243] = KO,
[ 29] = KO, ['H'] = 7, ['s'] = 44, [158] = KO, [201] = KO, [244] = KO,
[ 30] = KO, ['I'] = 8, ['t'] = 45, [159] = KO, [202] = KO, [245] = KO,
[ 31] = KO, ['J'] = 9, ['u'] = 46, [160] = KO, [203] = KO, [246] = KO,
[ 32] = KO, ['K'] = 10, ['v'] = 47, [161] = KO, [204] = KO, [247] = KO,
[ 33] = KO, ['L'] = 11, ['w'] = 48, [162] = KO, [205] = KO, [248] = KO,
[ 34] = KO, ['M'] = 12, ['x'] = 49, [163] = KO, [206] = KO, [249] = KO,
[ 35] = KO, ['N'] = 13, ['y'] = 50, [164] = KO, [207] = KO, [250] = KO,
[ 36] = KO, ['O'] = 14, ['z'] = 51, [165] = KO, [208] = KO, [251] = KO,
[ 37] = KO, ['P'] = 15, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
[ 38] = KO, ['Q'] = 16, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
[ 39] = KO, ['R'] = 17, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
[ 40] = KO, ['S'] = 18, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
[ 41] = KO, ['T'] = 19, [127] = KO, [170] = KO, [213] = KO,
[ 42] = KO, ['U'] = 20, [128] = KO, [171] = KO, [214] = KO,
};
int32_t kr_base64_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
return KNOT_ERANGE;
}
uint8_t rest_len = in_len % 3;
const uint8_t *stop = in + in_len - rest_len;
uint8_t *text = out;
// Encoding loop takes 3 bytes and creates 4 characters.
while (in < stop) {
text[0] = base64_enc[in[0] >> 2];
text[1] = base64_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
text[2] = base64_enc[(in[1] & 0x0F) << 2 | in[2] >> 6];
text[3] = base64_enc[in[2] & 0x3F];
text += 4;
in += 3;
}
// Processing of padding, if any.
switch (rest_len) {
case 2:
text[0] = base64_enc[in[0] >> 2];
text[1] = base64_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
text[2] = base64_enc[(in[1] & 0x0F) << 2];
text[3] = base64_pad;
text += 4;
break;
case 1:
text[0] = base64_enc[in[0] >> 2];
text[1] = base64_enc[(in[0] & 0x03) << 4];
text[2] = base64_pad;
text[3] = base64_pad;
text += 4;
break;
}
return (text - out);
}
int32_t kr_base64_encode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out)
{
// Checking inputs.
if (out == NULL) {
return KNOT_EINVAL;
}
if (in_len > MAX_BIN_DATA_LEN) {
return KNOT_ERANGE;
}
// Compute output buffer length.
uint32_t out_len = ((in_len + 2) / 3) * 4;
// Allocate output buffer.
*out = malloc(out_len);
if (*out == NULL) {
return KNOT_ENOMEM;
}
// Encode data.
int32_t ret = kr_base64_encode(in, in_len, *out, out_len);
if (ret < 0) {
free(*out);
*out = NULL;
}
return ret;
}
int32_t kr_base64_decode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
return KNOT_ERANGE;
}
if ((in_len % 4) != 0) {
return KNOT_BASE64_ESIZE;
}
const uint8_t *stop = in + in_len;
uint8_t *bin = out;
uint8_t pad_len = 0;
uint8_t c1, c2, c3, c4;
// Decoding loop takes 4 characters and creates 3 bytes.
while (in < stop) {
// Filling and transforming 4 Base64 chars.
c1 = base64_dec[in[0]];
c2 = base64_dec[in[1]];
c3 = base64_dec[in[2]];
c4 = base64_dec[in[3]];
// Check 4. char if is bad or padding.
if (c4 >= PD) {
if (c4 == PD && pad_len == 0) {
pad_len = 1;
} else {
return KNOT_BASE64_ECHAR;
}
}
// Check 3. char if is bad or padding.
if (c3 >= PD) {
if (c3 == PD && pad_len == 1) {
pad_len = 2;
} else {
return KNOT_BASE64_ECHAR;
}
}
// Check 1. and 2. chars if are not padding.
if (c2 >= PD || c1 >= PD) {
return KNOT_BASE64_ECHAR;
}
// Computing of output data based on padding length.
switch (pad_len) {
case 0:
bin[2] = (c3 << 6) + c4;
// FALLTHROUGH
case 1:
bin[1] = (c2 << 4) + (c3 >> 2);
// FALLTHROUGH
case 2:
bin[0] = (c1 << 2) + (c2 >> 4);
}
// Update output end.
switch (pad_len) {
case 0:
bin += 3;
break;
case 1:
bin += 2;
break;
case 2:
bin += 1;
break;
}
in += 4;
}
return (bin - out);
}
int32_t kr_base64_decode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out)
{
// Checking inputs.
if (out == NULL) {
return KNOT_EINVAL;
}
// Compute output buffer length.
uint32_t out_len = ((in_len + 3) / 4) * 3;
// Allocate output buffer.
*out = malloc(out_len);
if (*out == NULL) {
return KNOT_ENOMEM;
}
// Decode data.
int32_t ret = kr_base64_decode(in, in_len, *out, out_len);
if (ret < 0) {
free(*out);
*out = NULL;
}
return ret;
}
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
/*!
* \file
*
* \brief Base64 implementation (RFC 4648).
*
* \addtogroup contrib
* @{
*/
#pragma once
#include <stdint.h>
/*!
* \brief Encodes binary data using Base64.
*
* \note Output data buffer contains Base64 text string which isn't
* terminated with '\0'!
*
* \param in Input binary data.
* \param in_len Length of input data.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
* \retval KNOT_E* if error.
*/
int32_t kr_base64_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*!
* \brief Encodes binary data using Base64 and output stores to own buffer.
*
* \note Output data buffer contains Base64 text string which isn't
* terminated with '\0'!
*
* \note Output buffer should be deallocated after use.
*
* \param in Input binary data.
* \param in_len Length of input data.
* \param out Output data buffer.
*
* \retval >=0 length of output string.
* \retval KNOT_E* if error.
*/
int32_t kr_base64_encode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out);
/*!
* \brief Decodes text data using Base64.
*
* \note Input data needn't be terminated with '\0'.
*
* \note Input data must be continuous Base64 string!
*
* \param in Input text data.
* \param in_len Length of input string.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
* \retval KNOT_E* if error.
*/
int32_t kr_base64_decode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*!
* \brief Decodes text data using Base64 and output stores to own buffer.
*
* \note Input data needn't be terminated with '\0'.
*
* \note Input data must be continuous Base64 string!
*
* \note Output buffer should be deallocated after use.
*
* \param in Input text data.
* \param in_len Length of input string.
* \param out Output data buffer.
*
* \retval >=0 length of output data.
* \retval KNOT_E* if error.
*/
int32_t kr_base64_decode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out);
/*! @} */
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: knotdns-base64
DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-669dfa8c-3b50-425f-92fc-9b7ce18999f2
PackageName: knotdns-base64
PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@2b3c828a4cb8d9595318552483d4947345426c30#src/libknot/internal/base64.c
PackageOriginator: Organization: Knot DNS contributors
PackageLicenseDeclared: GPL-3.0-or-later
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "contrib/base64url.h"
#include "libknot/errcode.h"
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
/*! \brief Maximal length of binary input to Base64url encoding. */
#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3)
/*! \brief Base64url padding character. */
static const uint8_t base64url_pad = '\0';
/*! \brief Base64 alphabet. */
static const uint8_t base64url_enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
/*! \brief Indicates bad Base64 character. */
#define KO 255
/*! \brief Indicates Base64 padding character. */
#define PD 64
/*! \brief Transformation and validation table for decoding Base64. */
static const uint8_t base64url_dec[256] = {
[ 0] = PD, [ 43] = KO, ['V'] = 21, [129] = KO, [172] = KO, [215] = KO,
[ 1] = KO, [ 44] = KO, ['W'] = 22, [130] = KO, [173] = KO, [216] = KO,
[ 2] = KO, ['-'] = 62, ['X'] = 23, [131] = KO, [174] = KO, [217] = KO,
[ 3] = KO, [ 46] = KO, ['Y'] = 24, [132] = KO, [175] = KO, [218] = KO,
[ 4] = KO, [ 47] = KO, ['Z'] = 25, [133] = KO, [176] = KO, [219] = KO,
[ 5] = KO, ['0'] = 52, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
[ 6] = KO, ['1'] = 53, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
[ 7] = KO, ['2'] = 54, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
[ 8] = KO, ['3'] = 55, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
[ 9] = KO, ['4'] = 56, ['_'] = 63, [138] = KO, [181] = KO, [224] = KO,
[ 10] = KO, ['5'] = 57, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
[ 11] = KO, ['6'] = 58, ['a'] = 26, [140] = KO, [183] = KO, [226] = KO,
[ 12] = KO, ['7'] = 59, ['b'] = 27, [141] = KO, [184] = KO, [227] = KO,
[ 13] = KO, ['8'] = 60, ['c'] = 28, [142] = KO, [185] = KO, [228] = KO,
[ 14] = KO, ['9'] = 61, ['d'] = 29, [143] = KO, [186] = KO, [229] = KO,
[ 15] = KO, [ 58] = KO, ['e'] = 30, [144] = KO, [187] = KO, [230] = KO,
[ 16] = KO, [ 59] = KO, ['f'] = 31, [145] = KO, [188] = KO, [231] = KO,
[ 17] = KO, [ 60] = KO, ['g'] = 32, [146] = KO, [189] = KO, [232] = KO,
[ 18] = KO, [ 61] = KO, ['h'] = 33, [147] = KO, [190] = KO, [233] = KO,
[ 19] = KO, [ 62] = KO, ['i'] = 34, [148] = KO, [191] = KO, [234] = KO,
[ 20] = KO, [ 63] = KO, ['j'] = 35, [149] = KO, [192] = KO, [235] = KO,
[ 21] = KO, [ 64] = KO, ['k'] = 36, [150] = KO, [193] = KO, [236] = KO,
[ 22] = KO, ['A'] = 0, ['l'] = 37, [151] = KO, [194] = KO, [237] = KO,
[ 23] = KO, ['B'] = 1, ['m'] = 38, [152] = KO, [195] = KO, [238] = KO,
[ 24] = KO, ['C'] = 2, ['n'] = 39, [153] = KO, [196] = KO, [239] = KO,
[ 25] = KO, ['D'] = 3, ['o'] = 40, [154] = KO, [197] = KO, [240] = KO,
[ 26] = KO, ['E'] = 4, ['p'] = 41, [155] = KO, [198] = KO, [241] = KO,
[ 27] = KO, ['F'] = 5, ['q'] = 42, [156] = KO, [199] = KO, [242] = KO,
[ 28] = KO, ['G'] = 6, ['r'] = 43, [157] = KO, [200] = KO, [243] = KO,
[ 29] = KO, ['H'] = 7, ['s'] = 44, [158] = KO, [201] = KO, [244] = KO,
[ 30] = KO, ['I'] = 8, ['t'] = 45, [159] = KO, [202] = KO, [245] = KO,
[ 31] = KO, ['J'] = 9, ['u'] = 46, [160] = KO, [203] = KO, [246] = KO,
[ 32] = KO, ['K'] = 10, ['v'] = 47, [161] = KO, [204] = KO, [247] = KO,
[ 33] = KO, ['L'] = 11, ['w'] = 48, [162] = KO, [205] = KO, [248] = KO,
[ 34] = KO, ['M'] = 12, ['x'] = 49, [163] = KO, [206] = KO, [249] = KO,
[ 35] = KO, ['N'] = 13, ['y'] = 50, [164] = KO, [207] = KO, [250] = KO,
[ 36] = KO, ['O'] = 14, ['z'] = 51, [165] = KO, [208] = KO, [251] = KO,
['%'] = KO, ['P'] = 15, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
[ 38] = KO, ['Q'] = 16, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
[ 39] = KO, ['R'] = 17, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
[ 40] = KO, ['S'] = 18, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
[ 41] = KO, ['T'] = 19, [127] = KO, [170] = KO, [213] = KO,
[ 42] = KO, ['U'] = 20, [128] = KO, [171] = KO, [214] = KO,
};
int32_t kr_base64url_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
return KNOT_ERANGE;
}
uint8_t rest_len = in_len % 3;
const uint8_t *stop = in + in_len - rest_len;
uint8_t *text = out;
// Encoding loop takes 3 bytes and creates 4 characters.
while (in < stop) {
text[0] = base64url_enc[in[0] >> 2];
text[1] = base64url_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
text[2] = base64url_enc[(in[1] & 0x0F) << 2 | in[2] >> 6];
text[3] = base64url_enc[in[2] & 0x3F];
text += 4;
in += 3;
}
// Processing of padding, if any.
switch (rest_len) {
case 2:
text[0] = base64url_enc[in[0] >> 2];
text[1] = base64url_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
text[2] = base64url_enc[(in[1] & 0x0F) << 2];
text[3] = base64url_pad;
text += 3;
break;
case 1:
text[0] = base64url_enc[in[0] >> 2];
text[1] = base64url_enc[(in[0] & 0x03) << 4];
text[2] = base64url_pad;
text[3] = base64url_pad;
text += 2;
break;
}
return (text - out);
}
int32_t kr_base64url_encode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out)
{
// Checking inputs.
if (out == NULL) {
return KNOT_EINVAL;
}
if (in_len > MAX_BIN_DATA_LEN) {
return KNOT_ERANGE;
}
// Compute output buffer length.
uint32_t out_len = ((in_len + 2) / 3) * 4;
// Allocate output buffer.
*out = malloc(out_len);
if (*out == NULL) {
return KNOT_ENOMEM;
}
// Encode data.
int32_t ret = kr_base64url_encode(in, in_len, *out, out_len);
if (ret < 0) {
free(*out);
*out = NULL;
}
return ret;
}
int32_t kr_base64url_decode(const uint8_t *in,
uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
// cut up to two "%3d" from the end of input
int pad3d = 0;
const uint8_t *end = in + in_len;
char *perc3d = "d3%d3%", *stop3d = perc3d + 6;
while (end != in && perc3d != stop3d && tolower(*--end) == *perc3d) {
if (*perc3d++ == '%') {
in_len -= 3;
pad3d++;
}
}
if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
return KNOT_ERANGE;
}
const uint8_t *stop = in + in_len;
uint8_t *bin = out;
uint8_t pad_len = 0;
uint8_t c1, c2, c3, c4;
// Decoding loop takes 4 characters and creates 3 bytes.
while (in < stop) {
// Filling and transforming 4 Base64 chars.
c1 = base64url_dec[in[0]] ;
c2 = base64url_dec[in[1]] ;
c3 = (in + 2 < stop) ? base64url_dec[in[2]] : PD;
c4 = (in + 3 < stop) ? base64url_dec[in[3]] : PD;
// Check 1. and 2. chars if are not padding
if (c1 >= PD || c2 >= PD) {
return KNOT_BASE64_ECHAR;
}
// Check 3. char if is bad or padding.
else if (c3 >= PD) {
if (c3 == PD) {
pad_len = 2;
} else {
return KNOT_BASE64_ECHAR;
}
}
// Check 3. char if is bad or padding.
else if (c4 >= PD) {
if (c4 == PD) {
pad_len = 1;
} else {
return KNOT_BASE64_ECHAR;
}
}
if (pad_len > 0 && in <= stop - 4) {
return KNOT_BASE64_ECHAR;
}
// Computing of output data based on padding length.
switch (pad_len) {
case 0:
bin[2] = (c3 << 6) + c4;
// FALLTHROUGH
case 1:
bin[1] = (c2 << 4) + (c3 >> 2);
// FALLTHROUGH
case 2:
bin[0] = (c1 << 2) + (c2 >> 4);
}
// Update output end.
switch (pad_len) {
case 0:
bin += 3;
break;
case 1:
bin += 2;
goto end;
case 2:
bin += 1;
goto end;
}
in += 4;
}
end:
if (pad3d > pad_len) {
return KNOT_BASE64_ECHAR;
}
return (bin - out);
}
int32_t kr_base64url_decode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out)
{
// Checking inputs.
if (out == NULL) {
return KNOT_EINVAL;
}
// Compute output buffer length.
uint32_t out_len = ((in_len + 3) / 4) * 3;
// Allocate output buffer.
*out = malloc(out_len);
if (*out == NULL) {
return KNOT_ENOMEM;
}
// Decode data.
int32_t ret = kr_base64url_decode(in, in_len, *out, out_len);
if (ret < 0) {
free(*out);
*out = NULL;
}
return ret;
}
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*!
* \brief Base64url implementation (RFC 4648).
*/
#pragma once
#include <stdint.h>
/*!
* \brief Encodes binary data using Base64.
*
* \note Output data buffer contains Base64 text string which isn't
* terminated with '\0'!
*
* \param in Input binary data.
* \param in_len Length of input data.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
* \retval KNOT_E* if error.
*/
int32_t kr_base64url_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*!
* \brief Encodes binary data using Base64 and output stores to own buffer.
*
* \note Output data buffer contains Base64 text string which isn't
* terminated with '\0'!
*
* \note Output buffer should be deallocated after use.
*
* \param in Input binary data.
* \param in_len Length of input data.
* \param out Output data buffer.
*
* \retval >=0 length of output string.
* \retval KNOT_E* if error.
*/
int32_t kr_base64url_encode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out);
/*!
* \brief Decodes text data using Base64.
*
* \note Input data needn't be terminated with '\0'.
*
* \note Input data must be continuous Base64 string!
*
* \param in Input text data.
* \param in_len Length of input string.
* \param out Output data buffer.
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
* \retval KNOT_E* if error.
*/
int32_t kr_base64url_decode(const uint8_t *in,
uint32_t in_len,
uint8_t *out,
const uint32_t out_len);
/*!
* \brief Decodes text data using Base64 and output stores to own buffer.
*
* \note Input data needn't be terminated with '\0'.
*
* \note Input data must be continuous Base64 string!
*
* \note Output buffer should be deallocated after use.
*
* \param in Input text data.
* \param in_len Length of input string.
* \param out Output data buffer.
*
* \retval >=0 length of output data.
* \retval KNOT_E* if error.
*/
int32_t kr_base64url_decode_alloc(const uint8_t *in,
const uint32_t in_len,
uint8_t **out);
/*! @} */
#include "config.h"
#include <stdio.h>
#include <string.h>
/**
* asprintf - asprintf wrapper (and if necessary, implementation).
*
* This provides a convenient wrapper for asprintf, and also implements
* asprintf if necessary.
*
* Author: Rusty Russell <rusty@rustcorp.com.au>
*
* License: MIT
*
* Example:
* #include <ccan/asprintf/asprintf.h>
* #include <unistd.h>
* #include <err.h>
*
* int main(int argc, char *argv[])
* {
* char *p = afmt("This program has %i arguments", argc);
* int ret;
*
* while ((ret = write(STDOUT_FILENO, p, strlen(p))) > 0) {
* p += ret;
* if (!*p)
* exit(0);
* }
* err(1, "Writing to stdout");
* }
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/compiler\n");
return 0;
}
return 1;
}
/* Licensed under BSD-MIT - see LICENSE file for details */
/* SPDX-License-Identifier: MIT
* Source: https://ccodearchive.net/info/asprintf.html */
#include <ccan/asprintf/asprintf.h>
#include <stdarg.h>
#include <stdio.h>
......
/* Licensed under BSD-MIT - see LICENSE file for details */
/* SPDX-License-Identifier: MIT
* Source: https://ccodearchive.net/info/asprintf.html */
#ifndef CCAN_ASPRINTF_H
#define CCAN_ASPRINTF_H
#include "config.h"
......
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: ccan-asprintf
DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-40d4b71d-00e9-4e75-b6da-559203e6b815
PackageName: asprintf
PackageDownloadLocation: git+https://github.com/rustyrussell/ccan@fb1dfd092940905883ea6473162f5f6e36624da2#ccan/asprintf
PackageOriginator: Person: Rusty Russell (rusty@rustcorp.com.au)
PackageLicenseDeclared: MIT
#include "config.h"
#include <string.h>
#include <stdio.h>
/**
* compiler - macros for common compiler extensions
*
* Abstracts away some compiler hints. Currently these include:
* - COLD
* For functions not called in fast paths (aka. cold functions)
* - PRINTF_FMT
* For functions which take printf-style parameters.
* - CONST_FUNCTION
* For functions which return the same value for same parameters.
* - NEEDED
* For functions and variables which must be emitted even if unused.
* - UNNEEDED
* For functions and variables which need not be emitted if unused.
* - UNUSED
* For parameters which are not used.
* - IS_COMPILE_CONSTANT()
* For using different tradeoffs for compiletime vs runtime evaluation.
*
* License: CC0 (Public domain)
* Author: Rusty Russell <rusty@rustcorp.com.au>
*
* Example:
* #include <ccan/compiler/compiler.h>
* #include <stdio.h>
* #include <stdarg.h>
*
* // Example of a (slow-path) logging function.
* static int log_threshold = 2;
* static void COLD PRINTF_FMT(2,3)
* logger(int level, const char *fmt, ...)
* {
* va_list ap;
* va_start(ap, fmt);
* if (level >= log_threshold)
* vfprintf(stderr, fmt, ap);
* va_end(ap);
* }
*
* int main(int argc, char *argv[])
* {
* if (argc != 1) {
* logger(3, "Don't want %i arguments!\n", argc-1);
* return 1;
* }
* return 0;
* }
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
return 0;
}
return 1;
}
/* CC0 (Public domain) - see LICENSE file for details */
/* SPDX-License-Identifier: CC0-1.0
* Source: https://ccodearchive.net/info/compiler.html */
#ifndef CCAN_COMPILER_H
#define CCAN_COMPILER_H
#include "config.h"
......
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: ccan-compiler
DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-1569e849-880d-4ce7-ba3e-f4aaec8fce52
PackageName: compiler
PackageDownloadLocation: git+https://github.com/rustyrussell/ccan@23e96f89d54b8d5c4675284bbcd44fba68d8f826#ccan/compiler
PackageOriginator: Person: Rusty Russell (rusty@rustcorp.com.au)
PackageLicenseDeclared: CC0-1.0
#include <ccan/compiler/compiler.h>
static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...)
{
}
int main(int argc, char *argv[])
{
unsigned int i = 0;
my_printf(1, "Not a pointer "
#ifdef FAIL
"%p",
#if !HAVE_ATTRIBUTE_PRINTF
#error "Unfortunately we don't fail if !HAVE_ATTRIBUTE_PRINTF."
#endif
#else
"%i",
#endif
i);
return 0;
}
#include <ccan/compiler/compiler.h>
#include <ccan/tap/tap.h>
int main(int argc, char *argv[])
{
plan_tests(2);
ok1(!IS_COMPILE_CONSTANT(argc));
#if HAVE_BUILTIN_CONSTANT_P
ok1(IS_COMPILE_CONSTANT(7));
#else
pass("If !HAVE_BUILTIN_CONSTANT_P, IS_COMPILE_CONSTANT always false");
#endif
return exit_status();
}