AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 64 |
r3wp | 928 |
total: | 992 |
results window for this page: [start: 801 end: 900]
world-name: r3wp
Group: Dialects ... Questions about how to create dialects [web-public] | ||
Maxim: 13-Jan-2011 | another thing which helps is to be (rather) fluent or at least aware in how REBOL handles the evaluation of words and how to bind words to different blocks. mastering this will help you go at a new level in your dialecting. keep this for your second pass at learning if you're still new to REBOL itself. | |
Group: !REBOL3 ... [web-public] | ||
BrianH: 25-Mar-2010 | And if we BIND/no-self on a object with an overriden 'self field we can still see it. And if the override 'self is hidden, BIND/self doesn't unhide it, it inly unhides the original 'self. | |
Gabriele: 26-Mar-2010 | Ok, so let me try to recap this huge discussion. In R2 we had context! and object! as two separate types, although context! was hidden from users and only accessible by converting it to object! - conversion which was broken because it did not create 'self that object! requires. So, instead of fixing this by making context! accessible, it was decided to remove context! altogether and add 'self to all contexts, and add a bunch of exception refinements to BIND to work around all the problems that come out of that? | |
BrianH: 26-Mar-2010 | The part you missed for R3 was that there were no exception refinements added to BIND to deal with this at all - they weren't needed. And we are proposing to add *one* refinement to BIND, out of a choice of two. | |
BrianH: 27-Mar-2010 | Admittedly, you can't do the BIND unhiding trick either, but if you roll your own (let's call it 'this), the 'this reference can go in another context and you will get the same advantages. Or you can bind all the code that needs to refer to 'this before you hide 'this, so you won't need to unhide 'this later (normally impossible). | |
BrianH: 28-Apr-2010 | Yeah, but it's a special binding, with just a reference to the context, not to a field. The object doesn't have a 'self field. The 'self keyword is currently just a side-effect of the BIND and IN functions, not something that is really in the object. | |
BrianH: 28-Apr-2010 | (From chat #7216) Some tests pass, others fail. It's a good start. - The tests in the example code of bug#1549 pass (Ladislav's philosophicals) - The practical tests don't. In particular, bug#447, bug#1528 (for closures), bug#1529 and bug#1552 are still problematic. - We need a SELFLESS? function (or whatever it should be called) to resolve the main downside of the #1549 approach, and we need it for the a98 release. Here are the practical tests that need to pass: ; Objects ob: object [] print same? ob do bind [self] ob print same? ob do in ob [self] ; Functions ob: object [f: func [/x] [do bind/copy [self] 'x]] print same? ob ob/f ; Can't use the context after the function returns. ; This is not a side effect of Ladislav's proposal. ; Functions with a 'self parameter (#1528) ob: object [f: func [/self] [do bind/copy [self] 'self]] print not same? ob ob/f ; Closures (#447) ob: do closure [x] [bind? 'x] 1 print 1 = ob/x print not same? ob do bind [self] ob print not same? ob do in ob [self] ; Closures with a 'self parameter (#1528) ob: do attempt [closure [self] [bind? 'self]] 1 print 1 = attempt [ob/self] print not same? ob do bind [self] ob print not same? ob do in ob [self] ; Closures shouldn't bind 'self unless it is a parameter (#447) print same? self do closure [x] [self] 1 print not same? self do attempt [closure [self] [self]] 1 ; Loops (#1529) ob: repeat x 1 [bind? 'x] print 1 = ob/x print not same? ob do bind [self] ob print not same? ob do in ob [self] ; Loops with a 'self variable (#1529) ob: repeat self 1 [bind? 'self] print 1 = attempt [ob/self] print not same? ob do bind [self] ob print not same? ob do in ob [self] ; Loops shouldn't bind 'self unless it's a variable (#1529) print same? self repeat x 1 [self] print not same? self repeat self 1 [self] See also #1552: There needs to be a way to distinguish selfless contexts from selfish contexts at runtime (a SELFLESS? function), and selfless contexts need to MOLD into DOable syntax (perhaps a different datatype, or a flag). | |
Ladislav: 29-Apr-2010 | selfless?: func [context [word! object!]] [ make object! [ myself: 'self return same? myself first bind [self] context ] ] | |
Ladislav: 29-Apr-2010 | if we want to have the function faster, this version should suffice: make object! [ set 'selfless? func [context [word! object!]] [ return same? 'self first bind [self] context ] ] | |
Ladislav: 29-Apr-2010 | optimized: make object! [ set 'selfless? func [context [word! object!]] [ 'self =? first bind [self] context ] ] | |
Ladislav: 29-Apr-2010 | as it looks, this optimization was "too much", since the function modifies itself, so either we need to always create a new object, like above, or use BIND/COPY at least: make object! [ set 'selfless? func [context [word! object!]] [ 'self =? first bind/copy [self] context ] ] | |
BrianH: 29-Apr-2010 | I use /local self. I was talking about your 'self =? first bind/copy [self] context vs. my self =? do bind/copy [self] context Mine has a code-injection risk. | |
BrianH: 29-Apr-2010 | Another way to resolve the risk would be to change the line to this: :self =? do bind/copy [:self] context | |
Ladislav: 3-May-2010 | If you remember, once I used a trick to achive the same effect to enhance the BIND function | |
BrianH: 4-May-2010 | Steeve, REBOL in general and R3 in particular doesn't have direct support for parent objects; we support prototype objects instead, which is a completely different thing. So the body of an object isn't stored at all, let alone shared; instead, BODY-OF an object creates a brand-new block every time from a collection of the key and value pairs. There might be some data sharing of the words collection between a prototype of an object and derived objects (which might be what you meant) to save memory, iirc, but the values are BIND/copy'd. | |
Maxim: 4-May-2010 | in any case, there can be other alternatives too. the init could manage the hiding. so that you can bind expanded objects, if you have a hold of the original class . | |
BrianH: 4-May-2010 | The only overhead added to objects would be for fields to assign the method! values to. The method! values themselves would just have their references transferred on MAKE object! - they wouldn't be BIND/copy'd. And if you implement them right, they wouldn't even need to be defined as part of the object body, or bound to the object explicitly before being appended. | |
BrianH: 5-May-2010 | FOREACH has BIND/copy overhead of its code block, not slower speed. | |
BrianH: 5-May-2010 | REPEAT has the same BIND/copy overhead, but REPEAT w number! has less work to do, so it's faster. I wouldn't be surprised if REPEAT w series! is comparable to FORALL. | |
BrianH: 5-May-2010 | I can understand your REPEAT code being slower than FOREACH: You put an extra FIRST in the code block, so the code isn't comparable in speed. Compared to FORALL, there's the added BIND/copy overhead. | |
BrianH: 5-May-2010 | >> dt [loop 100000 [repeat x [1 2 3 4] []]] == 0:00:00.062792 >> dt [loop 100000 [repeat x 4 []]] == 0:00:00.060991 >> dt [loop 100000 [foreach x [1 2 3 4] []]] == 0:00:00.064321 >> dt [loop 100000 [x: [1 2 3 4] forall x []]] == 0:00:00.026746 Gotta love that BIND/copy overhead :( | |
BrianH: 5-May-2010 | You aren't testing code equivalence. FORALL is used in different circumstances than FOREACH. If the code is huge it adds to the BIND/copy overhead. If you have to use FIRST all the time it slows down FORALL because you're not using the right function. | |
BrianH: 7-May-2010 | >> a: [a] same? a in self a == true IN something block! is like BIND, not BIND/copy - IN modifies. Don't remove stuff from the original. | |
BrianH: 7-May-2010 | I think words are immutable in R3, like integers, tuples and typesets. When IN or BIND binds a block I think they replace the words they bind with new words that refer to the same symbols, but a new context. So IN and BIND never modify words - they replace them. | |
BrianH: 12-May-2010 | No change in syntax or parsing would be required. However, the DO's evaluation rules for the set-word expression *would* need to be changed. Note that these evaluation rules are *not* performed by a parser, so changing parsing would not be required, Paul. However, this change to the evaluation rules of the DO dialect would be so fundamental that we would essentially be changing the semantics of the language to that of another language. And that other language would resemble Icon more than it would REBOL, semantically. And changing the behavior of the SET, LESSER?, ... functions would not be enough because DO doesn't actually call those functions directly - it calls internal code, which may or may not also be called by those functions. But this is not a problem, because at least you wouldn't have to change the parsing. This means that all you would have to do is write your own evaluator and pass the code to that instead of DO. And create new versions of all the functions that call DO internally, behaving the same but calling your DO replacement instead. And create a context to reference those functions, and bind to that context instead of the standard system context. Basically, all you have to do is create a new dialect on the scale of the DO dialect, using the same REBOL parser, but different semantic rules. | |
Maxim: 2-Aug-2010 | yes, but its a refinement, and even then, it still acts "locally" within that object (I'm assuming its using function locals on words in didn't bind to). | |
Maxim: 13-Sep-2010 | shoudn't resolve have a refinement called /bind making it easier to rebind data to target context in a single pass? | |
Rebolek: 17-Sep-2010 | There's probably some easier way than this, I hope: >> x: 1 == 1 >> set bind to word! "a" 'x 2 == 2 >> a == 2 | |
ChristianE: 17-Sep-2010 | May I withdraw my suggestion? Don't use is in tight loops: >> dt [loop 100000 [set load "a" 2]] == 0:00:02.017813 >> dt [loop 100000 [set bind to word! "a" 's 2]] == 0:00:00.079424 | |
Henrik: 17-Sep-2010 | well, then there has to be a better way to do that. some kind of default-bind. | |
Andreas: 17-Sep-2010 | set bind/new to word! "a" self 2 or set bind/new to word! "a" system/contexts/user 2 | |
BrianH: 21-Sep-2010 | Maxim: "shoudn't resolve have a refinement called /bind making it easier to rebind data to target context in a single pass?" There is a REBIND internal function that hasn't been exported yet. Ask Carl or request in CureCode for the function to be exported. | |
BrianH: 21-Sep-2010 | Now for the other binding stuff: * SET is a low-level function that would be slowed down immensely by adding any refinements. * SET does handle the unbound scenario: It triggers an error. You can then handle the error. * R2 and R3 get their speed from the direct binding model. The core speedup of that model is that SET doesn't bind. * LOAD in R3 is a high-level mezzanine function. It is meant to be as fast as possible given its purpose, but being fast is not its main goal; user-level flexibility is. Most of the overhead of LOAD is in handling all of its various options, as refinements, file extensions and script header settings. If you know what you are doing, you can always optimize your code by doing it directly instead of having LOAD try to figure out that is what you want to do. LOAD is not meant for use in tight loops. * Henrik, ChristianE, the R3 standard answer to the question of how to make BIND TO-WORD "a" more efficient or friendly in R3 is this: You are encouraged to not program that way in R3. Converting strings to words is something you should do once, not all the time in tight loops. Your code will be much more efficient if you work in REBOL data rather than storing your code in strings and converting at runtime. Strings are for data, or script source, not for containing scripts at runtime. This is a good rule for all REBOL versions, but especially for R3 with its Unicode strings vs. shared UTF-8 words. * I have recently refactored LOAD so that it is broken into smaller, more efficient functions. You might find that those functions would work better for you in lower-level code. But this was done to let us make LOAD *more* powerful, not less, so the same advice I gave above about not using LOAD in tight loops still applies. I don't yet know if the new LOAD is faster or slower, but it is safer and easier to understand and modify, and you can make your own LOAD replacement that calls the same low-level functions if you like. Plus, you get compressed scripts :) | |
Ladislav: 22-Sep-2010 | The initialization has to occur in the function body, unfortunately, otherwise the R3 protection does not allow BIND to be used, which, on the other hand, means, that the IF call is done every time the function is called, which means additional overhead | |
Ladislav: 15-Nov-2010 | But, being at it, there is one annoyance I perceive: 1) the variables bound to a function context don't cease to exist even when the function is not running 2) code like: f: func [/a]['a] block: [a] bind block f do not work, while I can do such a bind on my own without needing any permission: change block f So, this is clearly just an annoyance, and not a useful feature. | |
Ladislav: 15-Nov-2010 | and, being at it, yet another annoyance of exactly the same kind is: o: make object! [me: 'o] error? try [bind 'self o] ; == true bind [self] o; == [self] , i.e. again, one can bind as wished, so the "feature" is just meant to be annoying, not useful | |
Ladislav: 16-Nov-2010 | I am able to bind a block to a function even when the function is not running, so pretending that it is impossible is just that: pretending. | |
Ladislav: 16-Nov-2010 | What I wanted to demonstrate was, that: block: [a] g: closure [a] ['a] f: func [a] ['a] ; this works bind block g ; this does not work bind block f ; but it can be replaced by this, doing what was requested: change block f , i.e. there is no reason why the operation should not work, except for the fact that somebody does not want me to do it (ineffectively, since I demonstrated, that it can be done anyway | |
Ladislav: 16-Nov-2010 | you can't rebind because definitional binding depends on the order of binding operations - there are at least two things I do not understand in this sentence: * "you can't rebind" - I am not trying to "rebind" above * "because definitional binding depends on the order of binding operations" - sure it does, does that mean, that the BIND function should not work at all? | |
BrianH: 18-Nov-2010 | R3 objects can't have fields *removed* because that breaks binding, but maps can *because* you can't bind to them. Most of the differences between maps and objects are because of that difference. | |
Sunanda: 25-Nov-2010 | Are there are practical differences between these two R3 ways of extending an object? obj: make object! [] extend obj 'a 1 bind/new 'b obj obj/b: 2 probe obj == make object! [ a: 1 b: 2 ] | |
Steeve: 25-Nov-2010 | Extend is a mezz, so that much be slower. And I always try to avoid GC overheads due to excessive usage of 'reduce Thats why I think bind/new is more capable especially, this form: >set bin/new 'b obj 2 instead of: >>bind/new 'b obj obj/b: 2 | |
Andreas: 25-Nov-2010 | Besides the readability/performance trade-off, things also start to differ when non-true? values are involved: obj: make object! [] extend obj 'a none extend obj 'b false set bind/new 'c obj none set bind/new 'd obj false print mold obj ==> make object! [ c: none d: false ] | |
Sunanda: 25-Nov-2010 | EXTEND is a wrapper for APPEND....So are there any practical advantages in using BIND/NEW rather than APPEND ? append obj [c: 3] == make object! [ a: 1 b: 2 c: 3 ] I know right now there are some differences when messing with PROTECT/HIDE, but there are many CureCodes to go before we'll know if those differences are for real. | |
BrianH: 25-Nov-2010 | I like the SET BIND/new trick. There has already been code in the mezzanines where such a trick would come in handy, but it had never occurred to me. Thanks Steeve! | |
BrianH: 25-Nov-2010 | The practical advantages of the SET BIND/new trick as opposed to APPEND is that you don't have to REDUCE a block to be appended. The point to the IF :val guard in EXTEND was to screen out false and none in GUI code, but that is likely no longer necessary. There was a blog where it was suggested that EXTEND be rewritten to work differently, but I think that various natives were enhanced instead. EXTEND is now a little anachronistic. | |
Sunanda: 26-Nov-2010 | Thanks for the EXTEND vs APPEND vs BIND discussion, guys. It can be useful to have different mechanisms that have their own default behaviours. One use of BIND/NEW is that it allows words to be unset when an object is created: obj: context [bind/new 'word self] ;; this works, and WORD is UNSET! obj: context [word: #[unset!]] ;; this does not work * Script error: word: needs a value * Where: make context * Near: make object! blk | |
Maxim: 11-Jan-2011 | I think to, I think the rule is most usefull in cases like bind where we need multiple variants of a word to mean different things. in such a case, the ? should always tend toward the most obvious/usefull conditional safe function. :-) | |
Oldes: 23-Jan-2011 | So far I have this: my-attempt: funct[code /local val][ either error? set/any 'val try code [ val: to-object val do bind [ print rejoin [ "!! " val/type " error: " reduce system/catalog/errors/(val/type)/(val/id) #"^/" "!! Where: " val/where #"^/" ;"!! Near: " val/near #"^/" ] ] val false ][ :val ] ] my-attempt [debase #ff] my-attempt [1 / 0] but not perfect... the Near and Where info is modified :-/ | |
Oldes: 23-Jan-2011 | I was using this function in R2: parse-error: func[ error [object!] /local type id arg1 arg2 arg3 where err-desc ][ type: error/type id: error/id where: mold get/any in error 'where either any [ unset? get/any in error 'arg1 unset? get/any in error 'arg2 unset? get/any in error 'arg3 ][ arg1: arg2: arg3: "(missing value)" ][ arg1: error/arg1 arg2: error/arg2 arg3: error/arg3 ] err-desc: system/error/:type rejoin [ "** " err-desc/type ": " reduce either block? err-desc/:id [ bind system/error/:type/:id 'arg1 ][ err-desc/:id ] newline "** Where: " where newline "** Near: " mold error/near ] ] >> f: does [1 / 0] >> if error? err: try [f][print parse-error disarm err] ** Math Error: Attempt to divide by zero ** Where: f ** Near: [1 / 0] In R3 the WHERE and NEAR report is different | |
BrianH: 4-Mar-2011 | set bind/new/copy words obj values | |
BrianH: 4-May-2011 | OK, the problem with that model *in this case* (PROTECT/hide) is that we are talking about object fields here, bindings of word values. REBOL objects bind their code blocks before executing them. If there is going to be any blocking of bindings, at least the object's own code needs to be bound first. This means that if you are going to make word bindings hidden, you need to do so after the object itself has been made, or at least after its code block has been bound. You can do this binding with PROTECT/hide, or with some setting in an object header, it doesn't matter. Since words are values and their bindings are static, being able to create a new word with the same binding means that you need access to a word with that binding, with *exactly* the same visibility issues as token access. The difference in this case between POLA and PROTECT/hide is whether object fields are hidden by default or not, not a matter of when they are hidden. | |
BrianH: 5-May-2011 | I'm more concerned with people trying to sneak functions into data, which could then use parameters to get access to the original code of another function. This can be used for code injection, or for getting access to bound words that have since been hidden, or to internal contexts. Given that words are often valid data, having a special case where they can execute functions by sneaking in a bound word is a real concern. However, if that function can't take parameters, there is no hacking potential and function code can be secure. The workaround if you don't want any functions executed (beyond the hacking) could be to unbind words retrieved from data, bind them to a known context, or just avoid using DO word or path altogether. | |
Geomol: 17-May-2011 | Is it possible to bind a function's body to a new context in R3? In R2, it can be done with bind second :f new-context | |
Ladislav: 17-May-2011 | As follows: f: make function! reduce [spec body] bind body new-context | |
Geomol: 17-May-2011 | I get some errors (under OS X): >> bind 'body o ** Script error: body is not in the specified context >> bind [body] o == [body] >> f 1 ** Script error: a has no value My f, body and o are defined this way: >> f: func [v] body: [v + a] >> o: context [a: 1] | |
Geomol: 17-May-2011 | Hm, I did it wrong, I think, but still doesn't work with: bind body o | |
Ladislav: 17-May-2011 | >> f: make function! reduce [[v] body: [v + a]] >> o: context [a: 1] == make object! [ a: 1 ] >> bind body o == [v + a] | |
Ladislav: 17-May-2011 | This needs some thought, Geomol. Actual example: f1: closure [/local a][a: 1 [a]] f2: func [blk /local a][a: 2 do blk] f3: func [blk /local a][a: 3 do bind blk 'a] >> f2 f1 == 1 >> f3 f1 == 3 | |
BrianH: 17-May-2011 | Recursive functions in R2 work by pushing the block of values in a context onto a stack during the recursive calls, then popping them off on return. In R2, function contexts are stack-relative, which makes word dereferencing 27% slower relative to object contexts, but function calls in general faster. Closures bind to object contexts, which are recreated with every function call. | |
Geomol: 19-May-2011 | I found an bad effect of not binding words in blocks at all, before the block is evaluated. Functions like LOOP take 2 args, count and block. By not binding the block content before it's evaluated, the count arg local to LOOP is found, if a count var is used in the block. So I guess the REBOL early bind of words is better. | |
Geomol: 20-May-2011 | Yeah, they will be reused. But the way, REBOL do it, if you have an application, that do a lot of block parsing for example, with new words coming in all the time, then that global context will just grow and grow. In reality, it will probably come to an end, as there are a finite number of words in a human language, if that's what being parsed. If words were not bound by just being loaded, but only when evaluated (or compiled, if that's the case), then parsing blocks would not produce any unset! words in the global context. But a consequence of this is, that blocks of code being sent to a function (like LOOP), will be able to see the words local to that function, unless the block is first bound outside the function, like count: 1 loop 10 bind [print count] 'count , which will then print the number 1 10 times. | |
BrianH: 20-May-2011 | TO-HEX generates an issue!, which is a word type in R3. Yes, you can even bind them. | |
BrianH: 26-May-2011 | Geomol, about native-op!, native-closure! and native-action!, these won't be necessary. Functions of the native! type don't need to bind their bodies to contexts, so they don't need the feature that makes closures closures. Ops and actions both redirect to the actual implementing function, which in the case of actions is an internal native associated with the type of the first argument, and in the case of op is a (at the moment only native) function provided at op creation time. If you wanted to allow the creation of user-defined datatypes with function!, closure! or command! implementations of the type's actions, the regular action! functions would still redirect to these implementations. Similarly, the regular op! type could be extended to support redirecting to other function types without needing the creation of a new function type. | |
Ladislav: 26-May-2011 | Functions of the native! type don't need to bind their bodies to contexts - in that sense, natives behave both as functions and as closures at the same time. That is not as a big of an exception, as it may look, e.g.: f: func [][] behaves as a closure, similarly as g: func [x y][add :x :y] , simply because in such simple cases it is not discernible whether the given "function" is a function or a closure | |
BrianH: 28-May-2011 | Sunanda, agreed, and also about it being clunky, particularly because USE has both COPY/deep and BIND/copy overhead in R3. ASSERT/type [local none!] is still the most efficient method. | |
Ladislav: 8-Oct-2011 | Brian, regarding BIND, I mean e.g. this: >> f: make function! compose/only [[a b c](body: [a do c])] >> a: first body == a >> f 1 1 [a + b] ** Script error: b has no value ** Where: do f ** Near: do c >> f 1 1 bind [a + b] first body ** Script error: none word is not bound to a context ** Where: bind ** Near: bind [a + b] first body | |
BrianH: 8-Oct-2011 | Yeah, it is an interesting efficiency hack that MAKE function! does a BIND on the function body instead of a BIND/copy. It does mean that you need to be careful with the runtime accessibility of your source though. | |
Ladislav: 8-Oct-2011 | MAKE function! does a BIND on the function body instead of a BIND/copy - it is not only for efficiency, it is actually the proper way even for safety | |
Ladislav: 8-Oct-2011 | I do like that. but, nevertheless, the MAKE function is able to bind, while I am not, which proves, that it is just an artificial, (not making anything more secure) and annoying limitation | |
BrianH: 8-Oct-2011 | it is actually the proper way even for safety - Why so? Once the function is made, security dictates that the accessibility of its bound body should be limited. If you can get a bound body, you can trace through the bindings to get access to any internal code it references. That is why R3's BODY-OF does something like an UNBIND/deep COPY/deep. If MAKE function! does a BIND rather than a BIND/copy, that means that any extant references to the original body block argument are a potential security hole unless they are contained. | |
Ladislav: 8-Oct-2011 | But, that does not solve the BIND annoyance. | |
Ladislav: 8-Oct-2011 | In my opinion, BIND should simply obey and not annoy with error message in such a case | |
Ladislav: 8-Oct-2011 | As said, if BIND does not do it for me, I can do it on my own using CHANGE, so no safety can be gained | |
BrianH: 8-Oct-2011 | On second thought, allowing BIND to take a function! for its context argument would allow you to get around the security protections of BODY-OF. | |
BrianH: 8-Oct-2011 | But you can already BIND to a word bound to a function context. BODY-OF just keeps you from getting access to a word bound to a function context from outside the function. As long as you control access to the original code block you are secure. | |
Ladislav: 8-Oct-2011 | But you can already BIND to a word bound to a function context. - actually, I cannot, if the function isn't already running (in that case BIND refuses to do that) | |
BrianH: 8-Oct-2011 | >> bind 'a do func [/a] ['a] ** Script error: a is not in the specified context ** Where: bind ** Near: bind 'a do func [/a] ['a] Well, then you don't have to be as careful with letting bound function words leak I guess. | |
Ladislav: 8-Oct-2011 | But, that is wrong, since when you let the word out, you can bind, just not using the BIND function (you need to use CHANGE for that) | |
BrianH: 8-Oct-2011 | >> head change [1] 'a == [a] >> head change [1] #"a" == [#"a"] With BIND, you can leak the 'a word and get access to the 'b word from that same context. You can't do that with CHANGE. | |
BrianH: 8-Oct-2011 | (Sorry, internet outage) Sure it is, in some cases. What if 'a is harmless, but 'b refers to a password? If you can only CHANGE, not BIND, then leaking a word is only as dangerous as leaking what that word refers to. If you can BIND using that word as a context, you can get access to *every* value referred to by that context, not just the one. So it's still potentially a problem to leak a single word (depending on what gets assigned to that one word), but not as bad a problem as it could be. | |
Ladislav: 9-Oct-2011 | I am still sure, that disabling BIND in such cases is totally useless. (besides, when the function is not running, you cannot obtain the value of 'b even if you obtained 'b) | |
BrianH: 9-Oct-2011 | Oh, that's what you meant. I was asking specifically about the particular question I asked. It sounded like you were saying you had a way to do a BIND without BIND. If so, that would be an interesting trick, but also a security hole. I'm more interested in the trick though, if it exists. | |
Ladislav: 9-Oct-2011 | Not much of a trick is needed. The above statement (when proven, which is easy), proves, that the disabling of BIND for non-running function words is not a security measure. | |
BrianH: 9-Oct-2011 | Let's ignore the function context aspect of it all, and simplify the problem. If you have a word bound to a context, and want to get access to another word bound to the same context, and don't have access to the BIND or IN functions at all, how would you do it? | |
Ladislav: 9-Oct-2011 | (Even though the BIND function is "crippled*, but, as proven by the above statement, unreasonably so.) | |
Ladislav: 9-Oct-2011 | Yes, but my intent was to prove, that the BIND crippling is unreasonable, which is provable. | |
Ladislav: 9-Oct-2011 | Above you mentioned, that the reson is this: - if I had access to a 'var-a variable bound to the F's context, and if I were able to do "some harm" having another variable 'var-b bound to the F's context, then that is a good reason why to cripple BIND, to not give me the access to the 'var-b bound to the F's context as well when the function is not running. As stated, I can disprove that as a reason. | |
Ladislav: 9-Oct-2011 | OK, I will cite you exactly: Sure it is, in some cases. What if 'a is harmless, but 'b refers to a password? If you can only CHANGE, not BIND, then leaking a word is only as dangerous as leaking what that word refers to. If you can BIND using that word as a context, you can get access to *every* value referred to by that context, not just the one. So it's still potentially a problem to leak a single word (depending on what gets assigned to that one word), but not as bad a problem as it could be. | |
BrianH: 9-Oct-2011 | OK, so you don't have a solution to that problem (darn, I was looking forward to that), but you have a proposed proof that it doesn't matter because you can't exploit it until the function is running. And since the BIND restriction when the function isn't running doesn't apply when the function *is* running later, even when applied to the same word, then the ban on BIND to a function-context-bound word when the function isn't running has no security benefit. But the ban on BIND to the function! value *itself* still has value, because it would defeat the efforts to prevent any bound words from leaking out of the function from helping. Otherwise it would be unsafe to let untrusted code call safe functions because they would need to have a reference to the function in order to call it. | |
Ladislav: 9-Oct-2011 | But the ban on BIND to the function! value *itself* still has value, because it would defeat the efforts to prevent any bound words from leaking out of the function from helping. - another disprovable statement | |
BrianH: 9-Oct-2011 | The "But the ban on BIND to the function! value *itself*..." statement refers to this: >> not find second types-of :bind function! == true The BIND function doesn't accept function! values for its context argument. The reason for this is so that functions can prevent access to their context from leaking to code *that the function calls* that could be exploited while the function is running. All the function has to do is not leak bound words, and it's safe. If that doesn't work, please show how. | |
Ladislav: 9-Oct-2011 | To remind you, I am and was always referring to this: >> f: func [a b] ['a] >> bind [b] f 1 2 ** Script error: none word is not bound to a context ** Where: bind ** Near: bind [b] f 1 2 The above is unrelated | |
BrianH: 9-Oct-2011 | No, the above is the exact reason for: >> not find second types-of :bind function! == true | |
Ladislav: 9-Oct-2011 | But, the reasons for disallowing the functions as the BIND arguments have actually a similar flaw. | |
BrianH: 9-Oct-2011 | a: func [code /stuff] [stuff: "something secret, not a literal string" code] With just a reference to :a, bind 'stuff to the function context. The function could be running or not when you get access to the bound word 'stuff. The exploit code can then be passed to the function in its code argument, which would then have access to the contents of 'stuff because the function is running. | |
BrianH: 9-Oct-2011 | No, seriously, I meant it. How do you do this without BIND 'stuff :a ? | |
BrianH: 9-Oct-2011 | a func [] [print get bind 'stuff :a] | |
Ladislav: 9-Oct-2011 | OK, but nothing of that kind applies to the case of BIND [...] 'some-variable | |
BrianH: 9-Oct-2011 | then the ban on BIND to a function-context-bound word when the function isn't running has no security benefit :) |
801 / 992 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | [9] | 10 |