diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+# 1.10.0
+
++ String match fixes (thanks @sol !).
+
 # 1.8.0
 
 + Add GHC 8.4 support (thanks @4e6 !).
diff --git a/hjsonschema.cabal b/hjsonschema.cabal
--- a/hjsonschema.cabal
+++ b/hjsonschema.cabal
@@ -1,5 +1,5 @@
 name:               hjsonschema
-version:            1.9.0
+version:            1.10.0
 synopsis:           JSON Schema library
 homepage:           https://github.com/seagreen/hjsonschema
 license:            MIT
@@ -80,6 +80,51 @@
     , unordered-containers >= 0.2
     , text                 >= 1.1
     , vector               >= 0.10
+
+test-suite spec
+  hs-source-dirs:
+    test
+    src
+  main-is: Spec.hs
+  type: exitcode-stdio-1.0
+  default-language: Haskell2010
+  ghc-options:
+    -Wall
+  default-extensions:
+    DeriveGeneric
+    NoImplicitPrelude
+    OverloadedStrings
+    ScopedTypeVariables
+  other-modules:
+      Import
+      JSONSchema.Validator.Draft4.String
+
+      JSONSchema.Validator.Draft4.StringSpec
+  build-depends:
+      base                 >= 4.7 && < 5
+    -- 0.11 is for `.:!`:
+    , aeson                >= 0.11
+    , bytestring           >= 0.10
+    , containers           >= 0.5
+    , file-embed           >= 0.0.8
+    , filepath             >= 1.3
+    , hashable             >= 1.2
+    , hjsonpointer         >= 1.1
+    -- 0.4.30 is for parseUrlThrow:
+    , http-client          >= 0.4.30
+    , http-client-tls      >= 0.3
+    , http-types           >= 0.8
+    , pcre-heavy           >= 1.0
+    , profunctors          >= 5.0
+    , protolude            >= 0.1.10
+    , QuickCheck           >= 2.8
+    , safe-exceptions      >= 0.1.6
+    , scientific           >= 0.3
+    , unordered-containers >= 0.2
+    , text                 >= 1.1
+    , vector               >= 0.10
+
+    , hspec                >= 2.2
 
 test-suite local
   hs-source-dirs:
diff --git a/src/JSONSchema/Validator/Draft4/String.hs b/src/JSONSchema/Validator/Draft4/String.hs
--- a/src/JSONSchema/Validator/Draft4/String.hs
+++ b/src/JSONSchema/Validator/Draft4/String.hs
@@ -22,10 +22,8 @@
     = MaxLengthInvalid MaxLength Text
     deriving (Eq, Show)
 
--- | The spec requires @"maxLength"@ to be non-negative.
 maxLengthVal :: MaxLength -> Text -> Maybe MaxLengthInvalid
 maxLengthVal a@(MaxLength n) x
-    | n <= 0         = Nothing
     | T.length x > n = Just (MaxLengthInvalid a x)
     | otherwise      = Nothing
 
@@ -45,10 +43,8 @@
     = MinLengthInvalid MinLength Text
     deriving (Eq, Show)
 
--- | The spec requires @"minLength"@ to be non-negative.
 minLengthVal :: MinLength -> Text -> Maybe MinLengthInvalid
 minLengthVal a@(MinLength n) x
-    | n <= 0         = Nothing
     | T.length x < n = Just (MinLengthInvalid a x)
     | otherwise      = Nothing
 
@@ -73,6 +69,8 @@
 patternVal a@(PatternValidator t) x =
     case RE.compileM (encodeUtf8 t) mempty of
         Left _   -> Just PatternNotRegex
-        Right re -> if x RE.=~ re
+        Right re -> if input RE.=~ re
                         then Nothing
                         else Just (PatternInvalid a x)
+  where
+    input = T.unpack x -- workaround for a bug in pcre-light
diff --git a/test/JSONSchema/Validator/Draft4/StringSpec.hs b/test/JSONSchema/Validator/Draft4/StringSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/JSONSchema/Validator/Draft4/StringSpec.hs
@@ -0,0 +1,25 @@
+module JSONSchema.Validator.Draft4.StringSpec (spec) where
+
+import           Protolude
+
+import           Test.Hspec
+
+import           JSONSchema.Validator.Draft4.String
+
+spec :: Spec
+spec = do
+    describe "maxLengthVal" $ do
+        context "with 0" $ do
+            it "accepts the empty string" $ do
+                maxLengthVal (MaxLength 0) "" `shouldBe` Nothing
+
+            it "rejects other strings" $ do
+                maxLengthVal (MaxLength 0) "foo" `shouldBe` Just (MaxLengthInvalid (MaxLength 0) "foo")
+
+    describe "patternVal" $ do
+        it "matches a substring" $ do
+            patternVal (PatternValidator "baz") "foo bar baz" `shouldBe` Nothing
+
+        context "with .*" $ do
+            it "matches the empty string (test for workaround for a bug in pcre-light)" $ do
+                patternVal (PatternValidator ".*") "" `shouldBe` Nothing
diff --git a/test/Local.hs b/test/Local.hs
--- a/test/Local.hs
+++ b/test/Local.hs
@@ -62,7 +62,7 @@
             Nothing -> expectationFailure "timeout expired"
             Just a  -> pure a
 
-    validate :: D4.Schema -> SchemaTestCase -> Expectation
+    validate :: HasCallStack => D4.Schema -> SchemaTestCase -> Expectation
     validate s sc = do
         res <- D4.fetchHTTPAndValidate (D4.SchemaWithURI s Nothing) (_scData sc)
         let failures = case res of
@@ -72,7 +72,7 @@
                                                        <> show other)
         assertResult sc failures
 
-    validateExample :: JT.Schema -> SchemaTestCase -> Expectation
+    validateExample :: HasCallStack => JT.Schema -> SchemaTestCase -> Expectation
     validateExample s sc = do
         res <- AlternateSchema.referencesViaHTTP (D4.SchemaWithURI s Nothing)
         case res of
diff --git a/test/Shared.hs b/test/Shared.hs
--- a/test/Shared.hs
+++ b/test/Shared.hs
@@ -14,7 +14,7 @@
 import           Test.Hspec
 
 skipTest :: FilePath -> Bool
-skipTest file = (file == "optional/format.json") -- Optional
+skipTest file = (file == "optional/format.json")
              || (file == "optional/zeroTerminatedFloats.json")
              || (file == "optional/ecmascript-regex.json")
 
@@ -109,12 +109,12 @@
                  Error e   -> panic ("Couldn't parse schema: " <> show e)
                  Success a -> a
 
-assertResult :: Show err => SchemaTestCase -> [err] -> Expectation
+assertResult :: (HasCallStack, Show err) => SchemaTestCase -> [err] -> Expectation
 assertResult sc failures
     | _scValid sc = assertValid sc failures
     | otherwise   = assertInvalid sc failures
 
-assertValid :: Show err => SchemaTestCase -> [err] -> Expectation
+assertValid :: (HasCallStack, Show err) => SchemaTestCase -> [err] -> Expectation
 assertValid _ [] = pure ()
 assertValid sc failures =
     expectationFailure $ unlines
@@ -124,7 +124,7 @@
         , "    Validation failures: " <> show failures
         ]
 
-assertInvalid :: SchemaTestCase -> [err] -> Expectation
+assertInvalid :: HasCallStack => SchemaTestCase -> [err] -> Expectation
 assertInvalid sc [] =
     expectationFailure $ unlines
         [ "    Validated invalid data"
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -fforce-recomp -F -pgmF hspec-discover #-}
