Bug 224845

Summary: Change return type to size_t in dd(1)
Product: Base System Reporter: Bulat <bltsrc>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed Not A Bug    
Severity: Affects Many People CC: bltsrc, mhorne063, pstef
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   

Description Bulat 2018-01-02 18:29:35 UTC
r326025

/bin/dd/args.c
static uintmax_t get_num(const char *val)

type SIZE_T would be more appropriate as a return value,
because size_t could include largest size of any object.

uintmax_t on the other hand may be one of extended integer types(if implemented, for example, 128bit number on x64), so exists possibility, that no object could have that much size,
so its more than needed, size_t would serve better in this case.

Indeed, analogous function that does the same
static size_t get_bsz(char *val)
in OpenBSD's dd has return type size_t;
Comment 1 Mitchell Horne 2018-01-09 17:17:49 UTC
(In reply to Bulat from comment #0)

What appears different between the FreeBSD and OpenBSD implementations of dd is
that FreeBSD supports the 't' (tera) and 'p' (peta) file size options on the command line. So on systems where size_t is implemented as 32 bits, some information would be lost if the user were to input a large file size. By 
using uintmax_t, it (almost) guarantees that the entirety of the user's input
size is captured, as uintmax_t is at least 64 bits wide. In the case that the
largest possible file size is smaller than the user's input, SIZE_MAX is used instead.

An example: The user inputs "1t" as a file size on a system where size_t is
32-bits wide. The value 1 is taken and bit shifted 40 times (1TB = 2^40 bytes),
and the 32 bit value of size_t is filled with only zeros, resulting in a 0 byte
output file or an error.
Comment 2 Piotr Pawel Stefaniak freebsd_committer freebsd_triage 2022-04-21 16:35:54 UTC
This is purposely wider than size_t. get_num() is used by several functions, including f_count() and the uintmax_t type makes it possible to copy UINTMAX_MAX blocks. Some of the callers can compare the value against SSIZE_MAX and yield an error if it is too large; otherwise, the value is converted to size_t.