2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-05 09:05:40 +00:00
Files
bind/lib/isccfg/include/isccfg/duration.h
Aram Sargsyan 24aa154b67 Handle large numbers when parsing/printing a duration
The isccfg_duration_fromtext() function is truncating large numbers
to 32 bits instead of capping or rejecting them, i.e. 64424509445,
which is 0xf00000005, gets parsed as 32-bit value 5 (0x00000005).

Fail parsing a duration if any of its components is bigger than
32 bits. Using those kind of big numbers has no practical use case
for a duration.

The isccfg_duration_toseconds() function can overflow the 32 bit
seconds variable when calculating the duration from its component
parts.

To avoid that, use 64-bit calculation and return UINT32_MAX if the
calculated value is bigger than UINT32_MAX. Again, a number this big
has no practical use case anyway.

The buffer for the generated duration string is limited to 64 bytes,
which, in theory, is smaller than the longest possible generated
duration string.

Use 80 bytes instead, calculated by the '7 x (10 + 1) + 3' formula,
where '7' is the count of the duration's parts (year, month, etc.), '10'
is their maximum length when printed as a decimal number, '1' is their
indicator character (Y, M, etc.), and 3 is two more indicators (P and T)
and the terminating NUL character.

(cherry picked from commit fddaebb285)
2022-10-17 08:54:10 +00:00

88 lines
1.9 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*! \file */
#include <inttypes.h>
#include <stdbool.h>
#include <isc/lang.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
#define CFG_DURATION_MAXLEN 80
/*%
* A configuration object to store ISO 8601 durations.
*/
typedef struct isccfg_duration {
/*
* The duration is stored in multiple parts:
* [0] Years
* [1] Months
* [2] Weeks
* [3] Days
* [4] Hours
* [5] Minutes
* [6] Seconds
*/
uint32_t parts[7];
bool iso8601;
bool unlimited;
} isccfg_duration_t;
isc_result_t
isccfg_duration_fromtext(isc_textregion_t *source, isccfg_duration_t *duration);
/*%<
* Converts an ISO 8601 duration style value.
*
* Returns:
*\li ISC_R_SUCCESS
*\li DNS_R_BADNUMBER
*/
isc_result_t
isccfg_parse_duration(isc_textregion_t *source, isccfg_duration_t *duration);
/*%<
* Converts a duration string to a ISO 8601 duration.
* If the string does not start with a P (or p), fall back to TTL-style value.
* In that case the duration will be treated in seconds only.
*
* Returns:
*\li ISC_R_SUCCESS
*\li DNS_R_BADNUMBER
*\li DNS_R_BADTTL
*/
uint32_t
isccfg_duration_toseconds(const isccfg_duration_t *duration);
/*%<
* Converts an ISO 8601 duration to seconds.
* The conversion is approximate:
* - Months will be treated as 31 days.
* - Years will be treated as 365 days.
*
* Notes:
*\li If the duration in seconds is greater than UINT32_MAX, the return value
* will be UINT32_MAX.
*
* Returns:
*\li The duration in seconds.
*/
ISC_LANG_ENDDECLS