Bug 43090

Summary: autoSizeColumn can calculate negative sizes for the column width due to a cast from integer to short
Product: POI Reporter: Jan Dostert <jan.dostert>
Component: HSSFAssignee: POI Developers List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 3.0-FINAL   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Jan Dostert 2007-08-10 09:21:46 UTC
Hi, 

autoSizeColumn can calculate negative sizes for the column width due to a cast
from integer to short.

If a column is long (e.g. 3000 characters), the calculated length of
autoSizeColumn does not fit into a short any more.

HSSFSheet.autoSizeColumn(short) line: 1476	

           if (width != -1) {
                sheet.setColumnWidth(column, (short) (width * 256));
            }

e.g. width = 1668.10  

width * 256 = 1668.10 * 256 = 427033,6

which is greater than 32767 which a short can hold. Due to the cast to short
only the lower two bytes are taken into account which results in -31718.

Thus, sheet.setColumnWidth is called with an argument of -31718 and sets the
width to a negative value.

Maybe a check like 

if (width > Short.MAX_VALUE) {
     width = Short.MAX_VALUE;
}

would already help.

Attached a small test case which reproduces the problem.

import java.io.FileOutputStream;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class AutoSizeColumn {

    public static void main(String args[]) throws Exception {

        HSSFWorkbook workBook = new HSSFWorkbook();
        HSSFSheet sheet = workBook.createSheet();
        
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell((short)0);

        int size = 3000;
        
        StringBuffer value = new StringBuffer(size);
        for (int i = 0; i < size; i++) {
            value.append(".");
        }
        
        cell.setCellValue(new HSSFRichTextString(value.toString()));
        
        sheet.autoSizeColumn((short)0);
        int width = sheet.getColumnWidth((short)0);
        
        if (width < 0) {
            System.out.println("width < 0");
        }
        
        workBook.write(new FileOutputStream("foo.xls"));
    }
}

Regards,
Jan
Comment 1 Yegor Kozlov 2007-08-10 10:35:24 UTC
Good catch.
I applied the suggested fix.

Regards,
Yegor