Patch #1484695: The tarfile module now raises a HeaderError exception
if a buffer given to frombuf() is invalid.
diff --git a/Doc/lib/libtarfile.tex b/Doc/lib/libtarfile.tex
index ca6e65a..5f277da 100644
--- a/Doc/lib/libtarfile.tex
+++ b/Doc/lib/libtarfile.tex
@@ -124,6 +124,11 @@
     only if \member{TarFile.errorlevel}\code{ == 2}.
 \end{excdesc}
 
+\begin{excdesc}{HeaderError}
+    Is raised by \method{frombuf()} if the buffer it gets is invalid.
+    \versionadded{2.6}
+\end{excdesc}
+
 \begin{seealso}
     \seemodule{zipfile}{Documentation of the \refmodule{zipfile}
     standard module.}
@@ -332,6 +337,8 @@
 
 \begin{methoddesc}{frombuf}{}
     Create and return a \class{TarInfo} object from a string buffer.
+    \versionadded[Raises \exception{HeaderError} if the buffer is
+    invalid.]{2.6}
 \end{methoddesc}
 
 \begin{methoddesc}{tobuf}{posix}
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 1b8f140..00789f3 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -280,6 +280,9 @@
 class StreamError(TarError):
     """Exception for unsupported operations on stream-like TarFiles."""
     pass
+class HeaderError(TarError):
+    """Exception for invalid headers."""
+    pass
 
 #---------------------------
 # internal stream interface
@@ -819,9 +822,17 @@
         """Construct a TarInfo object from a 512 byte string buffer.
         """
         if len(buf) != BLOCKSIZE:
-            raise ValueError("truncated header")
+            raise HeaderError("truncated header")
         if buf.count(NUL) == BLOCKSIZE:
-            raise ValueError("empty header")
+            raise HeaderError("empty header")
+
+        try:
+            chksum = nti(buf[148:156])
+        except ValueError:
+            raise HeaderError("invalid header")
+
+        if chksum not in calc_chksums(buf):
+            raise HeaderError("bad checksum")
 
         tarinfo = cls()
         tarinfo.buf = buf
@@ -831,7 +842,7 @@
         tarinfo.gid = nti(buf[116:124])
         tarinfo.size = nti(buf[124:136])
         tarinfo.mtime = nti(buf[136:148])
-        tarinfo.chksum = nti(buf[148:156])
+        tarinfo.chksum = chksum
         tarinfo.type = buf[156:157]
         tarinfo.linkname = buf[157:257].rstrip(NUL)
         tarinfo.uname = buf[265:297].rstrip(NUL)
@@ -843,8 +854,6 @@
         if prefix and not tarinfo.issparse():
             tarinfo.name = prefix + "/" + tarinfo.name
 
-        if tarinfo.chksum not in calc_chksums(buf):
-            raise ValueError("invalid header")
         return tarinfo
 
     def tobuf(self, posix=False):
@@ -1793,16 +1802,14 @@
 
                 tarinfo = self.proc_member(tarinfo)
 
-            except ValueError, e:
+            except HeaderError, e:
                 if self.ignore_zeros:
-                    self._dbg(2, "0x%X: empty or invalid block: %s" %
-                              (self.offset, e))
+                    self._dbg(2, "0x%X: %s" % (self.offset, e))
                     self.offset += BLOCKSIZE
                     continue
                 else:
                     if self.offset == 0:
-                        raise ReadError("empty, unreadable or compressed "
-                                        "file: %s" % e)
+                        raise ReadError(str(e))
                     return None
             break
 
diff --git a/Misc/NEWS b/Misc/NEWS
index f166f71..a4eb6e2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -101,6 +101,9 @@
 Library
 -------
 
+- Patch #1484695: The tarfile module now raises a HeaderError exception
+  if a buffer given to frombuf() is invalid.
+
 - Bug #1503765: Fix a problem in logging.config with spaces in comma-
   separated lists read from logging config files.