[cap-talk] Abstractions that subsume capabilities

Richard Uhtenwoldt notprivate2 at gmail.com
Wed Mar 12 00:04:11 EDT 2008


From: "Richard Underwood/Uhtenwoldt" <ru at sonic.net>

Kevin "performs surgery" on the following simple Haskell
program to give it "the capability nature":

main = do
    s <- readFile "/etc/passwd"
    hPrint stdout s

But the above code does not need to be changed to be good,
attack-resistant code.  To see why, we will make some very simple
modifications to it: namely, we will use different, more-primitive
input/output facilities to achieve the exact same behavior:

import IO
main = do
    handle <- openFile "/etc/passwd" ReadMode
    contents <- hGetContents handle
    flip mapM_ (lines contents)
        (\ line -> hPutStrLn stdout line)

Here is untested E code which does the same thing.  Observe that
it is almost identical except for syntax and the names of the
input/output operations.

    def handle := <file:/etc/passwd>
    def contents := handle.getText()
    for line in contents.split("\n") {
        println(line)
    }

To be painfully explicit in case you do not get it yet,
hGetContents is Haskell's version of E's getText; flip map is
Haskell's version of E's for loop; lines is Haskell's version of
E's split("\n"); hPutStrLn stdout is Haskell's version of E's
println.

Since I found the E code in the E Idioms Quick Reference Card, I
assume you all regard it as good, attack-resistant code.  But
obviously if it does not need surgery to make it more
attack-resistant, the Haskell code does not either.

It appears that there is a tendency on this mailing list to try
to make monads --and referential transparency?-- do things
they cannot do.

P.S.  In case there are any beginning Haskell learners reading
this, here are the type signatures of all the identifiers in the
above Haskell code:

data IOMode           =  ReadMode | WriteMode | AppendMode | ReadWriteMode
openFile              :: FilePath -> IOMode -> IO Handle
hGetContents          :: Handle -> IO String
-- flip f  takes its (first) two arguments in the reverse order of f.
flip                  :: (a -> b -> c) -> b -> a -> c
-- here is a definition of flip:
flip f x y            = f y x
mapM_                 :: Monad m => (a -> m b) -> [a] -> m ()
-- here is a definition of mapM:
mapM_ f as            = sequence_ (map f as)
sequence_             :: Monad m => [m a] -> m ()
sequence_             = foldr (>>) (return ())
-- lines breaks a string up into a list of strings at newline characters.
-- The resulting strings do not contain newlines.
lines                 :: String -> [String]
hPutStrLn             :: Handle -> String -> IO ()

-- 
Text by me above is hereby placed in the public domain


More information about the cap-talk mailing list