diff --git a/src/core/n-control.c b/src/core/n-control.c index 1a74bad697..995b122926 100644 --- a/src/core/n-control.c +++ b/src/core/n-control.c @@ -135,27 +135,27 @@ enum { ***********************************************************************/ { REBSER *series = VAL_OBJ_FRAME(value); - - if (!GET_FLAG(flags, PROT_WORDS)) { - if (IS_MARK_SERIES(series)) return; // avoid loop - if (GET_FLAG(flags, PROT_SET)) { + if (IS_MARK_SERIES(series)) return; // avoid loop + for (value = FRM_WORDS(series)+1; NOT_END(value); value++) { + Protect_Word(value, flags); + } + if (GET_FLAG(flags, PROT_SET)) { + // protecting... + if (!GET_FLAG(flags, PROT_WORDS)) { PROTECT_SERIES(series); - if (GET_FLAG(flags, PROT_PERMANENTLY)) LOCK_SERIES(series); + if (GET_FLAG(flags, PROT_PERMANENTLY)) + LOCK_SERIES(series); } - else + } else { + // unprotecting... + if(!GET_FLAG(flags, PROT_WORDS)) { //unprotect series only when not locked (using protect/permanently) if (!IS_LOCK_SERIES(series)) UNPROTECT_SERIES(series); + } } - - for (value = FRM_WORDS(series)+1; NOT_END(value); value++) { - Protect_Word(value, flags); - } - if (!GET_FLAG(flags, PROT_DEEP)) return; - MARK_SERIES(series); // recursion protection - for (value = FRM_VALUES(series)+1; NOT_END(value); value++) { Protect_Value(value, flags); } diff --git a/src/tests/units/object-test.r3 b/src/tests/units/object-test.r3 index 80c0cba3ad..9a755ca795 100644 --- a/src/tests/units/object-test.r3 +++ b/src/tests/units/object-test.r3 @@ -103,4 +103,41 @@ Rebol [ ===end-group=== + +===start-group=== "UNPROTECT object!" + ;@@ https://github.com/Oldes/Rebol-issues/issues/1015 + --test-- "unprotect object" + ; To allow adding words to o, and allow modification of words already in o, but not affect their values: + o: unprotect protect/deep o: object [a: 10 b: [20]] + --assert not error? try [extend o 'c 3] + --assert not error? try [append o 'd] + --assert not error? try [o/a: 0] + --assert error? try [append o/b 0] + + --test-- "unprotect/words object!" + ; To allow modification of words already in o, but not affect their values or the object itself: + o: unprotect/words protect/deep o: object [a: 10 b: [20]] + --assert error? try [extend o 'c 3] + --assert error? try [append o 'd] + --assert not error? try [o/a: 0] + --assert error? try [append o/b 0] + + --test-- "unprotect/deep object!" + ; To allow adding words to o, and allow modification of words already in o or their values: + o: unprotect/deep protect/deep o: object [a: 10 b: [20]] + --assert not error? try [extend o 'c 3] + --assert not error? try [append o 'd] + --assert not error? try [o/a: 0] + --assert not error? try [append o/b 0] + + --test-- "unprotect/words/deep object!" + ; To allow modification of words already in o and their contents, but not affect the object itself: + o: unprotect/words/deep protect/deep o: object [a: 10 b: [20]] + --assert error? try [extend o 'c 3] + --assert error? try [append o 'd] + --assert not error? try [o/a: 0] + --assert not error? try [append o/b 0] + +===end-group=== + ~~~end-file~~~