metaeducation / rebol-issues

6 stars 1 forks source link

Object words that override hidden object words aren't accessible, directly #1140

Open rebolbot opened 15 years ago

rebolbot commented 15 years ago

Submitted by: BrianH

When you PROTECT/hide a word in an object, appending another word of that name is supposed to create a new binding entry of that name. Then, in theory, subsequent bindings to the object are supposed to access the new field, as if the old field didn't exist. Except they don't: Those overrides are currently inaccessible. Even to APPEND, which can't tell that the field has been overridden and tries to override it again.

I'm not sure that allowing appends of previously hidden words to override the old word for new bindings is a good idea (it would probably break the module security model). However, the current behavior is really bad, or at least awkward and ugly: See the code for details.

This seems like something that needs tweaking.

(First noticed by Sunanda)
; First, the expected behavior
>> o1: make object! [g: 'blah protect/hide 'g]
== make object! [
]
>> o1/g
** Script error: cannot access g in path o1/g
>> o2: make object! [g: 'blah]
== make object! [
    g: 1
]
>> repeat x 10 [extend o1 'g x extend o2 'g x]
== 10

; Now, the tests
>> o1
== make object! [
    g: 1
    g: 2
    g: 3
    g: 4
    g: 5
    g: 6
    g: 7
    g: 8
    g: 9
    g: 10
]  ; what?
>> length? o1
== 11
>> o2
== make object! [
    g: 10
]  ; This is what I expected o1 to look like
>> length? o2
== 1
>> words-of o1
== [g g g g g g g g g g]
>> values-of o1
== [1 2 3 4 5 6 7 8 9 10]
>> o1/g
** Script error: cannot access g in path o1/g
>> in o1 'g
== none
>> select o1 'g
== none
>> do in o1 [g]
== 10  ; what?
>> do in o1 [self/g]
== blah  ; see bug #1139
>> append o1 'h do in o1 [h: self]
== make object! [
    g: 1
    g: 2
    g: 3
    g: 4
    g: 5
    g: 6
    g: 7
    g: 8
    g: 9
    g: 10
    h: make object! [...]
]
>> do in o1 [h/g]
** Script error: cannot access g in path h/g

CC - Data [ Version: alpha 76 Type: Issue Platform: All Category: Security Reproduce: Always Fixed-in:alpha 79 ]

rebolbot commented 15 years ago

Submitted by: Carl

This needs some discussion, because APPEND of an existing word is actually a SET not an APPEND.

There are a few possible ways to handle this situation. I've marked this bug as 'problem to discuss it in more detail.

rebolbot commented 15 years ago

Submitted by: Sunanda

Here is an example of a system crash (assertion failure 1207) generated by using this bug as an exploit to poison/overflow system/contexts/user

repeat n 5000 [
 print n
 collect-words words-of system/contexts/user
 foreach w words-of system/contexts/user [protect/hide w]
 ]

I see the failure occurring around iteration 2430....That is not enough words to overflow the word limit (somewhere else said to by around the 450,000 mark).

rebolbot commented 15 years ago

Submitted by: Carl

As mentioned above, APPEND (EXTEND) using an existing word is a SET, not an extension of the object. SET requires a BIND, but we are not allowed to bind to hidden fields, and attempting to do so will throw an error.

rebolbot commented 15 years ago

Submitted by: BrianH

That sounds good. We should do that. The current behavior of APPEND extending the object (as shown in the code) is not good.