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
>
---------------------------------------------------------------------------=
---