On 6/18/19 12:33 PM, Jakub Jelinek wrote:
> On Tue, Jun 18, 2019 at 12:27:31PM +0200, Martin Liška wrote:
>>> Oops. The problematic case is then if the STRING_CST c_getstr finds
>>> is not NUL terminated (dunno if we ever construct that) or if
>>> string_size is smaller than string_length and there are no NULs in that
>>> size.
>>
>> The function always returns a null-terminated string:
>>
>> 14587 /* Return a pointer P to a NUL-terminated string representing the
>> sequence
>> 14588 of constant characters referred to by SRC (or a subsequence of
>> such
>> 14589 characters within it if SRC is a reference to a string plus some
>> 14590 constant offset). If STRLEN is non-null, store the number of
>> bytes
>> 14591 in the string constant including the terminating NUL char.
>> *STRLEN is
>> 14592 typically strlen(P) + 1 in the absence of embedded NUL
>> characters. */
>> 14593
>> 14594 const char *
>> 14595 c_getstr (tree src, unsigned HOST_WIDE_INT *strlen /* = NULL */)
>> 14596 {
>> 14597 tree offset_node;
>> 14598 tree mem_size;
>>
>> That said, the unconditional strnlen should be fine.
>
> But *strlen it sets might be smaller.
No, for "A\0" you'll get *strlen == 3, but strlen (returned value) == 1.
>
> I'd try say const char foo[5] = "foobar";
> or similar, or say stick gcc_assert in c_getstr where it is setting
> *strlen and gcc_assert (strnlen (to be returned value, *strlen) < *strlen);
> do a bootstrap/regtest with that and see if it ever triggers (or instead
> of assert failure log into a log file with "a" mode).
>
> If not, there is no point to pass non-NULL second argument to c_getstr,
> you'd always just use strlen on the returned string.
There might be consumers (like folding of memcmp) of c_getstr which want to
know how long is a string constant
even thought there's a null-terminating character in the middle of the constant.
Martin
>
> Jakub
>