**Submitter:** Douglas Walls

**Submission Date:** 2013-03-12

**Source:** WG 14

**Reference Document:** N1683
N1771
**
Version:** 1.1

**Summary**

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."

**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".