Defect Report #433
Previous Defect Report < - > Next Defect Report
Submitter: Douglas Walls
Submission Date: 2013-03-12
Source: WG 14
Reference Document: N1683
N1771
Version: 1.1
Date: April 2014
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
Apr 2013 meeting
Committee Discussion
- RSIZE_MAX is intended to be the maximum size, in bytes, permitted
by an implementation for an object.
- The constraints for wide character functions appear to be
incorrect.
- For example, K.3.9.2.1.2p8 second sentence should read something
like "Neither s1max*sizeof(wchar_t) nor n*sizeof(wchar_t) shall be
greater than RSIZE_MAX."
Oct 2013 meeting
Committee Discussion
- The list of functions cited was not entirely correct, and upon
further review the Suggested Technical Corrigendum from N1771
were adopted.
- These changes also address, where noted, the defect reported in
DR428.
Apr 2014 meeting
Committee Discussion
A "nor nor" typo in the Suggested Technical Corrigendum for K.3.9.3.2.2p12 was noticed and corrected in the Proposed Technical Corrigendum below.
Proposed Technical Corrigendum
K.3.6.5.1 The mbstowcs_s function
In K.3.6.5.1p2, replace "RSIZE_MAX" with "RSIZE_MAX/sizeof(wchar_t)".
In K.3.6.5.1p3, replace "less than RSIZE_MAX" with
"not greater than RSIZE_MAX/sizeof(wchar_t)".
K.3.6.5.2 The wcstombs_s function
In K.3.6.5.2p2, replace "then neither len nor dstmax shall be greater
than RSIZE_MAX" with
"then neither len shall be greater than RSIZE_MAX/sizeof(wchar_t) nor
dstmax shall be greater than RSIZE_MAX".
In K.3.6.5.2p3, replace "less than RSIZE_MAX" with "not greater than
RSIZE_MAX".
K.3.9.1.3 The snwprintf_s function
In K.3.9.1.3p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.1.3p3, replace "less than RSIZE_MAX" with "not greater
than RSIZE_MAX/sizeof(wchar_t)". See DR 428
K.3.9.1.4 The swprintf_s function
In K.3.9.1.4p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.1.4p3, replace "less than RSIZE_MAX" with "not greater
than RSIZE_MAX/sizeof(wchar_t)". See DR 428
K.3.9.1.8 The vsnwprintf_s function
In K.3.9.1.8p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.1.8p3, replace "less than RSIZE_MAX" with "not greater
than RSIZE_MAX/sizeof(wchar_t)". See DR 428
K.3.9.1.9 The vswprintf_s function
In K.3.9.1.9p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.1.9p3, replace "less than RSIZE_MAX" with "not greater
than RSIZE_MAX/sizeof(wchar_t)". See DR 428
K.3.9.2.1.1 The wcscpy_s function
In K.3.9.2.1.1p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.1.1p3, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.1.2 The wcsncpy_s function
In K.3.9.2.1.2p8, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.1.2p9, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.1.3 The wmemcpy_s function
In K.3.9.2.1.3p15, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.1.3p16, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.1.4 The wmemmove_s function
In K.3.9.2.1.4p20, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.1.4p21, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.2.1 The wcscat_s function
In K.3.9.2.2.1p3, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.2.1p4, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.2.2 The wcsncat_s function
In K.3.9.2.2.2p10, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.2.2.2p11, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.2.3.1 The wcstok_s function
In K.3.9.2.3.1p2, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
K.3.9.3.2.1 The mbsrtowcs_s function
In K.3.9.3.2.1p3, replace "RSIZE_MAX" with
"RSIZE_MAX/sizeof(wchar_t)".
In K.3.9.3.2.1p4, replace "less than RSIZE_MAX" with "not greater
than RSIZE_MAX/sizeof(wchar_t)". See DR 428
K.3.9.3.2.2 The wcsrtombs_s function
In K.3.9.3.2.2p12, replace "then neither len nor dstmax shall be
greater than RSIZE_MAX" with
"then neither len shall be greater than RSIZE_MAX/sizeof(whcar_t)
nor dstmax shall be greater than RSIZE_MAX".
In K.3.9.3.2.2p13, replace "less than RSIZE_MAX" with "not greater than
RSIZE_MAX".
Previous Defect Report < - > Next Defect Report