On Mon, Apr 11, 2011 at 7:09 PM, James Reeves <jree...@weavejester.com> wrote: > On 11 April 2011 21:26, Ken Wesson <kwess...@gmail.com> wrote: >> On Mon, Apr 11, 2011 at 1:09 PM, James Reeves <jree...@weavejester.com> >> wrote: >>> If you already have a, b, and c, then compounding them into one >>> function, only to then use a map to split them up again doesn't seem a >>> good solution. >> >> The preconditions have to be checked. The preconditions for >> integer-in-range checks are the integer check and the non-blank check, >> in the original example. I don't really see any way of simplifying >> that further, unless the logic of verifying the preconditions is moved >> out to the caller (and, thus, duplicated for every caller). > > You wouldn't necessarily need to explicitly verify each precondition, > but it might be the case that the same string is parsed multiple > times. However, I'm unsure why you think this is a problem.
I don't. My own code posted earlier parses some strings multiple times. I eschewed premature optimization there; a temporary memoized version of each predicate, new per field being validated per request, can be used to get rid of the multiple parsings if it's really, really necessary. >>> (chain >>> (validation a "A failed") >>> (validation b "B failed") >>> (validation c "C failed")) >>> >>> Here each function does precisely one thing (i.e. they are simple), so >>> we achieve the same effect without compounding. >> >> You have compounding, via your "chain" here. You've just broken out a >> couple of more explicit steps. > > If the chain of validations were placed in a function, then it could > be described as compound. Where is your (chain ...) sexp going to go? At top level? If it's not, then it's placed in a function. > But it's compound by necessity, and has a > singular purpose - to validate a particular object. So's mine. > Your not-int-in-range? function is not compound by necessity, as three > or four simpler functions could perform the same task No, since it has to deal with blank/non-integer input somehow anyway. Either it has to check those preconditions, or its caller does. Either it is a compound predicate, its caller is a compound predicate, or the code at the bottom of the next layer up contains duplicated precondition logic for every separate case of an integer range check. > and it doesn't have a singular purpose. It's a more complex, and to > my mind, less idiomatic solution. Yours is simpler at the expense of forcing the caller to check the preconditions. Either you end up with duplicated code for every separate integer range check (bad), or you end up with a function in between the two that checks the preconditions, and is then a compound predicate. >>> Because if you forget to validate a field that is allow by default, >>> then you end up with invalid data in your database and a potential >>> security risk. >> >> If you forget to do *anything* in a security-critical system, that's a >> potential security risk. > > If you forget a "deny" rule, that's a potential security risk, but if > you forget an "allow" rule, it usually isn't. But it sometimes is. > For instance, say you have a firewall that's "deny all" by default. > You want to allow ports 22 and 80, but forget port 80. This will > result in your web server being inaccessible, but your security won't > be compromised. In fact, by forgetting a rule, you've made the system > *more* secure, if less useful. If the web server is providing security patches and updates, its inaccessibility may make a wider system less secure. >>> If, on the other hand, you forget to validate a field that is deny by >>> default, then you end up with a failed validation. >> >> Depending on the application, even dead functionality can be a >> security risk. Perhaps it causes a police fingerprint-database search >> to not work or produce a false negative, for instance. > > But these situations are rare, and usually easily discovered. But, but, but. You made a universal statement that I've proven was wrong. You've basically admitted this by admitting that there are any exceptions at all to your "universal" rule. So, why keep arguing? >> Ultimately, assessing security risks requires knowing the particulars >> of the application and its intended uses. > > Sure, but But, but, but! What is it with you? :) > it helps to have sensible defaults, and "deny all" is usually the most > secure place to start. Again, that depends on the system and on what you mean by "secure". Is "deny all" a sensible default when designing MP3 player firmware? "Security" in such a context means "nobody unauthorized can screw with my music storage, organization, and playback". Things not working would be the player's manufacturer having effectively screwed with your music storage, organization, and playback. So "deny all" is effectively a *less* secure default in that case (and this goes for a lot of non-mission-critical, single-user applications). It is often a more secure default in other cases (important, multi-user or network-facing systems). There is no single right answer here that is independent of the application's basic nature and use context! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en