Monday, January 27, 2014

Some code just kills your day...

public void calculateFileSizeAndDigest(OutputStream os)
throws DigiDocException
{
if(m_logger.isDebugEnabled()){
m_logger.debug("calculateFileSizeAndDigest(" + getId() + ") body: " +
((m_body != null) ? "OK" : "NULL") + " base64: " + m_bodyIsBase64 +
" DF cache: " + ((m_fDfCache != null) ? m_fDfCache.getAbsolutePath() : "NULL"));
}
if(m_contentType.equals(CONTENT_BINARY)) {
byte[] digest = null;
try {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
String longFileName = m_fileName;
m_fileName = new File(m_fileName).getName();
FileInputStream fis = new FileInputStream(longFileName);
byte[] data = new byte[4096];
int nRead = 0;
long lSize = 0;
while((nRead = fis.read(data)) > 0) {
sha.update(data, 0, nRead);
lSize += nRead;
}
digest = sha.digest();
setSize(lSize);
} catch(Exception ex) {
m_logger.error("Error calculating bdoc digest: " + ex);
}
setDigest(digest);
if(m_logger.isDebugEnabled())
m_logger.debug("DataFile: \'" + getId() + "\' length: " +
getSize() + " digest: " + Base64Util.encode(digest));
return;
}
MessageDigest sha = null;
boolean bUse64ByteLines = true;
String use64Flag = ConfigManager.instance().getProperty("DATAFILE_USE_64BYTE_LINES");
if(use64Flag != null && use64Flag.equalsIgnoreCase("FALSE"))
bUse64ByteLines = false;
try {
sha = MessageDigest.getInstance("SHA-1"); // TODO: fix digest type
// if DataFile's digest has already been initialized
// and body in memory, e.g. has been read from digidoc
// then write directly to output stream and don't calculate again
if(m_origDigestValue != null && m_body != null && os != null) {
os.write(xmlHeader());
if(m_logger.isDebugEnabled())
m_logger.debug("write df header1: " + xmlHeader());
os.write(m_body);
os.write(xmlTrailer());
return;
}
String longFileName = m_fileName;
File fIn = new File(m_fileName);
FileInputStream fis = null;
m_fileName = fIn.getName();
if(fIn.canRead()) {
fis = new FileInputStream(longFileName);
if(m_logger.isDebugEnabled())
m_logger.debug("Read file: " + longFileName);
}
if(m_fDfCache != null) {
fis = new FileInputStream(m_fDfCache);
if(m_logger.isDebugEnabled())
m_logger.debug("Read cache: " + m_fDfCache);
}
byte[] tmp1=null,tmp2=null,tmp3=null;
ByteArrayOutputStream sbDig = new ByteArrayOutputStream();
sbDig.write(xmlHeader());
// add trailer and canonicalize
tmp3 = xmlTrailer();
sbDig.write(tmp3);
tmp1 = canonicalizeXml(sbDig.toByteArray());
// now remove the end tag again and calculate digest of the start tag only
tmp2 = new byte[tmp1.length - tmp3.length];
System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
sha.update(tmp2);
if(os != null) {
os.write(xmlHeader());
}
// reset the collecting buffer and other temp buffers
sbDig = new ByteArrayOutputStream();
tmp1 = tmp2 = tmp3 = null;
// content must be read from file
if(m_body == null) {
byte[] buf = new byte[block_size];
byte[] b64leftover = null;
int fRead = 0, b64left = 0;
ByteArrayOutputStream content = null;
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) {
// optimization for 64 char base64 lines
// convert to base64 online at a time to conserve memory
// VS: DF temp file base64 decoding fix
if(m_fDfCache == null) {
if(bUse64ByteLines)
b64leftover = new byte[65];
else
content = new ByteArrayOutputStream();
}
}
while((fRead = fis.read(buf)) > 0 || b64left > 0) { // read input file
if(m_logger.isDebugEnabled())
m_logger.debug("read: " + fRead + " bytes of input data");
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) {
// VS: DF temp file base64 decoding fix
if(m_fDfCache != null) {
if(os != null)
os.write(buf, 0, fRead);
sha.update(buf, 0, fRead);
} else {
if(bUse64ByteLines) { // 1 line base64 optimization
b64left = calculateAndWriteBase64Block(os, sha, b64leftover,
b64left, buf, fRead, fRead < block_size);
} else { // no optimization
content.write(buf, 0, fRead);
}
}
} else {
if(fRead < buf.length) {
tmp2= new byte[fRead];
System.arraycopy(buf, 0, tmp2, 0, fRead);
tmp1 = ConvertUtils.data2utf8(tmp2, m_codepage);
}
else
tmp1 = ConvertUtils.data2utf8(buf, m_codepage);
sbDig.write(tmp1);
}
if(m_logger.isDebugEnabled())
m_logger.debug("End using block: " + fRead + " in: " + ((fis != null) ? fis.available() : 0));
} // end reading input file
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) {
// VS: DF temp file base64 decoding fix
if(!bUse64ByteLines && m_fDfCache == null)
sbDig.write(Base64Util.encode(content.toByteArray(), 0).getBytes());
content = null;
}
if(m_logger.isDebugEnabled())
m_logger.debug("End reading content");
} else { // content allready in memeory
if(m_body != null) {
if(bUse64ByteLines && m_contentType.equals(CONTENT_EMBEDDED_BASE64) && !m_bodyIsBase64) {
calculateAndWriteBase64Block(os, sha, null, 0, m_body, m_body.length, true);
m_body = Base64Util.encode(m_body).getBytes();
} else {
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64) && !m_bodyIsBase64)
tmp1 = Base64Util.encode(m_body).getBytes();
else if(m_contentType.equals(CONTENT_EMBEDDED_BASE64) && m_bodyIsBase64)
tmp1 = ConvertUtils.data2utf8(m_body, m_codepage);
else
tmp1 = ConvertUtils.data2utf8(m_body, m_codepage);
sbDig.write(tmp1);
}
}
}
tmp1 = null;
if(fis != null)
fis.close();
// don't need to canonicalize base64 content !
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) {
// VS: DF temp file base64 decoding fix
if(!bUse64ByteLines && m_fDfCache == null) {
tmp2 = sbDig.toByteArray();
if(tmp2 != null && tmp2.length > 0) {
sha.update(tmp2);
if(os != null)
os.write(tmp2);
}
}
} else {
// canonicalize body
tmp2 = sbDig.toByteArray();
if(tmp2 != null && tmp2.length > 0) {
//System.out.println("Body: \"" + tmp2 + "\"");
if(tmp2[0] == '<')
tmp2 = canonicalizeXml(tmp2);
if(tmp2 != null && tmp2.length > 0) {
sha.update(tmp2); // crash
if(os != null)
os.write(tmp2);
}
}
}
tmp2 = null;
sbDig = null;
// trailer
tmp1 = xmlTrailer();
sha.update(tmp1);
if(os != null)
os.write(tmp1);
// now calculate the digest
byte[] digest = sha.digest();
setDigest(digest);
if(m_logger.isDebugEnabled())
m_logger.debug("DataFile: \'" + getId() + "\' length: " +
getSize() + " digest: " + Base64Util.encode(digest));
m_fileName = longFileName;
} catch(Exception ex) {
DigiDocException.handleException(ex, DigiDocException.ERR_READ_FILE);
}
}
view raw gistfile1.java hosted with ❤ by GitHub