[bug-65669] proper handling of apostrophe escaping in table column names

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894713 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-11-03 13:55:11 +00:00
parent 90d791b8ff
commit 8f1baa1190
2 changed files with 51 additions and 4 deletions

View File

@ -29,6 +29,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.apache.commons.collections4.map.CaseInsensitiveMap;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.SpreadsheetVersion;
@ -60,7 +61,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
private CTTable ctTable;
private transient List<XSSFXmlColumnPr> xmlColumnPrs;
private transient List<XSSFTableColumn> tableColumns;
private transient HashMap<String, Integer> columnMap;
private transient CaseInsensitiveMap<String, Integer> columnMap;
private transient CellReference startCellReference;
private transient CellReference endCellReference;
private transient String commonXPath;
@ -836,9 +837,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
public int findColumnIndex(String columnHeader) {
if (columnHeader == null) return -1;
if (columnMap == null) {
// FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap
final int count = getColumnCount();
columnMap = new HashMap<>(count * 3 / 2);
columnMap = new CaseInsensitiveMap<>(count * 3 / 2);
int i = 0;
for (XSSFTableColumn column : getColumns()) {
@ -849,7 +849,10 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
}
// Table column names with special characters need a single quote escape
// but the escape is not present in the column definition
Integer idx = columnMap.get(caseInsensitive(columnHeader.replace("'", "")));
String unescapedString = columnHeader
.replace("''", "'")
.replace("'#", "#");
Integer idx = columnMap.get(unescapedString);
return idx == null ? -1 : idx;
}

View File

@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.AreaReference;
@ -592,6 +593,49 @@ public final class TestXSSFTable {
}
}
@Test
void testBug65669() throws IOException {
String[] testValues = new String[] {"C'olumn", "Column"};
for (String testValue : testValues) {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
final String column = testValue;
// Set the values for the table
XSSFRow row;
XSSFCell cell;
for (int i = 0; i < 3; i++) {
// Create row
row = sheet.createRow(i);
for (int j = 0; j < 3; j++) {
// Create cell
cell = row.createCell(j);
if (i == 0) {
final String columnName = column + (j + 1);
cell.setCellValue(columnName);
} else {
if (j != 2) {
cell.setCellValue((i + 1.0) * (j + 1.0));
}
}
}
}
// Create Table
AreaReference reference = wb.getCreationHelper().createAreaReference(
new CellReference(0, 0), new CellReference(2, 2));
XSSFTable table = sheet.createTable(reference);
table.setName("Table1");
table.setDisplayName("Table1");
for (int i = 1; i < 3; i++) {
cell = sheet.getRow(i).getCell(2);
cell.setCellFormula("Table1[[#This Row],[" + column + "1]]");
}
}
}
}
private static XSSFTable addTable(XSSFSheet sheet,int nRow, int nCol, int nNumRows, int nNumCols) {
for (int i = 0; i < nNumRows; i++) {
XSSFRow row = sheet.createRow(i + nRow);