[
  {
    "Id": "430468",
    "ThreadId": "209184",
    "Html": "<p>Hi. I'd like to know if it's possible to and how to manipulate the extra fields on zip entries. Specifically, I need to make one have a length of 0.</p>\r\n<p>The situation:</p>\r\n<p>I'm writing an ePub creation tool for fun and personal use, and using DotNetZip to make the zip container. When I use the &quot;epubcheck&quot; validation tool, it always returns an error like &quot;extra field length for first filename must be 0, but was 36&quot;. This 'first file' is some special file called &quot;mimetype&quot; containing the mime-type data for epub. The code that (likely) produces this error message in the epubcheck tool is (particularly important parts in bold):</p>\r\n<p>&nbsp;</p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>FileInputStream epubIn = <span style=\"color:Blue\">new</span> FileInputStream(epubFile);<br><br><span style=\"color:Blue\">byte</span>[] header = <span style=\"color:Blue\">new</span> <span style=\"color:Blue\">byte</span>[58];<br><br><span style=\"color:Blue\">if</span> (epubIn.read(header) != header.length) {<br>report.error(<span style=\"color:Blue\">null</span>, 0, <span style=\"color:#A31515\">&quot;cannot read header&quot;</span>);<br>} <span style=\"color:Blue\">else</span> {<br><br>  <span style=\"color:Blue\">int</span> fnsize = getIntFromBytes(header, 26);<br>  <strong><span style=\"color:Blue\">int</span> extsize = getIntFromBytes(header, 28);</strong><br><br>  <span style=\"color:Blue\">if</span> (header[0] != <span style=\"color:#A31515\">'P'</span> &amp;&amp; header[1] != <span style=\"color:#A31515\">'K'</span>) {<br>    report.error(<span style=\"color:Blue\">null</span>, 0, <span style=\"color:#A31515\">&quot;corrupted ZIP header&quot;</span>);<br>  } <span style=\"color:Blue\">else</span> <span style=\"color:Blue\">if</span> (fnsize != 8) {<br>    report.error(<span style=\"color:Blue\">null</span>, 0, <span style=\"color:#A31515\">&quot;length of first filename in archive must be 8, but was &quot;</span> + fnsize);<br><br>  } <strong><span style=\"color:Blue\">else</span> <span style=\"color:Blue\">if</span> (extsize != 0) {<br>    report.error(<span style=\"color:Blue\">null</span>, 0,<span style=\"color:#A31515\">&quot;extra field length for first filename must be 0, but was &quot;</span> + extsize);<br></strong><br>  } <span style=\"color:Blue\">else</span> <span style=\"color:Blue\">if</span> (!CheckUtil.checkString(header, 30, <span style=\"color:#A31515\">&quot;mimetype&quot;</span>)) {<br>    report.error(<span style=\"color:Blue\">null</span>, 0, <span style=\"color:#A31515\">&quot;mimetype entry missing or not the first in archive&quot;</span>);<br><br>  } <span style=\"color:Blue\">else</span> <span style=\"color:Blue\">if</span> (!CheckUtil.checkString(header, 38, <span style=\"color:#A31515\">&quot;application/epub+zip&quot;</span>)) {<br>    report.error(<span style=\"color:Blue\">null</span>, 0, <span style=\"color:#A31515\">&quot;mimetype contains wrong type (application/epub+zip expected)&quot;</span>);<br><br>  }<br>}<br></pre>\r\n</div>\r\n<p>&nbsp;</p>\r\n<p>The code I use to write the zip file is:</p>\r\n<p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>ZipFile output = <span style=\"color:Blue\">new</span> ZipFile(Encoding.UTF8); <span style=\"color:Green\">//use utf-8 file names</span>\r\noutput.UseUnicodeAsNecessary = <span style=\"color:Blue\">true</span>; <span style=\"color:Green\">//ensure the file names use unicode names?</span>\r\noutput.Encryption = EncryptionAlgorithm.None; <span style=\"color:Green\">//the file cannot be encrypted</span>\r\noutput.CompressionLevel = CompressionLevel.None; <span style=\"color:Green\">//the file cannot be compressed</span>\r\noutput.AddEntry(<span style=\"color:#A31515\">&quot;mimetype&quot;</span>, data.Mimetype, Encoding.ASCII); <span style=\"color:Green\">//file in ascii(ansi) encoding</span>\r\n</pre>\r\n</div>\r\n</p>\r\n<p>Any hits or suggestions? Thank you.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-13T07:25:27.5-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "430527",
    "ThreadId": "209184",
    "Html": "<p>yes, you can work around this.</p>\r\n<p>The &quot;extra field&quot; in&nbsp;a zip entry contains high-resolution timestamp information, potentially encryption information, other stuff.&nbsp;&nbsp;</p>\r\n<p>By default DotNetZip produces zip files that include NTFS timestamp information in that extra field.&nbsp; The size of that time information is 36 bytes: a 4 byte signature followed by 12 bytes each for the created, modified, and accessed times for the file.&nbsp;&nbsp;To exclude that timestamp you can set <strong>ZipFile.EmitTimesInWindowsFormatWhenSaving</strong> to false, in the same way (and right after) you set UseUnicodeAsNecessary to true. You will still get the low-resolution timestamp on the zip entry.&nbsp; This should give you an &quot;extra field&quot; of zero bytes in length.</p>\r\n<p>ps: it seems unnecessarily rigid for ePub to require that the extra field length for the entry be zero.&nbsp; The extra field is optional, it need not be handled by the reading application.&nbsp; If the app doesn't want or need the extra field, it can ignore it.&nbsp; No need to report an error.&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-13T09:11:33.713-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "430697",
    "ThreadId": "209184",
    "Html": "<p>Thank you so much! I can finally output a &quot;valid&quot; (according to  epubcheck) epub.</p>\r\n<blockquote style=\"border:solid .1em #ccc;font-style:italic;margin:.25em 1em 0 1em;padding:0 .25em 0 .25em\"><strong>Cheeso wrote:</strong><br>\r\n<p>ps: it seems unnecessarily rigid for ePub to require that the extra field length for the entry be zero.&nbsp; The extra field is optional, it need not be handled by the reading application.&nbsp; If the app doesn't want or need the extra field, it can ignore it.&nbsp; No need to report an error.&nbsp;</p>\r\n</blockquote>\r\n<p>I agree that the requirements for the frankly useless &quot;mimetype&quot; file are overly strict and a bit difficult to follow. I'd imagine most reading systems skip it anyway. My Sony Reader read my &quot;invalid&quot; epub just fine. But... since you can never be sure who will enforce what, we have to try to pass the only 'validation' tool available for epub.</p>",
    "PostedDate": "2010-04-13T16:46:00.683-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "433736",
    "ThreadId": "209184",
    "Html": "<p>Glad it worked for you!</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-21T09:14:27.127-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "485721",
    "ThreadId": "209184",
    "Html": "<p>My thanks too!</p>\r\n<p>For what it's worth, the point behind this restriction is that the mime type is at an exact binary offest from the start of the file.&nbsp; This makes it easier for low powered devices to check what sort of file it is and so on.&nbsp; However, I do agree that this seems overkill these days.</p>\r\n<p>Now for the rest of the errors :(</p>\r\n<p>Iain</p>",
    "PostedDate": "2010-08-27T08:46:12.183-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]