"Hugh Sasse Staff Elec Eng" <hgs / dmu.ac.uk> wrote:
> On Thu, 27 Jan 2005, Dave Burt wrote:
>
>> "ts" <decoux / moulon.inra.fr> wrote:
>>>>>>>> "H" == Hugh Sasse Staff Elec Eng <hgs / dmu.ac.uk> writes:
>>>
>>> H>          Thread.new(input){|source|
>>> H>            $SAFE=5
>>> H>            instance_eval source
>>> H>          }.value
>>>
>>> Sorry to say this but this is the most common error that I see when
>>> someone try to eval some code with $SAFE >= 4
>>>
>>> The code will be eval'ed with $SAFE >= 4 but the result (#value) will be
>>> used with $SAFE = 0 and you can have problems.
>>>
>>> The result of #eval must be cleaned with $SAFE >= 4, before it's
>>> returned.
>>
>> Hi,
>>
>> I'm having trouble understanding what you mean by this. Can you say it in
>> Ruby?
>
> My understanding is
>
>               valid_input = Thread.new(input){|source|
>                  $SAFE=5
>                  result = instance_eval source
>                  final_result = validate(result)
>                }.value
>
> would be better than:
>
>               result = Thread.new(input){|source|
>                  $SAFE=5
>                  result = instance_eval source
>                }.value
>                final_result = validate(result)  # OOPS!!!
>
> because the validation takes places while "the safety catch is on"
> in the first of these two cases.

So essentially, the problem is that the result of eval here is tainted 
(untrusted input) and needs to be treated with appropriate care. If it was 
used at $SAFE=0, the result object would have normal Ruby priveleges. So the 
safe thing to do is to only access that result with $SAFE in place, and 
maybe to create a new object with valid data taken from the result to use 
later.

Thanks for the explanation.

Cheers,
Dave