On 08/21/2018 09:37 AM, Martin Sebor wrote:
> On 08/21/2018 05:50 AM, Joseph Myers wrote:
>> On Tue, 21 Aug 2018, Martin Sebor wrote:
>>
>>> I still believe it would be simpler, more robust, and safe
>>> to pass in a flag to either count bytes (the default, for
>>> all callers except sprintf %ls), or elements of the string
>>> type (for sprintf %ls).
>>
>> But the correct thing to count for sprintf %ls is elements of the type
>> expected by sprintf %ls.  That may not be the type of the string constant
>> (and as this is in variable arguments, there isn't any implicit
>> conversion
>> to const wchar_t * like you would get with a function prototype - I'm not
>> sure if anything ensures this code is only reached, regardless of
>> language, if the argument does actually (after any casts present in the
>> source code) point to the correct wchar_t type).
> 
> Sure, but the only valid argument to %ls is wchar_t*.  Passing
> it something else is undefined.
> 
> The only caller interested in the element count is %ls and
> the only case where the function could return a result that
> might be different from that of C wcslen() with the same
> (invalid) argument is the undefined:
> 
>   snprintf (0, 0, "%ls", "1234");
> 
> In this case, c_strlen() would return 4 which GCC's snprintf
> turns into [0, 24], and calls the libc snprintf which will
> then proceed to read past the end of the narrow string and
> return some bogus value (if it doesn't crash).
> 
> So I don't see a problem here(*).
I think we should be counting wchar_ts in this case.   If someone passes
something other than a wchar_t as the argument for a %ls, then the code
is in error.

At issue is we need a way for the sprintf code to indicate to c_strlen
the size of a wchar_t argument.  Between Joseph's suggestions and my own
poking around I think we can do that.  I just have to fight aix long
enough to be able to do some testing.

> 
> In any event, my main concern isn't whether the function take
> a flag or an element size as an argument.  What I believe it
> needs to do is count bytes when requested even when the array
> is a wide string.
Umm, that's precisely what it does.  If you ask it to count bytes, it'll
count bytes.  You can request to count 16bit wchat_t and a 32bit wchar_t
objects.  So I'm not sure why we're still arguing over this.




> 
> Martin
> 
> PS The only problem I see is that GCC will call the library
> function in this case, which we know is undefined and will
> unavoidably read past the end of the argument and (if it
> doesn't crash due to misalignment) return some indeterminate
> value.  That's worse than any other outcome (such as folding
> the call into a constant or trapping) and can easily be
> prevented.  But that's a separate discussion.
Right.  So let's please defer it.  We don't need to expand this
discussion further, it's tangled enough already.

jeff

Reply via email to