Skip to content

Commit

Permalink
FEAT: PROTECT/words supported for an object! value
Browse files Browse the repository at this point in the history
PROTECT object! now protects the object and its words, but not their values.

PRODUCT/deep object! protects the object, its words, and their values.

PROTECT/words object! only protects the words of the object!, but not the object itself or the values of the words.

PROTECT/words/deep object! also protects any values assigned to the words, but still not protects the object itself.

Implements: Oldes/Rebol-issues#1014
Related to: Oldes/Rebol-issues#1170
  • Loading branch information
Oldes committed Apr 2, 2020
1 parent a89c235 commit 3092806
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 15 deletions.
22 changes: 12 additions & 10 deletions src/core/n-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ enum {
PROT_DEEP,
PROT_HIDE,
PROT_WORD,
PROT_WORDS,
PROT_PERMANENTLY
};

Expand Down Expand Up @@ -135,16 +136,17 @@ enum {
{
REBSER *series = VAL_OBJ_FRAME(value);

if (IS_MARK_SERIES(series)) return; // avoid loop

if (GET_FLAG(flags, PROT_SET)) {
PROTECT_SERIES(series);
if (GET_FLAG(flags, PROT_PERMANENTLY)) LOCK_SERIES(series);
if (!GET_FLAG(flags, PROT_WORDS)) {
if (IS_MARK_SERIES(series)) return; // avoid loop
if (GET_FLAG(flags, PROT_SET)) {
PROTECT_SERIES(series);
if (GET_FLAG(flags, PROT_PERMANENTLY)) LOCK_SERIES(series);
}
else
//unprotect series only when not locked (using protect/permanently)
if (!IS_LOCK_SERIES(series))
UNPROTECT_SERIES(series);
}
else
//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);
Expand Down Expand Up @@ -213,7 +215,7 @@ enum {
Check_Security(SYM_PROTECT, POL_WRITE, val);

if (D_REF(2)) SET_FLAG(flags, PROT_DEEP);
//if (D_REF(3)) SET_FLAG(flags, PROT_WORD);
if (D_REF(3)) SET_FLAG(flags, PROT_WORDS);

if (D_REF(5)) SET_FLAG(flags, PROT_HIDE);
else SET_FLAG(flags, PROT_WORD); // there is no unhide
Expand Down
47 changes: 42 additions & 5 deletions src/tests/units/object-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ Rebol [

===end-group===

===start-group=== "EXTEND object"
--test-- "extend object"
obj: object []
--assert 1 = extend obj 'a 1
--assert 1 = obj/a
===end-group===

===start-group=== "APPEND on OBJECT"
;@@ https://github.com/rebol/rebol-issues/issues/708
--test-- "issue-708"
Expand All @@ -58,11 +65,41 @@ Rebol [
--assert err/id = 'protected
unprotect o

--test-- "issue-1170"
;@@ https://github.com/Oldes/Rebol-issues/issues/1170
obj: protect object [a: object [b: 10]]
--assert error? try [obj/a: 0]
--assert not error? try [obj/a/b: 0]
===end-group===

===start-group=== "PROTECT object!"
;@@ https://github.com/Oldes/Rebol-issues/issues/1014
--test-- "protect object"
; To prevent adding words to o, and prevent modification of words already in o:
o: protect object [a: object [b: 10]]
--assert error? try [extend o 'c 3]
--assert error? try [append o 'd]
--assert error? try [o/a: 0]
--assert not error? try [o/a/b: 0] ;;@@ https://github.com/Oldes/Rebol-issues/issues/1170

--test-- "protect/words object!"
; To allow adding words to o, but prevent modification to words already in o:
o: protect/words object [a: object [b: 10]]
--assert not error? try [extend o 'c 3]
--assert not error? try [append o 'd]
--assert error? try [o/a: 0]
--assert not error? try [o/a/b: 0]

--test-- "protect/deep object!"
; To prevent adding words to o, modification of words already in o, or their contents:
o: protect/deep object [a: object [b: 10]]
--assert error? try [extend o 'c 3]
--assert error? try [append o 'd]
--assert error? try [o/a: 0]
--assert error? try [o/a/b: 0]

--test-- "protect/words/deep object!"
; To allow adding words to o, but prevent modification of words already in o or their contents:
o: protect/words/deep object [a: object [b: 10]]
--assert not error? try [extend o 'c 3]
--assert not error? try [append o 'd]
--assert error? try [o/a: 0]
--assert error? try [o/a/b: 0]

===end-group===

Expand Down

0 comments on commit 3092806

Please sign in to comment.