]> gitweb.michael.orlitzky.com - dead/harbl.git/blobdiff - src/Domain.hs
Add length (max 255) checking for domains.
[dead/harbl.git] / src / Domain.hs
index 8d1e0885c8ae57739a6a24c8e5ec697739e57c7c..f19b11115989822dcde6303565708a083bc4d1b7 100644 (file)
@@ -5,7 +5,16 @@
 --
 --     <https://tools.ietf.org/html/rfc1035#section-2.3.1>
 --
-module Domain
+--   We basically work with strings and characters everywhere, even
+--   though this isn't really correct. The length specifications in
+--   the RFCs are all in terms of octets, so really a ByteString.Char8
+--   would be more appropriate. With strings, for example, we could
+--   have a unicode mumbo jumbo character that takes up two bytes
+--   (octets).
+--
+module Domain (
+  UserDomain,
+  user_domain )
 where
 
 import Data.Char ( toLower )
@@ -25,7 +34,7 @@ import Text.Parsec (
 import qualified Text.Parsec as Parsec ( digit, letter)
 import Text.Parsec.String ( Parser )
 
-import Pretty
+import Pretty ( Pretty(..) )
 
 -- * Digits
 
@@ -565,10 +574,34 @@ instance Pretty Domain where
 --   >>> parseTest domain "."
 --   DomainRoot
 --
+--   Anything over 255 characters is an error, so the root will be
+--   parsed:
+--
+--   >>> let big_label = replicate 63 'x'
+--   >>> let big_subdomain = concat $ replicate 5 (big_label ++ ".")
+--   >>> parseTest domain big_subdomain
+--   DomainRoot
+--
+--   But exactly 255 is allowed:
+--
+--   >>> import Data.List ( intercalate )
+--   >>> let big_label = replicate 63 'x'
+--   >>> let big_subdomain = intercalate "." (replicate 4 big_label)
+--   >>> let (Right r) = parse domain "" big_subdomain
+--   >>> length (pretty_show r)
+--   255
+--
 domain :: Parser Domain
 domain = try parse_subdomain <|> parse_empty
   where
-    parse_subdomain = fmap DomainName subdomain
+    parse_subdomain :: Parser Domain
+    parse_subdomain = do
+      s <- subdomain
+      if (length $ pretty_show s) <= 255
+      then return $ DomainName s
+      else fail "subdomains can be at most 255 characters"
+
+    parse_empty :: Parser Domain
     parse_empty = string "" >> return DomainRoot