diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,11 @@
+## 1.5.4
+
+* Fixing a bug due to misuse of memcpy(). (#8)
+
+## 1.5.3
+
+* Adding debug information.
+
 ## 1.5.2
 
 * Minor optimization for HPACK.
diff --git a/Network/HPACK/Buffer.hs b/Network/HPACK/Buffer.hs
--- a/Network/HPACK/Buffer.hs
+++ b/Network/HPACK/Buffer.hs
@@ -71,16 +71,34 @@
 
 {-# INLINE shiftLastN #-}
 shiftLastN :: WorkingBuffer -> Int -> Int -> IO ()
+shiftLastN WorkingBuffer{..} 0 _   = return ()
 shiftLastN WorkingBuffer{..} i len = do
     ptr <- readIORef offset
-    let !src = ptr `plusPtr` negate len
-        !dst = src `plusPtr` i
-        !ptr' = ptr `plusPtr` i
+    let !ptr' = ptr `plusPtr` i
     if ptr' >= limit then
         throwIO BufferOverrun
+      else if i < 0 then do
+        let !src = ptr `plusPtr` negate len
+            !dst = src `plusPtr` i
+        shiftLeft dst src len
+        writeIORef offset ptr'
       else do
-        memcpy dst src len
+        let !src = ptr `plusPtr` (-1)
+            !dst = ptr' `plusPtr` (-1)
+        shiftRight dst src len
         writeIORef offset ptr'
+  where
+    -- memcpy cannot be used for overlapped areas.
+    shiftLeft :: Buffer -> Buffer -> Int -> IO ()
+    shiftLeft _    _    0   = return ()
+    shiftLeft !dst !src n = do
+        peek src >>= poke dst
+        shiftLeft (dst `plusPtr` 1) (src `plusPtr` 1) (n - 1)
+    shiftRight :: Buffer -> Buffer -> Int -> IO ()
+    shiftRight _    _    0   = return ()
+    shiftRight !dst !src n = do
+        peek src >>= poke dst
+        shiftRight (dst `plusPtr` (-1)) (src `plusPtr` (-1)) (n - 1)
 
 {-# INLINE copyByteString #-}
 copyByteString :: WorkingBuffer -> ByteString -> IO ()
diff --git a/http2.cabal b/http2.cabal
--- a/http2.cabal
+++ b/http2.cabal
@@ -1,5 +1,5 @@
 Name:                   http2
-Version:                1.5.3
+Version:                1.5.4
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
diff --git a/test/HPACK/EncodeSpec.hs b/test/HPACK/EncodeSpec.hs
--- a/test/HPACK/EncodeSpec.hs
+++ b/test/HPACK/EncodeSpec.hs
@@ -37,7 +37,7 @@
 go _    _    _    []     _    = return True
 go etbl dtbl stgy (h:hs) lens = do
     bs <- encodeHeader stgy 4096 etbl h `E.catch` \(E.SomeException e) -> do
-        putStrLn $ "decodeHeader: " ++ show e
+        putStrLn $ "encodeHeader: " ++ show e
         print h
         E.throwIO e
     let lens' = case lens of
@@ -46,7 +46,7 @@
               | otherwise         -> error $ show h ++ "\nshould be " ++ show l
             []                    -> []
     h' <- decodeHeader dtbl bs  `E.catch` \(E.SomeException e) -> do
-        putStrLn $ "encodeHeader: " ++ show e
+        putStrLn $ "decodeHeader: " ++ show e
         print h
         E.throwIO e
     if h == h' then
