On Wed, Mar 4, 2026 at 2:59 AM Branko Čibej <[email protected]> wrote:

> On 3. 3. 26 21:13, Timofei Zhakov wrote:
>
> On Tue, Mar 3, 2026 at 4:51 PM Branko Čibej <[email protected]> wrote:
>
>> On 3. 3. 26 14:55, Evgeny Kotkov via dev wrote:
>>
>> Timofei Zhakov <[email protected]> <[email protected]> writes:
>>
>>
>> I prepared a patch that fixes them by adding const where needed. Can anyone
>> correct me if I'm misunderstanding something?
>>
>> I think that the patch indeed improves the situation by propagating the non-
>> const types upwards, so that everything happens without implicit const
>> discards.  So +1 in general.
>>
>>
>>
>> I'll note that changes like this one:
>>
>> --- subversion/libsvn_subr/version.c (revision 1932024)
>> +++ subversion/libsvn_subr/version.c (working copy)
>> @@ -253,7 +253,7 @@ svn_version__parse_version_string(svn_version_t **
>>       require that it be present. */
>>    if (pieces->nelts == 3)
>>      {
>> -      const char *piece = APR_ARRAY_IDX(pieces, 2, const char *);
>> +      char *piece = APR_ARRAY_IDX(pieces, 2, char *);
>>        char *hyphen = strchr(piece, '-');
>>        if (hyphen)
>>          {
>>
>>
>> have much wider consequences than this one-line change. The 'pieces' come
>> from 'svn_cstring_split()' which is documented as
>>
>> /** Divide @a input into substrings, interpreting any char from @a sep
>>  * as a token separator.
>>  *
>>  * Return an array of copies of those substrings (plain const char*),
>>  * allocating both the array and the copies in @a pool.
>>
>>
>> and this is a public API. So, strictly speaking, the proposed change is
>> an API violation, as opposed to what we were doing before with is "just" a
>> standard C hack.
>>
>> If we want to be really sure we're doing everything right then in all the
>> cases where we get a 'const char*' from anywhere and then change it, we
>> should create a local copy first. I mean, who knows if it isn't pointing to
>> a static string in write-protected memory?
>>
>> Or we could avoid code churn by assuming that whoever is reading the code
>> understands C90 semantics.
>>
>>
> There are a few more places where elements of the svn_cstring_split
> function are treated as 'char *' instead of 'const char *'. Have a look at
> these:
>
> subversion/libsvn_subr/io.c:3816
> [[[
>           /* Tokenize (into our return pool). */
>           tokens = svn_cstring_split(buf->data, " \t", TRUE, pool);
>           if (tokens->nelts < 2)
>             continue;
>
>           /* The first token in a multi-token line is the media type.
>              Subsequent tokens are filename extensions associated with
>              that media type. */
>           type = APR_ARRAY_IDX(tokens, 0, const char *);
>           for (i = 1; i < tokens->nelts; i++)
>             {
>               /* We can safely address 'ext' as a non-const string because
>                * we know svn_cstring_split() allocated it in 'pool' for
> us. */
>               char *ext = APR_ARRAY_IDX(tokens, i, char *);
>               fileext_tolower(ext);
>               svn_hash_sets(types, ext, type);
>             }
> ]]]
>
> subversion/mod_dav_svn/repos.c:1917
> [[[
>       char *keyval = APR_ARRAY_IDX(array, i, char *);
>       char *equals = strchr(keyval, '=');
>       if (equals != NULL)
>         {
>           *equals = '\0';
>           apr_table_set(table, keyval, equals + 1);
>         }
> ]]]
>
> subversion/svnsync/sync.c:116
> [[[
>       char *line = APR_ARRAY_IDX(lines, i, char *);
> ...
> ]]]
>
> I would like to suggest explicitly allowing this usage by adjusting the
> docstring of svn_cstring_split. It should always be safe to cast 'char *'
> to 'const char *' so this doesn't cause any
> backward compatibility violation nor changing existing code.
>
> I think that if all elements are allocated for us in a pool and the caller
> "owns" them, they should be able to do whatever they want with those
> strings.
>
> [[[
> Index: subversion/include/svn_string.h
> ===================================================================
> --- subversion/include/svn_string.h (revision 1932137)
> +++ subversion/include/svn_string.h (working copy)
> @@ -463,8 +463,8 @@ svn_string_compare_stringbuf(const svn_string_t *s
>  /** Divide @a input into substrings, interpreting any char from @a sep
>   * as a token separator.
>   *
> - * Return an array of copies of those substrings (plain const char*),
> - * allocating both the array and the copies in @a pool.
> + * Return an array of copies of those substrings (plain char*), allocating
> + * both the array and the copies in @a pool.
>   *
>   * None of the elements added to the array contain any of the
>   * characters in @a sep_chars, and none of the new elements are empty
> Index: subversion/libsvn_subr/string.c
> ===================================================================
> --- subversion/libsvn_subr/string.c (revision 1932137)
> +++ subversion/libsvn_subr/string.c (working copy)
> @@ -902,7 +902,7 @@ svn_cstring_split_append(apr_array_header_t *array
>          }
>
>        if (p[0] != '\0')
> -        APR_ARRAY_PUSH(array, const char *) = p;
> +        APR_ARRAY_PUSH(array, char *) = p;
>
>        p = svn_cstring_tokenize(sep_chars, &pats);
>      }
> ]]]
>
>
>
> +1, that's a good change, since it's how we've been using the returned
> data internally.
>

Committed in revision r1932154.

-- 
Timofei Zhakov

Reply via email to