[PATCH] Add a character size parameter to c_strlen/get_range_strlen
Jeff Law
law@redhat.com
Tue Aug 21 15:57:00 GMT 2018
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
More information about the Gcc-patches
mailing list