You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2016/11/25 08:55:53 UTC

svn commit: r1771254 - in /poi/trunk/src: java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ ooxml/java/org/apache/poi/xssf/usermodel/ testcases/org/apache/poi/ss/usermodel/

Author: centic
Date: Fri Nov 25 08:55:52 2016
New Revision: 1771254

URL: http://svn.apache.org/viewvc?rev=1771254&view=rev
Log:
Bug 59200: Check for actual Excel limits on data validation title/text

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java
    poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java?rev=1771254&r1=1771253&r2=1771254&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java Fri Nov 25 08:55:52 2016
@@ -42,13 +42,13 @@ public final class DVRecord extends Stan
 
 	/** Option flags */
 	private int _option_flags;
-	/** Title of the prompt box */
+	/** Title of the prompt box, cannot be longer than 32 chars */
 	private UnicodeString _promptTitle;
-	/** Title of the error box */
+	/** Title of the error box, cannot be longer than 32 chars */
 	private UnicodeString _errorTitle;
-	/** Text of the prompt box */
+	/** Text of the prompt box, cannot be longer than 255 chars */
 	private UnicodeString _promptText;
-	/** Text of the error box */
+	/** Text of the error box, cannot be longer than 255 chars */
 	private UnicodeString _errorText;
 	/** Not used - Excel seems to always write 0x3FE0 */
 	private short _not_used_1 = 0x3FE0;
@@ -82,6 +82,21 @@ public final class DVRecord extends Stan
 			Ptg[] formula1, Ptg[] formula2,
 			CellRangeAddressList regions) {
 		
+		// check length-limits
+		if(promptTitle != null && promptTitle.length() > 32) {
+			throw new IllegalStateException("Prompt-title cannot be longer than 32 characters, but had: " + promptTitle);
+		}
+		if(promptText != null && promptText.length() > 255) {
+			throw new IllegalStateException("Prompt-text cannot be longer than 255 characters, but had: " + promptText);
+		}
+
+		if(errorTitle != null && errorTitle.length() > 32) {
+			throw new IllegalStateException("Error-title cannot be longer than 32 characters, but had: " + errorTitle);
+		}
+		if(errorText != null && errorText.length() > 255) {
+			throw new IllegalStateException("Error-text cannot be longer than 255 characters, but had: " + errorText);
+		}
+
 		int flags = 0;
 		flags = opt_data_type.setValue(flags, validationType);
 		flags = opt_condition_operator.setValue(flags, operator);
@@ -267,8 +282,8 @@ public final class DVRecord extends Stan
 		}
 		Ptg[] ptgs = f.getTokens();
 		sb.append('\n');
-		for (int i = 0; i < ptgs.length; i++) {
-			sb.append('\t').append(ptgs[i].toString()).append('\n');
+		for (Ptg ptg : ptgs) {
+			sb.append('\t').append(ptg.toString()).append('\n');
 		}
 	}
 

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java?rev=1771254&r1=1771253&r2=1771254&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java Fri Nov 25 08:55:52 2016
@@ -44,7 +44,9 @@ public final class HSSFDataValidation im
 	/**
 	 * Constructor which initializes the cell range on which this object will be
 	 * applied
-	 * @param constraint 
+	 *
+	 * @param regions A list of regions where the constraint is validated.
+	 * @param constraint The constraints to apply for this validation.
 	 */
 	public HSSFDataValidation(CellRangeAddressList regions, DataValidationConstraint constraint) {
 		_regions = regions;
@@ -109,6 +111,7 @@ public final class HSSFDataValidation im
 	 * @see org.apache.poi.hssf.usermodel.DataValidation#getSuppressDropDownArrow()
 	 */
 	public boolean getSuppressDropDownArrow() {
+		//noinspection SimplifiableIfStatement
 		if (_constraint.getValidationType()==ValidationType.LIST) {
 			return _suppress_dropdown_arrow;
 		}
@@ -148,6 +151,13 @@ public final class HSSFDataValidation im
 	 * @see org.apache.poi.hssf.usermodel.DataValidation#createPromptBox(java.lang.String, java.lang.String)
 	 */
 	public void createPromptBox(String title, String text) {
+		// check length-limits
+		if(title != null && title.length() > 32) {
+			throw new IllegalStateException("Prompt-title cannot be longer than 32 characters, but had: " + title);
+		}
+		if(text != null && text.length() > 255) {
+			throw new IllegalStateException("Prompt-text cannot be longer than 255 characters, but had: " + text);
+		}
 		_prompt_title = title;
 		_prompt_text = text;
 		this.setShowPromptBox(true);
@@ -171,6 +181,12 @@ public final class HSSFDataValidation im
 	 * @see org.apache.poi.hssf.usermodel.DataValidation#createErrorBox(java.lang.String, java.lang.String)
 	 */
 	public void createErrorBox(String title, String text) {
+		if(title != null && title.length() > 32) {
+			throw new IllegalStateException("Error-title cannot be longer than 32 characters, but had: " + title);
+		}
+		if(text != null && text.length() > 255) {
+			throw new IllegalStateException("Error-text cannot be longer than 255 characters, but had: " + text);
+		}
 		_error_title = title;
 		_error_text = text;
 		this.setShowErrorBox(true);

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java?rev=1771254&r1=1771253&r2=1771254&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java Fri Nov 25 08:55:52 2016
@@ -103,6 +103,13 @@ public class XSSFDataValidation implemen
 	 * @see org.apache.poi.ss.usermodel.DataValidation#createErrorBox(java.lang.String, java.lang.String)
 	 */
 	public void createErrorBox(String title, String text) {
+		// the spec does not specify a length-limit, however Excel reports files as "corrupt" if they exceed 255 bytes for these texts...
+		if(title != null && title.length() > 255) {
+			throw new IllegalStateException("Error-title cannot be longer than 32 characters, but had: " + title);
+		}
+		if(text != null && text.length() > 255) {
+			throw new IllegalStateException("Error-text cannot be longer than 255 characters, but had: " + text);
+		}
 		ctDdataValidation.setErrorTitle(title);
 		ctDdataValidation.setError(text);
 	}
@@ -111,6 +118,13 @@ public class XSSFDataValidation implemen
 	 * @see org.apache.poi.ss.usermodel.DataValidation#createPromptBox(java.lang.String, java.lang.String)
 	 */
 	public void createPromptBox(String title, String text) {
+		// the spec does not specify a length-limit, however Excel reports files as "corrupt" if they exceed 255 bytes for these texts...
+		if(title != null && title.length() > 255) {
+			throw new IllegalStateException("Error-title cannot be longer than 32 characters, but had: " + title);
+		}
+		if(text != null && text.length() > 255) {
+			throw new IllegalStateException("Error-text cannot be longer than 255 characters, but had: " + text);
+		}
 		ctDdataValidation.setPromptTitle(title);
 		ctDdataValidation.setPrompt(text);
 	}
@@ -237,14 +251,12 @@ public class XSSFDataValidation implemen
 	}
 	
     private static XSSFDataValidationConstraint getConstraint(CTDataValidation ctDataValidation) {
-    	XSSFDataValidationConstraint constraint = null;
     	String formula1 = ctDataValidation.getFormula1();
     	String formula2 = ctDataValidation.getFormula2();
     	Enum operator = ctDataValidation.getOperator();
     	org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType.Enum type = ctDataValidation.getType();
 		Integer validationType = XSSFDataValidation.validationTypeReverseMappings.get(type);
 		Integer operatorType = XSSFDataValidation.operatorTypeReverseMappings.get(operator);
-		constraint = new XSSFDataValidationConstraint(validationType,operatorType, formula1,formula2);
-    	return constraint;
+		return new XSSFDataValidationConstraint(validationType,operatorType, formula1,formula2);
     }
 }

Modified: poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java?rev=1771254&r1=1771253&r2=1771254&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java Fri Nov 25 08:55:52 2016
@@ -21,6 +21,7 @@ import org.apache.poi.hssf.usermodel.HSS
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.ss.util.PaneInformation;
 import org.apache.poi.ss.util.SheetUtil;
 import org.apache.poi.util.POILogFactory;
@@ -36,6 +37,7 @@ import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.text.AttributedString;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import static org.junit.Assert.*;
@@ -46,9 +48,12 @@ import static org.junit.Assert.*;
  * @author Yegor Kozlov
  */
 public abstract class BaseTestBugzillaIssues {
-    
     private static final POILogger logger = POILogFactory.getLogger(BaseTestBugzillaIssues.class);
 
+    private static final String TEST_32 = "Some text with 32 characters to ";
+    private static final String TEST_255 = "Some very long text that is exactly 255 characters, which are allowed here, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla.....";
+    private static final String TEST_256 = "Some very long text that is longer than the 255 characters allowed in HSSF here, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla bla, bla1";
+
     private final ITestDataProvider _testDataProvider;
 
     protected BaseTestBugzillaIssues(ITestDataProvider testDataProvider) {
@@ -477,7 +482,7 @@ public abstract class BaseTestBugzillaIs
         String txt = lines[0] + "0";
 
         AttributedString str = new AttributedString(txt);
-        copyAttributes(font, str, 0, txt.length());
+        copyAttributes(font, str, txt.length());
 
         // TODO: support rich text fragments
         /*if (rt.numFormattingRuns() > 0) {
@@ -496,18 +501,18 @@ public abstract class BaseTestBugzillaIs
     private double computeCellWidthFixed(Font font, String txt) {
         final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);
         AttributedString str = new AttributedString(txt);
-        copyAttributes(font, str, 0, txt.length());
+        copyAttributes(font, str, txt.length());
 
         TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
         return getFrameWidth(layout);
     }
 
-    private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) {
-        str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
+    private static void copyAttributes(Font font, AttributedString str, int endIdx) {
+        str.addAttribute(TextAttribute.FAMILY, font.getFontName(), 0, endIdx);
         str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
-        if (font.getBoldweight() == Font.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
-        if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
-        if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
+        if (font.getBold()) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 0, endIdx);
+        if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, 0, endIdx);
+        if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 0, endIdx);
     }
 
     /**
@@ -1020,6 +1025,7 @@ public abstract class BaseTestBugzillaIs
         wb.close();
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void bug56981() throws IOException {
         Workbook wb = _testDataProvider.createWorkbook();
@@ -1095,7 +1101,7 @@ public abstract class BaseTestBugzillaIs
         Font font = wb.createFont();
         font.setFontName("Arial");
         font.setFontHeightInPoints((short)14);
-        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
+        font.setBold(true);
         font.setColor(IndexedColors.RED.getIndex());
         str2.applyFont(font);
 
@@ -1276,6 +1282,7 @@ public abstract class BaseTestBugzillaIs
         wb2.close();
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void bug58260() throws IOException {
         //Create workbook and worksheet
@@ -1779,4 +1786,61 @@ public abstract class BaseTestBugzillaIs
         
         wb.close();
     }
+
+    @Test
+    public void test59200() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        final Sheet sheet = wb.createSheet();
+
+        DataValidation dataValidation;
+        CellRangeAddressList headerCell = new CellRangeAddressList(0, 1, 0, 1);
+        DataValidationConstraint constraint = sheet.getDataValidationHelper().createCustomConstraint("A1<>\"\"");
+
+        dataValidation = sheet.getDataValidationHelper().createValidation(constraint, headerCell);
+
+        // HSSF has 32/255 limits as part of the Spec, XSSF has no limit in the spec, but Excel applies a 255 length limit!
+        // more than 255 fail for all
+        checkFailures(dataValidation, TEST_256, TEST_32, true);
+        checkFailures(dataValidation, TEST_32, TEST_256, true);
+        // more than 32 title fail for HSSFWorkbook
+        checkFailures(dataValidation, TEST_255, TEST_32, wb instanceof HSSFWorkbook);
+        // 32 length title and 255 length text wrok for both
+        checkFailures(dataValidation, TEST_32, TEST_255, false);
+
+        dataValidation.setShowErrorBox(false);
+        sheet.addValidationData(dataValidation);
+
+        // write out and read back in to trigger some more validation
+        final Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb);
+
+        final Sheet sheetBack = wbBack.getSheetAt(0);
+        final List<? extends DataValidation> dataValidations = sheetBack.getDataValidations();
+        assertEquals(1, dataValidations.size());
+
+        /*String ext = (wb instanceof HSSFWorkbook) ? ".xls" : ".xlsx";
+        OutputStream str = new FileOutputStream("C:\\temp\\59200" + ext);
+        try {
+            wb.write(str);
+        } finally {
+            str.close();
+        }*/
+
+        wb.close();
+    }
+
+    private void checkFailures(DataValidation dataValidation, String title, String text, boolean shouldFail) {
+        try {
+            dataValidation.createPromptBox(title, text);
+            assertFalse("Should fail in a length-check, had " + title.length() + " and " + text.length(), shouldFail);
+        } catch (IllegalStateException e) {
+            assertTrue("Should not fail in a length-check, had " + title.length() + " and " + text.length(), shouldFail);
+            // expected here
+        }
+        try {
+            dataValidation.createErrorBox(title, text);
+            assertFalse("Should fail in a length-check, had " + title.length() + " and " + text.length(), shouldFail);
+        } catch (IllegalStateException e) {
+            assertTrue("Should not fail in a length-check, had " + title.length() + " and " + text.length(), shouldFail);
+        }
+    }
 }
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org