Re: Bug in class READABLE_STRING_8

Eric Bezault <[email protected]> Fri, 25 Nov 2016 17:18:03 +0100
Newsgroups gmane.comp.lang.eiffel.gobo.devel
Message-ID <[email protected]>
Hi Wolfgang,

Do you have an example where it actually crashes?
I tried that:

	s :=3D ""
	s.copy ("")

And it did not crash.

I noticed something wrong in your reasoning below. You wrote:

 >> If the string to copy is empty, i.e. `old_area=3DVoid' then `area' is
 >> void, too, after `standard_copy'

This is not true. `old_area' is not affected by `standard_copy'.
It's a local variable, not an attribute. And as far as I can see,
the `area' of a STRING_8 is never void. Even for an empty string,
`make' creates an `area'.

The reason why there is a test for Void with `old_area' is that
when called from `twin', the target of `copy' may be a non-initialized
object (with its reference attributes Void).

-- =

Eric Bezault
mailto:[email protected]
http://www.gobosoft.com


On 11/25/2016 10:37, Wolfgang Jansen wrote:
> On 24/11/16 23:51, Wolfgang Jansen wrote:
>>
>> Hi Eric,
>>
>> I found an fatal error in routine READABLE_STRING_8.copy if the
>> argument is a non-void but empty string. The origin text is as follows:
>>
>>     copy (other: like Current)
>>             -- Reinitialize by copying the characters of `other'.
>>             -- (This is also used by `twin'.)
>>         local
>>             old_area: like area
>>         do
>>             if other /=3D Current then
>>                 old_area :=3D area
>>                 standard_copy (other)
>>                     -- Note: <=3D is needed as all Eiffel string should
>> have an
>>                     -- extra character to insert null character at the
>> end.
>>                 if old_area =3D Void or else old_area =3D other.area or
>> else old_area.count <=3D count then
>>                         -- Prevent copying of large `area' if only a
>> few characters are actually used.
>>                     area :=3D area.resized_area (count + 1)
>>                 else
>>                     old_area.copy_data (area, 0, 0, count)
>>                     area :=3D old_area
>>                 end
>>                 internal_hash_code :=3D 0
>>             end
>>         ensure then
>>             new_result_count: count =3D other..count
>>             -- same_characters: For every `i' in 1..`count', `item'
>> (`i') =3D `other'.`item' (`i')
>>         end
>>
>>
>> If the string to copy is empty, i.e. `old_area=3DVoid' then `area' is
>> void, too,
>> after `standard_copy'. Then branch `if old_area=3DVoid or else ...'
>> leads to instruction `area :=3D area.resized_area (count + 1)' that must
>> crash. I propose the following modification (it works fine for me):
>>
>>
>>     copy (other: like Current)
>>             -- Reinitialize by copying the characters of `other'.
>>             -- (This is also used by `twin'.)
>>         local
>>             old_area: like area
>>         do
>>             if other /=3D Current then
>>                 old_area :=3D area
>>                 standard_copy (other)
>>                     -- Note: <=3D is needed as all Eiffel string should
>> have an
>>                     -- extra character to insert null character at the
>> end.
>>                 if old_area =3D Void then
>>                 elseif old_area =3D other.area or else old_area.count <=
=3D
>> count then
>>                         -- Prevent copying of large `area' if only a
>> few characters are actually used.
>>                     area :=3D area.resized_area (count + 1)
>>                 else
>>                     old_area.copy_data (area, 0, 0, count)
>>                     area :=3D old_area
>>                 end
>>                 internal_hash_code :=3D 0
>>             end
>>         ensure then
>>             new_result_count: count =3D other..count
>>             -- same_characters: For every `i' in 1..`count', `item'
>> (`i') =3D `other'.`item' (`i')
>>         end
>>
>>
>> I do not know whether the bug is already in ISE's distribution of the
>> class.
>>
>> Best regards
>> Wolfgang
>>
>> --
>> Dr. Wolfgang Jansen
>> Lauenburger Stra=DFe 40
>> D-12169 Berlin
>>
>> Tel: (+49) 0172 40 86 916
>> e-mail: [email protected]
>>
>>
>> ------------------------------------------------------------------------=
------
>>
>>
>> _______________________________________________
>> gobo-eiffel-develop mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/gobo-eiffel-develop
>
> Sorry, I introduced another bug into the routine, now it fails if the
> target string was empty.
> We need to guard both possibilities: the target is empty or the source
> is empty. The improved improvement of the critical lines reads as follows:
>
>                 if area =3D Void then
>                     -- Nothing to copy or modify.
>                 elseif old_area =3D Void or else old_area.count <=3D count
> or else old_area =3D area then
>                     -- Prevent copying of large `area' if only a few
> characters are actually used.
>                     area :=3D area.resized_area (count + 1)
>                 else
>                     old_area.copy_data (area, 0, 0, count)
>                     area :=3D old_area
>                 end
>
> The `if' condition guards the call in the `elseif' branch, the left
> `elseif' condition guards the following call and the call in the `else'
> branch. What case ever occurs, the target has at least as many
> characters as needed, all characters of the source are copied, and
> `count' is set correctly.
>
> --
> Dr. Wolfgang Jansen
> Lauenburger Stra=DFe 40
> D-12169 Berlin
>
> Tel: (+49) 0172 40 86 916
> e-mail: [email protected]
>
>
>
> -------------------------------------------------------------------------=
-----
>
>
>
> _______________________________________________
> gobo-eiffel-develop mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/gobo-eiffel-develop
>




---------------------------------------------------------------------------=
---