From acb219fbe1524b1cd69a19b55d3503da99e06466 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 2 Nov 2015 23:46:57 +0000 Subject: [PATCH] fixes sonar/findbugs issues add Date.toString() to forbidden-apis and fix occurrences git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1712181 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hpsf/TypedPropertyValue.java | 22 ++++---------- .../poi/ss/usermodel/DataFormatter.java | 20 +++++++++---- .../poi/POIXMLPropertiesTextExtractor.java | 24 +++++++++++---- .../devtools/forbidden-signatures.txt | 3 +- .../poi/hmef/attribute/MAPIDateAttribute.java | 17 +++++++++-- .../poi/hmef/attribute/TNEFDateAttribute.java | 29 ++++++++++++------- .../hwpf/sprm/CharacterSprmUncompressor.java | 2 +- .../apache/poi/hssf/usermodel/TestBugs.java | 2 ++ 8 files changed, 76 insertions(+), 43 deletions(-) diff --git a/src/java/org/apache/poi/hpsf/TypedPropertyValue.java b/src/java/org/apache/poi/hpsf/TypedPropertyValue.java index 43ac27aeb..3093a10af 100644 --- a/src/java/org/apache/poi/hpsf/TypedPropertyValue.java +++ b/src/java/org/apache/poi/hpsf/TypedPropertyValue.java @@ -73,7 +73,7 @@ class TypedPropertyValue return offset - startOffset; } - int readValue( byte[] data, int offset ) + int readValue( byte[] data, int offset ) // NOSONAR { switch ( _type ) { @@ -82,18 +82,16 @@ class TypedPropertyValue _value = null; return 0; + case Variant.VT_R4: case Variant.VT_I2: _value = Short.valueOf( LittleEndian.getShort( data, offset ) ); return 4; + case Variant.VT_INT: case Variant.VT_I4: _value = Integer.valueOf( LittleEndian.getInt( data, offset ) ); return 4; - case Variant.VT_R4: - _value = Short.valueOf( LittleEndian.getShort( data, offset ) ); - return 4; - case Variant.VT_R8: _value = Double.valueOf( LittleEndian.getDouble( data, offset ) ); return 8; @@ -110,10 +108,6 @@ class TypedPropertyValue _value = new CodePageString( data, offset ); return ( (CodePageString) _value ).getSize(); - case Variant.VT_ERROR: - _value = Long.valueOf( LittleEndian.getUInt( data, offset ) ); - return 4; - case Variant.VT_BOOL: _value = new VariantBool( data, offset ); return VariantBool.SIZE; @@ -134,7 +128,9 @@ class TypedPropertyValue _value = Integer.valueOf( LittleEndian.getUShort( data, offset ) ); return 4; + case Variant.VT_UINT: case Variant.VT_UI4: + case Variant.VT_ERROR: _value = Long.valueOf( LittleEndian.getUInt( data, offset ) ); return 4; @@ -146,14 +142,6 @@ class TypedPropertyValue _value = LittleEndian.getByteArray( data, offset, 8 ); return 8; - case Variant.VT_INT: - _value = Integer.valueOf( LittleEndian.getInt( data, offset ) ); - return 4; - - case Variant.VT_UINT: - _value = Long.valueOf( LittleEndian.getUInt( data, offset ) ); - return 4; - case Variant.VT_LPSTR: _value = new CodePageString( data, offset ); return ( (CodePageString) _value ).getSize(); diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index a6a53d04f..5ab2478ee 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -22,12 +22,14 @@ package org.apache.poi.ss.usermodel; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.FieldPosition; import java.text.Format; import java.text.ParsePosition; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -107,7 +109,7 @@ import org.apache.poi.util.POILogger; * Excel will output "", DataFormatter will output "0". * *

- * Some formats are automatically "localised" by Excel, eg show as mm/dd/yyyy when + * Some formats are automatically "localized" by Excel, eg show as mm/dd/yyyy when * loaded in Excel in some Locales but as dd/mm/yyyy in others. These are always * returned in the "default" (US) format, as stored in the file. * Some format strings request an alternate locale, eg @@ -176,6 +178,11 @@ public class DataFormatter implements Observer { */ private DateFormatSymbols dateSymbols; + /** + * A default date format, if no date format was given + */ + private DateFormat defaultDateformat; + /** General format for numbers. */ private Format generalNumberFormat; @@ -690,10 +697,7 @@ public class DataFormatter implements Observer { * supplied Date and format */ private String performDateFormatting(Date d, Format dateFormat) { - if(dateFormat != null) { - return dateFormat.format(d); - } - return d.toString(); + return (dateFormat != null ? dateFormat : defaultDateformat).format(d); } /** @@ -945,7 +949,7 @@ public class DataFormatter implements Observer { * To notify callers, the returned {@link Observable} should be used. * The Object in {@link Observer#update(Observable, Object)} is the new Locale. * - * @return the listener object, where callers can register themself + * @return the listener object, where callers can register themselves */ public Observable getLocaleChangedObservable() { return localeChangedObervable; @@ -968,6 +972,10 @@ public class DataFormatter implements Observer { decimalSymbols = DecimalFormatSymbols.getInstance(locale); generalNumberFormat = new ExcelGeneralNumberFormat(locale); + // taken from Date.toString() + defaultDateformat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dateSymbols); + defaultDateformat.setTimeZone(LocaleUtil.getUserTimeZone()); + // init built-in formats formats.clear(); diff --git a/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java b/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java index 8a35a34e4..9fd34914f 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java +++ b/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java @@ -18,9 +18,14 @@ package org.apache.poi; import java.math.BigDecimal; +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; +import org.apache.poi.util.LocaleUtil; import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; /** @@ -29,20 +34,27 @@ import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProper * and title. */ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { + + private final DateFormat dateFormat; + /** * Creates a new POIXMLPropertiesTextExtractor for the * given open document. */ public POIXMLPropertiesTextExtractor(POIXMLDocument doc) { super(doc); + DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); + dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); + dateFormat.setTimeZone(LocaleUtil.TIMEZONE_UTC); } + /** * Creates a new POIXMLPropertiesTextExtractor, for the * same file that another TextExtractor is already * working on. */ public POIXMLPropertiesTextExtractor(POIXMLTextExtractor otherExtractor) { - super(otherExtractor.getDocument()); + this(otherExtractor.getDocument()); } private void appendIfPresent(StringBuffer text, String thing, boolean value) { @@ -53,7 +65,7 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { } private void appendIfPresent(StringBuffer text, String thing, Date value) { if(value == null) { return; } - appendIfPresent(text, thing, value.toString()); + appendIfPresent(text, thing, dateFormat.format(value)); } private void appendIfPresent(StringBuffer text, String thing, String value) { if(value == null) { return; } @@ -66,7 +78,8 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { /** * Returns the core document properties, eg author */ - public String getCorePropertiesText() { + @SuppressWarnings("resource") + public String getCorePropertiesText() { POIXMLDocument document = getDocument(); if(document == null) { // event based extractor does not have a document return ""; @@ -103,7 +116,8 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { * Returns the extended document properties, eg * application */ - public String getExtendedPropertiesText() { + @SuppressWarnings("resource") + public String getExtendedPropertiesText() { POIXMLDocument document = getDocument(); if(document == null) { // event based extractor does not have a document return ""; @@ -135,7 +149,7 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { * Returns the custom document properties, if * there are any */ - @SuppressWarnings("deprecation") + @SuppressWarnings({ "deprecation", "resource" }) public String getCustomPropertiesText() { POIXMLDocument document = getDocument(); if(document == null) { // event based extractor does not have a document diff --git a/src/resources/devtools/forbidden-signatures.txt b/src/resources/devtools/forbidden-signatures.txt index de6afc337..e002a1a17 100644 --- a/src/resources/devtools/forbidden-signatures.txt +++ b/src/resources/devtools/forbidden-signatures.txt @@ -22,4 +22,5 @@ java.util.Locale#getDefault() java.util.Locale#setDefault(java.util.Locale) -java.util.TimeZone#getDefault() \ No newline at end of file +java.util.TimeZone#getDefault() +java.util.Date#toString() \ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIDateAttribute.java b/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIDateAttribute.java index 243359639..53eb575e6 100644 --- a/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIDateAttribute.java +++ b/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIDateAttribute.java @@ -17,19 +17,29 @@ package org.apache.poi.hmef.attribute; +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; import org.apache.poi.hmef.Attachment; import org.apache.poi.hmef.HMEFMessage; import org.apache.poi.hpsf.Util; import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; /** * A pure-MAPI attribute holding a Date, which applies - * to a {@link HMEFMessage} or one of its {@link Attachment}s. + * to a {@link HMEFMessage} or one of its {@link Attachment}s. + * + * Timestamps are usually given in UTC. + * + * @see [MS-OXOMSG]: Email Object Protocol + * @see [MS-OXPROPS]: Exchange Server Protocols Master Property List */ public final class MAPIDateAttribute extends MAPIAttribute { private static POILogger logger = POILogFactory.getLogger(MAPIDateAttribute.class); @@ -53,7 +63,10 @@ public final class MAPIDateAttribute extends MAPIAttribute { } public String toString() { - return getProperty().toString() + " " + data.toString(); + DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); + DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); + return getProperty().toString() + " " + df.format(data); } /** diff --git a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java index 4616b46d7..1df0d9691 100644 --- a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java +++ b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java @@ -19,8 +19,12 @@ package org.apache.poi.hmef.attribute; import java.io.IOException; import java.io.InputStream; +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import org.apache.poi.hmef.Attachment; import org.apache.poi.hmef.HMEFMessage; @@ -45,26 +49,26 @@ public final class TNEFDateAttribute extends TNEFAttribute { protected TNEFDateAttribute(int id, int type, InputStream inp) throws IOException { super(id, type, inp); - byte[] data = getData(); - if(data.length == 8) { + byte[] binData = getData(); + if(binData.length == 8) { // The value is a 64 bit Windows Filetime this.data = Util.filetimeToDate( LittleEndian.getLong(getData(), 0) ); - } else if(data.length == 14) { + } else if(binData.length == 14) { // It's the 7 date fields. We think it's in UTC... Calendar c = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); - c.set(Calendar.YEAR, LittleEndian.getUShort(data, 0)); - c.set(Calendar.MONTH, LittleEndian.getUShort(data, 2) - 1); // Java months are 0 based! - c.set(Calendar.DAY_OF_MONTH, LittleEndian.getUShort(data, 4)); - c.set(Calendar.HOUR_OF_DAY, LittleEndian.getUShort(data, 6)); - c.set(Calendar.MINUTE, LittleEndian.getUShort(data, 8)); - c.set(Calendar.SECOND, LittleEndian.getUShort(data, 10)); + c.set(Calendar.YEAR, LittleEndian.getUShort(binData, 0)); + c.set(Calendar.MONTH, LittleEndian.getUShort(binData, 2) - 1); // Java months are 0 based! + c.set(Calendar.DAY_OF_MONTH, LittleEndian.getUShort(binData, 4)); + c.set(Calendar.HOUR_OF_DAY, LittleEndian.getUShort(binData, 6)); + c.set(Calendar.MINUTE, LittleEndian.getUShort(binData, 8)); + c.set(Calendar.SECOND, LittleEndian.getUShort(binData, 10)); // The 7th field is day of week, which we don't require c.clear(Calendar.MILLISECOND); // Not set in the file this.data = c.getTime(); } else { - throw new IllegalArgumentException("Invalid date, found " + data.length + " bytes"); + throw new IllegalArgumentException("Invalid date, found " + binData.length + " bytes"); } } @@ -73,8 +77,11 @@ public final class TNEFDateAttribute extends TNEFAttribute { } public String toString() { + DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); + DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); return "Attribute " + getProperty().toString() + ", type=" + getType() + - ", date=" + data.toString(); + ", date=" + df.format(data); } /** diff --git a/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java b/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java index 644e8a31a..e382ffe09 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java @@ -394,7 +394,7 @@ public final class CharacterSprmUncompressor extends SprmUncompressor newCHP.setHpsPos (hpsPos); } boolean fAdjust = (operand & 0x0100) > 0; - if (fAdjust && hpsPos != 128 && hpsPos != 0 && oldCHP.getHpsPos () == 0) + if (fAdjust && (hpsPos & 0xFF) != 128 && hpsPos != 0 && oldCHP.getHpsPos () == 0) { newCHP.setHps (Math.max (newCHP.getHps () + ( -2), 2)); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index b62cae1ef..30f634319 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -2949,6 +2949,8 @@ public final class TestBugs extends BaseTestBugzillaIssues { } catch (IOException e) { Assume.assumeNoException("Downloading a jpg from poi.apache.org should work", e); return; + } finally { + wb.close(); } // Convert BufferedImage to byte[]