Document: N1683
Date: 2013-03-12
Defect Report #4nn
Previous Defect Report < - > Next Defect Report
Submitter: Douglas Walls
Submission Date: 2013-03-12
Source:WG14
Reference Document: N1683
Version: 1.0
Date:
Subject: Issue with constraints for wide character function
arguments involving RSIZE_MAX
Summary
K.3.7.2.2 The strncat_s function
The strncat_s() has a
constraint that neither s1max
nor n shall be greater than RSIZE_MAX.
Both s1max and n are defined as representing a number of char
sized characters.
K.3.9.2.1.2 The wcsncpy_s function
The same constraint is given for the function the wcsncat_s()
function, i.e. that neither s1max
nor n shall be greater than RSIZE_MAX. For wcsncat_s(), s1max and n are defined as representing a
number of wchar_t sized
characters. On most implementations the size of a
wide characters is many times the size of a char. On Solaris it
is 4 time the size.
K.3.4 Integer types <stdint.h> is
defined as follows
1 The header <stdint.h>
defines a macro.
2 The macro is
RSIZE_MAX
which expands to a value 386) of type size_t.
Functions that have parameters of type rsize_t
consider it a runtime-constraint violation if the values of those
parameters are greater than RSIZE_MAX.
386) The macro RSIZE_MAX need
not expand to a constant expression.
Recommended practice
3 Extremely large object sizes are frequently a sign that an object’s
size was calculated incorrectly. For example, negative numbers appear
as very large positive numbers when converted to an unsigned type like
size_t. Also, some implementations do not support objects as large as
the maximum value that can be represented by type size_t.
4 For those reasons, it is sometimes beneficial to restrict the range
of object sizes to detect programming errors. For implementations
targeting machines with large address spaces, it is recommended that RSIZE_MAX be defined as the smaller
of the size of the largest object supported or (SIZE_MAX >> 1), even if this
limit is smaller than the size of some legitimate, but very large,
objects. Implementations targeting machines with small address spaces
may wish to define RSIZE_MAX
as SIZE_MAX, which means that
there is no object size that is considered a runtime-constraint
violation.
The recommended practice implies RSIZE_MAX
represents maximum object sizes.
Footnote 386) implies an implementation can adjust what RSIZE_MAX
expands to depending upon the context in which it is being used.
But what I don't understand is how, the user can take advantage of
RSIZE_MAX to check the values
of n and s1max prior to calling the
function wcsncpy_s in order to
avoid violating the runtime constraint
error. There is no context in which the implementation can expand
RSIZE_MAX to the value they
need.
Example:
if ((s1max <=
RSIZE_MAX) & (n <= RSIZE_MAX))
error =
wcsncpy_s (s1, s1max, s2 n); // Assume no other runtime
constraints
if
(error != 0) {
// Since RSIZE_MAX is not a constant expression
// Can this ever occur due to s1max or n being greater than RSIZE_MAX?
}
}
Is a conforming implementation allowed to return a non-zero value
for wcsncpy_s() in the example
above?
N1147 the Rationale for TR24731 explains implementations might wish to
adjust the value of RSIZE_MAX
dynamically, and gives several scenarios
for doing so. None of which seem germane to the questions raised here.
So what is the purpose of providing the macro RSIZE_MAX?
If the purpose is to limit all buffer sizes to RSIZE_MAX, it's use in constraints
for wide character functions appear to be malformed.
The definitions of wcsncpy_s()
and strncat_s() have
constraints that treat their arguments that represent character counts
as if those counts represent the size of an object that can be tested
against RSIZE_MAX in the same
way. But those character counts represent characters of very
different sizes. And thus very different object sizes.
Maybe the constraint error for wcsncpy_s()
arguments smax1 and n should be rewritten as something
like:
Neither (s1max *
sizeof(wchar_t)) nor (n *
sizeof(wchar_t)) shall be greater than RSIZE_MAX.
Other functions where max argument represent the number of
wchar_t or multi-byte characters and may need similar changes
include:
mbstowcs_s
wcstombs_s
snwprintf_s
swprintf_s
swscanf_s
vsnwprintf_s
vswprintf_s
wcscpy_s
wcsncpy_s
wmemcpy_s
wmemmove_s
wcscat_s
wcstok_s
wcrtomb_s
mbsrtowcs_s
wcsrtombs_s
Suggested Technical Corrigendum
Previous Defect Report < - > Next Defect Report