以下のコードは、安全でないGeneralizedNewtypeDeriving
拡張機能を使用して、異なるインスタンスData.Set
を持つ異なる要素を挿入することで中断しています。Ord
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Data.Set
import System.Random
class AlaInt i where
fromIntSet :: Set Integer -> Set i
toIntSet :: Set i -> Set Integer
instance AlaInt Integer where
fromIntSet = id
toIntSet = id
newtype I = I Integer deriving (Eq, Show, AlaInt)
instance Ord I where compare (I n1) (I n2) = compare n2 n1 -- sic!
insert' :: Integer -> Set Integer -> Set Integer
insert' n s = toIntSet $ insert (I n) $ fromIntSet s
randomInput = take 5000 $ zip (randomRs (0,9) gen) (randoms gen) where
gen = mkStdGen 911
createSet = Prelude.foldr f empty where
f (e,True) = insert e
f (e,False) = insert' e
main = print $ toAscList $ createSet randomInput
コードが出力され[1,3,5,7,8,6,9,6,4,2,0,9]
ます。リストは順不同で、9
2 回あることに注意してください。
他の拡張機能を使用してこの辞書スワッピング攻撃を実行することは可能ConstraintKinds
ですか? はいの場合、Data.Set
そのような攻撃に耐えられるように再設計できますか?