hs-php-session (empty) → 0.0.8.8
raw patch · 7 files changed
+542/−0 lines, 7 filesdep +basedep +bytestringsetup-changed
Dependencies added: base, bytestring
Files
- Data/PHPSession.hs +346/−0
- Data/PHPSession/Types.hs +98/−0
- LICENSE +30/−0
- README.md +4/−0
- Setup.hs +2/−0
- Test/General.hs +36/−0
- hs-php-session.cabal +26/−0
+ Data/PHPSession.hs view
@@ -0,0 +1,346 @@+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Data.PHPSession+-- Copyright: (c) 2013-2014 Edward Blake+-- License: BSD-style+-- Maintainer: Edward L. Blake <edwardlblake@gmail.com>+-- Stability: experimental+-- Portability: portable+--+-- Encodes and decodes serialized PHP sessions in the format used by the \"php\" setting+-- for session.serialize_handler.+-- ++module Data.PHPSession (+ -- * Decode from 'ByteString'+ decodePHPSession,+ decodePHPSessionValue,+ -- * Encode to 'ByteString'+ encodePHPSession,+ encodePHPSessionValue,+ -- * Decode only part of a 'ByteString'+ decodePartialPHPSession,+ decodePartialPHPSessionValue,+ -- * PHP session types+ PHPSessionVariableList,+ PHPSessionClassName (..),+ PHPSessionValue (..),+ PHPSessionAttr (..)+) where++import Data.PHPSession.Types++import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as LBS+import qualified Data.List as L+import Data.List (foldl')+import qualified Data.Char as C++-- import qualified Text.Regex.Posix as TR++-- | Decodes a 'ByteString' representing a PHP session into a 'PHPSessionVariableList'+decodePHPSession :: LBS.ByteString -> Maybe PHPSessionVariableList+decodePHPSession input =+ case decodePartialPHPSession input of+ (everything,"") -> everything+ (_, _) -> Nothing++-- -> [(LBS.ByteString, PHPSessionValue)]+-- | Decodes as much as needed of a 'ByteString' representing a PHP session into a 'PHPSessionVariableList'+decodePartialPHPSession :: LBS.ByteString -> (Maybe PHPSessionVariableList, LBS.ByteString)+decodePartialPHPSession "" = (Nothing, "")+decodePartialPHPSession input =+ decodePartialPHPSessionEachTopLevel input []+ where+ decodePartialPHPSessionEachTopLevel input lst =+ case input of+ "" -> (Just $ reverse lst,"")+ _ ->+ case LBS.take 1 input of+ "}" ->+ (Just $ reverse lst, LBS.drop 1 input)+ _ ->+ case decodePartialPHPSessionVarName input of+ (Nothing,_) -> (Nothing, input)+ (Just name, rest) ->+ case decodePartialPHPSessionValue rest of+ (Nothing,_) -> (Nothing, input)+ (Just sym,rest') ->+ decodePartialPHPSessionEachTopLevel rest' ((name, sym):lst)+ decodePartialPHPSessionVarName input =+ case dec input of+ Nothing -> (Nothing, input)+ Just (sername, rest) -> (Just sername, rest)+ --case input TR.=~ ("[a-zA-Z_][a-zA-Z0-9_]*\\|" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",sernametype,rest) ->+ -- let (sername,_) = LBS.span (/='|') sernametype+ -- in (sername,rest)+-- where+ dec input = do+ (f0,n0) <- get_alpha input+ (restname,n1) <- get_alphanum_any_left n0+ (_,n2) <- get_vertbar n1+ return (LBS.concat [f0,restname], n2)+ get_alpha input =+ case LBS.takeWhile (\a -> (C.isAsciiLower a) || (C.isAsciiUpper a) || (a == '_')) input of+ "" -> Nothing; l -> Just (l, LBS.drop (LBS.length l) input)+ get_alphanum_any_left input =+ case LBS.takeWhile (\a -> (C.isAsciiLower a) || (C.isAsciiUpper a) || (C.isDigit a) || (a == '_')) input of+ l -> Just (l, LBS.drop (LBS.length l) input)+ get_vertbar input = case LBS.take 1 input of "|" -> Just ("|", LBS.drop 1 input); _ -> Nothing+++ +-- Not exported and used by decodePartialPHPSessionValue+decodePartialPHPSessionValuesNested :: LBS.ByteString -> [PHPSessionValue] -> (Maybe [PHPSessionValue], LBS.ByteString)+decodePartialPHPSessionValuesNested input lst =+ case input of+ "" -> (Just $ reverse lst,"")+ _ ->+ case LBS.take 1 input of+ "}" ->+ (Just $ reverse lst, LBS.drop 1 input)+ _ ->+ case decodePartialPHPSessionValue input of+ (Just sym,rest) -> + decodePartialPHPSessionValuesNested rest (sym:lst)+ _ -> (Nothing, input)+++-- | Decodes a 'ByteString' into a 'PHPSessionValue'+decodePHPSessionValue :: LBS.ByteString -> Maybe PHPSessionValue+decodePHPSessionValue input =+ case decodePartialPHPSessionValue input of+ (everything,"") -> everything+ (_,_) -> Nothing++-- | Decodes as much of a 'ByteString' as needed into a 'PHPSessionValue'+decodePartialPHPSessionValue :: LBS.ByteString -> (Maybe PHPSessionValue, LBS.ByteString)+decodePartialPHPSessionValue "" = (Nothing, "")+decodePartialPHPSessionValue input =+ let sertype = LBS.take 1 input+ rest = LBS.drop 1 input+ in case sertype of+ -- "Object implementing Serializeable" (C)+ -- ex: hi|C:9:"ClassName":5:{harr}}+ "C" ->+ case dec_colon_integer_colon_dquote_classname_dquote_colon rest of+ Nothing -> (Nothing, input)+ Just (_classnamelen,cls',numrest) ->+ + --case rest TR.=~ (":[0-9]+:\"[A-Za-z0-9_]+\":" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",cls,numrest) ->+ case LBS.span (/=':') numrest of+ (num, colrest) ->+ -- let [_,cls',_] = LBS.split '"' cls+ let num' = read (LBS.unpack num)+ (dat,rest') = LBS.splitAt num' $ LBS.drop 2 colrest+ rest'' = LBS.drop 1 rest' + in (Just $ PHPSessionValueObjectSerializeable (PHPSessionClassName cls') dat, rest'')+ + -- Object (O) ex: hi|O:9:"ClassName":2:{s:4:"blah";i:1;s:3:"str";s:6:"string";}+ "O" ->+ case dec_colon_integer_colon_dquote_classname_dquote rest of+ Nothing -> (Nothing, input)+ Just (_,cls',attrest) ->+ -- case rest TR.=~ (":[0-9]+:\"[A-Za-z0-9_]+\"" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",cls,attrest) ->+ -- let [_,cls',_] = LBS.split '"' cls+ let (l,rest') = decodePartialPHPSessionAttr attrest []+ in case l of+ Nothing -> (Nothing, input)+ Just [PHPSessionAttrInt _, PHPSessionAttrNested vals] ->+ let (al, bl) = L.partition (odd . snd) (zip vals [1..])+ arlst = map (\[a,b] -> (a,b)) $ L.transpose [ map (\(a,_)->a) al, map (\(a,_)->a) bl ]+ in ((Just $ PHPSessionValueObject (PHPSessionClassName cls') arlst),rest')+ + -- String (s) ex: hi|s:6:"string";+ "s" ->+ case dec_colon_integer_colon_dquote rest of+ Nothing -> (Nothing, input)+ Just (len, strrest) ->+ --case rest TR.=~ (":[0-9]+:\"" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",strlen,strrest) ->+ -- let [_,len,_] = LBS.split ':' strlen+ let len' = read (LBS.unpack len)+ (str,rest') = LBS.splitAt len' $ strrest+ rest'' = LBS.drop 2 rest' + in (Just $ PHPSessionValueString str,rest'')+ + _ ->+ let (l,rest') = decodePartialPHPSessionAttr rest []+ in case (sertype, l) of+ -- Array (a) ex: hi|a:3:{i:0;i:1;i:1;i:2;i:2;s:3:"abc";}+ ("a",Just [PHPSessionAttrInt _, PHPSessionAttrNested vals]) -> + let (al, bl) = L.partition (odd . snd) (zip vals [1..])+ arlst = map (\[a,b] -> (a,b)) $ L.transpose [ map (\(a,_)->a) al, map (\(a,_)->a) bl ]+ in (Just $ PHPSessionValueArray arlst, rest')+ + -- Boolean (b) ex: hi|b:0; = FALSE -- hi|b:1; = TRUE+ ("b",Just [PHPSessionAttrInt 1]) -> (Just $ PHPSessionValueBool True,rest')+ ("b",Just [PHPSessionAttrInt 0]) -> (Just $ PHPSessionValueBool False,rest')+ + -- Float (d) ex: hi|d:0.1000000000000000055511151231257827021181583404541015625;+ ("d",Just [PHPSessionAttrFloat num]) -> (Just (PHPSessionValueFloat $ Right num),rest')+ ("d",Just [PHPSessionAttrInt num]) -> (Just (PHPSessionValueFloat $ Left num),rest')+ + -- Integer (i) ex: hi|i:26;+ ("i",Just [PHPSessionAttrInt num]) -> (Just $ PHPSessionValueInt num,rest')+ + -- Null (N) ex: hi|N;+ ("N",Just []) -> (Just PHPSessionValueNull,rest')+ + -- Recursive values and references (r), (R), TODO: PHP 6 encoded String (S)+ _ -> case l of+ Just l' -> (Just (PHPSessionValueMisc sertype l'),rest')+ Nothing -> (Nothing, input)+ where++ decodePartialPHPSessionAttr :: LBS.ByteString -> [PHPSessionAttr] -> (Maybe [PHPSessionAttr],LBS.ByteString)+ decodePartialPHPSessionAttr input l =+ case LBS.take 1 input of+ ";" ->+ (Just $ reverse l,LBS.drop 1 input)+ _ ->+ case dec_colon_and_number input of+ Just (num,rest) ->+ --case input TR.=~ (":[-0-9.]+" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",num,rest) ->+ let num' = LBS.unpack $ num -- LBS.drop 1 + in case LBS.elem '.' num of+ True ->+ decodePartialPHPSessionAttr rest ((PHPSessionAttrFloat $ read $ num'):l)+ False ->+ decodePartialPHPSessionAttr rest ((PHPSessionAttrInt $ read $ num'):l)+ _ ->+ case dec_colon_and_open_curly input of+ Just (":{", rest) ->+ -- case input TR.=~ (":{" :: LBS.ByteString) :: (LBS.ByteString,LBS.ByteString,LBS.ByteString) of+ -- ("",":{",rest) ->+ let (Just sub,rest') = decodePartialPHPSessionValuesNested rest []+ in (Just $ reverse (PHPSessionAttrNested sub:l),rest')+ Nothing ->+ (Nothing, input)+ -- error "No good"+ dec_colon_integer_colon_dquote_classname_dquote_colon input = do+ (_0,n0) <- dec_get_colon input+ (len,n1) <- dec_get_integer n0+ (_2,n2) <- dec_get_colon n1+ (_3,n3) <- dec_get_dquote n2+ (classname,n4) <- dec_get_alphanum n3+ (_5,n5) <- dec_get_dquote n4+ (_6,n6) <- dec_get_colon n5+ return (len,classname,n6)+ dec_colon_integer_colon_dquote_classname_dquote input = do+ (_0,n0) <- dec_get_colon input+ (len,n1) <- dec_get_integer n0+ (_2,n2) <- dec_get_colon n1+ (_3,n3) <- dec_get_dquote n2+ (classname,n4) <- dec_get_alphanum n3+ (_5,n5) <- dec_get_dquote n4+ return (len,classname,n5)+ dec_colon_integer_colon_dquote input = do+ (_0,n0) <- dec_get_colon input+ (len,n1) <- dec_get_integer n0+ (_2,n2) <- dec_get_colon n1+ (_3,n3) <- dec_get_dquote n2+ return (len,n3)+ dec_colon_and_number input = do+ (_0,n0) <- dec_get_colon input+ (num,n1) <- dec_get_number n0+ return (num,n1)+ dec_colon_and_open_curly input = do+ (_0,n0) <- dec_get_colon input+ (_1,n1) <- dec_get_openc input+ return (":{", n1)+ + dec_one_or_more input a = case a of "" -> Nothing; l -> Just (l, LBS.drop (LBS.length l) input)+ dec_get_number input =+ dec_one_or_more input $ LBS.takeWhile (\a -> (C.isDigit a) || (a == '-') || (a == '.')) input+ dec_get_alphanum input =+ dec_one_or_more input $ LBS.takeWhile (\a -> (C.isDigit a) || (C.isAsciiLower a) || (C.isAsciiUpper a) || (a == '_')) input+ dec_get_integer input =+ dec_one_or_more input $ LBS.takeWhile C.isDigit input+ dec_get_openc input = case LBS.take 1 input of "{" -> Just ("{", LBS.drop 1 input); _ -> Nothing+ dec_get_dquote input = case LBS.take 1 input of "\"" -> Just ("\"", LBS.drop 1 input); _ -> Nothing+ dec_get_colon input = case LBS.take 1 input of ":" -> Just (":", LBS.drop 1 input); _ -> Nothing++-- | Encode a 'PHPSessionVariableList' into a 'ByteString'.+encodePHPSession :: PHPSessionVariableList -> LBS.ByteString+encodePHPSession lst =+ encodePHPSessionTop lst []+encodePHPSessionTop lst outlst =+ case lst of+ [] -> LBS.concat $ reverse outlst+ (name,var):xs ->+ let out' = (encodePHPSessionVarName name) : outlst+ out'' = (encodePHPSessionValue var) : out'+ in encodePHPSessionTop xs out''+ where+ encodePHPSessionVarName name =+ LBS.concat [name, "|"]++-- | Encode a 'PHPSessionValue' into a 'ByteString'.+encodePHPSessionValue var =+ case var of+ PHPSessionValueObjectSerializeable (PHPSessionClassName cls) dat ->+ LBS.concat+ [+ "C:", LBS.pack $ show (LBS.length cls), ":\"", cls, "\":",+ LBS.pack $ show (LBS.length dat), ":{", dat, "}"+ ]+ PHPSessionValueArray arlst ->+ let nst = reverse $ foldl' (\l (k,v) -> (v:(k:l))) [] arlst+ in LBS.concat+ [+ "a", encodePHPSessionAttr (PHPSessionAttrInt $ length arlst),+ encodePHPSessionAttr (PHPSessionAttrNested nst)+ ]+ PHPSessionValueBool b ->+ LBS.concat+ [+ "b", encodePHPSessionAttr (PHPSessionAttrInt $ if b then 1 else 0), ";"+ ]+ PHPSessionValueFloat d ->+ LBS.concat+ [+ "d", encodePHPSessionAttr $+ case d of+ Left i -> PHPSessionAttrInt i;+ Right d' -> PHPSessionAttrFloat d',+ ";"+ ]+ PHPSessionValueInt i ->+ LBS.concat+ [+ "i", encodePHPSessionAttr (PHPSessionAttrInt i), ";"+ ]+ PHPSessionValueNull ->+ "N;"+ PHPSessionValueObject (PHPSessionClassName cls) proplst ->+ let nst = reverse $ foldl' (\l (k,v) -> (v:(k:l))) [] proplst+ cls' = BS.concat $ LBS.toChunks cls+ in LBS.concat+ [+ "O", encodePHPSessionAttr (PHPSessionAttrInt $ BS.length cls'),+ ":\"", LBS.fromChunks [cls'], "\"",+ encodePHPSessionAttr (PHPSessionAttrInt $ length proplst),+ encodePHPSessionAttr (PHPSessionAttrNested nst)+ ]+ PHPSessionValueString str ->+ let str' = BS.concat $ LBS.toChunks str+ in LBS.concat+ [+ "s", encodePHPSessionAttr (PHPSessionAttrInt $ BS.length str'),+ ":\"", LBS.fromChunks [str'], "\";"+ ]+ PHPSessionValueMisc sertype atts ->+ LBS.concat $ [sertype] ++ map encodePHPSessionAttr atts ++ [";"]+ where++ encodePHPSessionAttr att =+ case att of+ PHPSessionAttrInt i -> LBS.concat [":", LBS.pack $ show i]+ PHPSessionAttrFloat f -> LBS.concat [":", LBS.pack $ show f]+ PHPSessionAttrNested vars ->+ LBS.concat $ [":{"] ++ map encodePHPSessionValue vars ++ ["}"]
+ Data/PHPSession/Types.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Data.PHPSession+-- Copyright: (c) 2013-2014 Edward Blake+-- License: BSD-style+-- Maintainer: Edward L. Blake <edwardlblake@gmail.com>+-- Stability: experimental+-- Portability: portable+--+-- Encodes and decodes serialized PHP sessions in the format used by the \"php\" setting+-- for serialize_handler.+-- ++module Data.PHPSession.Types (+ -- * PHP session types+ PHPSessionVariableList,+ PHPSessionClassName (..),+ PHPSessionValue (..),+ PHPSessionAttr (..)+) where++import qualified Data.ByteString.Lazy.Char8 as LBS++-- | Holds the "top-level" session variables and their value contents.+type PHPSessionVariableList = [(LBS.ByteString, PHPSessionValue)]++data PHPSessionClassName =+ PHPSessionClassName LBS.ByteString++instance Show PHPSessionClassName where+ show (PHPSessionClassName str) = "PHPSessionClassName " ++ show str++instance Eq PHPSessionClassName where+ PHPSessionClassName a == PHPSessionClassName b = a == b++data PHPSessionValue =+ PHPSessionValueArray [(PHPSessionValue,PHPSessionValue)] |+ PHPSessionValueBool Bool |+ PHPSessionValueFloat (Either Int Double) |+ PHPSessionValueInt Int |+ PHPSessionValueNull |+ PHPSessionValueObject PHPSessionClassName [(PHPSessionValue,PHPSessionValue)] |+ PHPSessionValueObjectSerializeable PHPSessionClassName LBS.ByteString |+ PHPSessionValueString LBS.ByteString |+ PHPSessionValueMisc LBS.ByteString [PHPSessionAttr]++instance Show PHPSessionValue where+ show (PHPSessionValueArray arlst) = "PHPSessionValueArray " ++ show arlst+ show (PHPSessionValueBool b) = "PHPSessionValueBool " ++ show b+ show (PHPSessionValueFloat f) = "PHPSessionValueFloat " ++ show f+ show (PHPSessionValueInt i) = "PHPSessionValue " ++ show i+ show (PHPSessionValueNull) = "PHPSessionValueNull"+ show (PHPSessionValueObject cls xs) = "PHPSessionValueObject " ++ show cls ++ " " ++ show xs+ show (PHPSessionValueObjectSerializeable x xs) =+ "PHPSessionValueObjectSerializeable " ++ show x ++ " " ++ show xs+ show (PHPSessionValueString s) = "PHPSessionValueString " ++ show s+ show (PHPSessionValueMisc x xs) = "PHPSessionValueMisc " ++ show x ++ " " ++ show xs++instance Eq PHPSessionValue where+ PHPSessionValueArray a == PHPSessionValueArray b = a == b+ PHPSessionValueBool a == PHPSessionValueBool b = a == b+ PHPSessionValueFloat a == PHPSessionValueFloat b = a == b+ PHPSessionValueInt a == PHPSessionValueInt b = a == b+ PHPSessionValueNull == PHPSessionValueNull = True+ PHPSessionValueObject a b == PHPSessionValueObject c d = a == c && b == d+ PHPSessionValueObjectSerializeable a b == PHPSessionValueObjectSerializeable c d = a == c && b == d+ PHPSessionValueString a == PHPSessionValueString b = a == b+ PHPSessionValueMisc a b == PHPSessionValueMisc c d = False+ _ == _ = False+ +instance Ord PHPSessionValue where+ PHPSessionValueArray a <= PHPSessionValueArray b = a <= b+ PHPSessionValueBool a <= PHPSessionValueBool b = a <= b+ PHPSessionValueFloat a <= PHPSessionValueFloat b = a <= b+ PHPSessionValueInt a <= PHPSessionValueInt b = a <= b+ PHPSessionValueNull <= PHPSessionValueNull = True+ PHPSessionValueObject (PHPSessionClassName a) b <= PHPSessionValueObject (PHPSessionClassName c) d = a <= c && b <= d+ PHPSessionValueObjectSerializeable (PHPSessionClassName a) b <= PHPSessionValueObjectSerializeable (PHPSessionClassName c) d = a <= c && b <= d+ PHPSessionValueString a <= PHPSessionValueString b = a <= b+ PHPSessionValueMisc a b <= PHPSessionValueMisc c d = False+ _ <= _ = False+ +data PHPSessionAttr =+ PHPSessionAttrInt Int |+ PHPSessionAttrFloat Double |+ PHPSessionAttrNested [PHPSessionValue]++instance Show PHPSessionAttr where+ show (PHPSessionAttrInt n) = "PHPSessionAttrInt " ++ show n+ show (PHPSessionAttrFloat n) = "PHPSessionAttrFloat " ++ show n+ show (PHPSessionAttrNested ns) = "PHPSessionAttrNested " ++ show ns++instance Eq PHPSessionAttr where+ PHPSessionAttrInt a == PHPSessionAttrInt b = a == b+ PHPSessionAttrFloat a == PHPSessionAttrFloat b = a == b+ PHPSessionAttrNested a == PHPSessionAttrNested b = a == b+ _ == _ = False+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Edward L. Blake + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Edward L. Blake nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+hs-php-session +============== + +Haskell library for encoding and decoding PHP session serializations
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple +main = defaultMain
+ Test/General.hs view
@@ -0,0 +1,36 @@+-- |+-- Module : Data.PHPSession+-- License: BSD3+-- Maintainer: Edward L. Blake <edwardlblake@gmail.com>+-- Stability: experimental+-- Portability: unknown+--+-- Testing Data.PHPSession+-- +{-# LANGUAGE OverloadedStrings #-}++module Test.General where++import Data.PHPSession++import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as LBS+import qualified Data.List as L+import qualified Text.Regex.Posix as TR+import Data.List (foldl')++testcases :: Bool+testcases =+ let test1 = "v1|s:94:\" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}\";v2|a:3:{i:0;i:10;i:1;i:9;i:2;s:5:\"eight\";}v3|C:9:\"ClassName\":94:{ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}}v4|b:1;v5|i:10;v6|d:5.5;v7|N;"+ test2 = "v1|a:3:{i:0;i:10;i:1;i:9;i:2;a:3:{i:0;i:8;i:1;i:7;i:2;a:3:{i:0;i:6;i:1;s:4:\"five\";i:2;d:4;}}}v2|O:9:\"ClassName\":2:{s:4:\"blah\";i:1;s:3:\"str\";s:94:\" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}\";}"+ test3 = "v1|s:256:\"00000000000000000000000000000000 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\";"+ tresults = map (\test -> case decodePHPSession test of+ Nothing -> False+ Just dec -> let result = encodePHPSession dec in+ if result == test+ then True+ else error $ "Not same: " ++ LBS.unpack test ++ " and " ++ LBS.unpack result)+ [test3] -- [test1,test2,test3]+ fresults = map (\test -> case decodePHPSession test of Nothing -> False; Just dec -> let result = encodePHPSession dec in result == test)+ []+ in and tresults && ((or fresults) /= True)
+ hs-php-session.cabal view
@@ -0,0 +1,26 @@+name: hs-php-session +version: 0.0.8.8 +synopsis: PHP session serialization +-- description: +homepage: https://github.com/elblake/hs-php-session +license: BSD3 +license-file: LICENSE +author: Edward L. Blake +maintainer: edwardlblake@gmail.com +-- copyright: +category: Data +build-type: Simple +cabal-version: >=1.8 + +extra-source-files: + README.md + Test/General.hs + +library + exposed-modules: + Data.PHPSession + Data.PHPSession.Types + -- other-modules: + build-depends: + base ==4.6.*, + bytestring