On 07.06.2012 12:16, Daniel Widenfalk wrote:
> On 2012-06-07 11:47, Bert Huijben wrote:
>>
>>> -----Original Message-----
>>> From: Bert Huijben [mailto:b...@qqmail.nl]
>>> Sent: donderdag 7 juni 2012 11:34
>>> To: 'Daniel Widenfalk'; dev@subversion.apache.org;
>>> us...@subversion.apache.org
>>> Subject: RE: Potential issue in
>> libsvn_diff:diff_file.c:find_identical_prefix
>>>
>>>
>>>> -----Original Message-----
>>>> From: Daniel Widenfalk [mailto:daniel.widenf...@iar.se]
>>>> Sent: donderdag 7 juni 2012 11:06
>>>> To: dev@subversion.apache.org; us...@subversion.apache.org
>>>> Subject: Potential issue in
>> libsvn_diff:diff_file.c:find_identical_prefix
>>>> Hi,
>>>>
>>>> First off: I'm sorry if I post this in the wrong way.
>>>>
>>>> I've found a potential issue in the function "find_identical_prefix"
>>>> in libsvn_diff/diff_file.c
>>>>
>>>> The faulty code looks like this:
>>>>
>>>> diff_file.c:432 (as per 1.7.1, code identical to 1.7.5)
>>>> -------------------------------
>>>>       is_match = TRUE;
>>>>       for (delta = 0; delta < max_delta && is_match; delta +=
>>>> sizeof(apr_uintptr_t))
>>>>         {
>>>>           apr_uintptr_t chunk = *(const apr_size_t *)(file[0].curp +
>>> delta);
>>>>           if (contains_eol(chunk))
>>>>             break;
>>>>
>>>>           for (i = 1; i < file_len; i++)
>>>>             if (chunk != *(const apr_size_t *)(file[i].curp + delta))
>>>>               {
>>>>                 is_match = FALSE;
>>>>                 delta -= sizeof(apr_size_t);
>>>>                 break;
>>>>               }
>>>>         }
>>>> -------------------------------
>>>>
>>>> The problem is that the 64-bit build I'm using (ColabNet) have
>>>> different sizes for apr_uintptr_t and apr_size_t.
>>>>
>>>> From looking at the disassembly I can deduce that
>>>> sizeof(apr_uintptr_t) = 4 and sizeof(apr_size_t) = 8. This leads
>>>> to these two issues:
>>>>
>>>> 1) Data is truncated in the initial read-up to "chunk" and the compare
>>>>    in the inner loop will fail because the second read-up will compare
>>>>    a 64-bit value against a 32-bit value.
>>>>
>>>> 2) When the test fails it will back up delta by 8, not 4, resulting in
>>>>    a buffer advance of -4 later in the code. Once the search code has
>>>>    advanced another 4 character if will be back at the same spot.
>>>>
>>>>    Rinse and repeat.
>>>>
>>>> Are these a known issues?
>>>>
>>>> In my case this results in an infinite loop on the following input
>>>> string:
>>>>
>>>>   23 0a 23 20 54 68 69 73 20 70 72 6f 6a 65 63
>>>>
>>>> I found this out when my svn-client spiraled into an infinite loop
>>>> and would not respond to ctrl-c during a "svn up" command.
>>> Which apr version did you use?
>>>
>>> I think this issue was fixed in Subversion 1.7.2:
>>>
>>> (From http://svn.apache.org/repos/asf/subversion/tags/1.7.2/CHANGES)
>>> * properly define WIN64 on Windows x64 builds (r1188609)
>>>
>>> Not by a code change here in this piece of the code, but by making sure
>> that
>>> the pointer size is defined correctly in apr.
>>> So that would fix this issue and maybe several others.
>> And since then then also APR was patched to properly check for _WIN64
>> instead of WIN64 for defining these variable types correctly.
> Updating to 1.7.5 makes the issue go away. The type mismatch is still
> in the 1.7.5 source but if the system do guarantee that
>
>    sizeof(apr_uintptr_t) == sizeof(apr_size_t)
>
> then it should be ok.

Unless the platform ABI is totally broken, then it should always be the
case that sizeof(uintptr_t) >= sizeof(size_t), and the same holds for
the APR aliases; assuming of course that they're defined correctly. :)

Since both types are unsigned by definition, standard C type coercion
rules guarantee that the uintptr_t result holds the same value as the
original size_t, so there isn't really any type mismatch here.

But I can't help wondering if that bit of code could be written more
elegantly without all the casts.

-- Brane

Reply via email to