Update to handle BOM char and index-out-of-bounds condition

This commit is contained in:
2022-08-17 11:34:00 -05:00
parent a0cfd5a97e
commit 9bf898af7a
2 changed files with 67 additions and 1 deletions

View File

@ -95,6 +95,15 @@ public class CsvToQRecordAdapter
throw (new IllegalArgumentException("Empty csv value was provided."));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// once, from a DOS csv file (that had come from Excel), we had a "" character (FEFF, Byte-order marker) at the start of a //
// CSV, which caused our first header to not match... So, let us strip away any FEFF or FFFE's at the start of CSV strings. //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(csv.length() > 1 && (csv.charAt(0) == 0xfeff || csv.charAt(0) == 0xfffe))
{
csv = csv.substring(1);
}
try
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -118,7 +127,7 @@ public class CsvToQRecordAdapter
// put values from the CSV record into a map of header -> value //
//////////////////////////////////////////////////////////////////
Map<String, String> csvValues = new HashMap<>();
for(int i = 0; i < headers.size(); i++)
for(int i = 0; i < headers.size() && i < csvRecord.size(); i++)
{
csvValues.put(headers.get(i), csvRecord.get(i));
}

View File

@ -31,6 +31,7 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@ -281,4 +282,60 @@ class CsvToQRecordAdapterTest
// todo - this is what the method header comment means when it says we don't handle all cases well...
// Assertions.assertEquals(List.of("A", "B", "C", "C 2", "C 3"), csvToQRecordAdapter.makeHeadersUnique(List.of("A", "B", "C 2", "C", "C 3")));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testByteOrderMarker()
{
CsvToQRecordAdapter csvToQRecordAdapter = new CsvToQRecordAdapter();
List<QRecord> records = csvToQRecordAdapter.buildRecordsFromCsv("""
id,firstName
1,John""", TestUtils.defineTablePerson(), null);
assertEquals(1, records.get(0).getValueInteger("id"));
assertEquals("John", records.get(0).getValueString("firstName"));
}
/*******************************************************************************
** Fix an IndexOutOfBounds that we used to throw.
*******************************************************************************/
@Test
void testTooFewBodyColumns()
{
CsvToQRecordAdapter csvToQRecordAdapter = new CsvToQRecordAdapter();
List<QRecord> records = csvToQRecordAdapter.buildRecordsFromCsv("""
id,firstName,lastName
1,John""", TestUtils.defineTablePerson(), null);
assertEquals(1, records.get(0).getValueInteger("id"));
assertEquals("John", records.get(0).getValueString("firstName"));
assertNull(records.get(0).getValueString("lastName"));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
public void testTooFewColumnsIndexMapping()
{
int index = 1;
QIndexBasedFieldMapping mapping = new QIndexBasedFieldMapping()
.withMapping("id", index++)
.withMapping("firstName", index++)
.withMapping("lastName", index++);
CsvToQRecordAdapter csvToQRecordAdapter = new CsvToQRecordAdapter();
List<QRecord> records = csvToQRecordAdapter.buildRecordsFromCsv("1,John", TestUtils.defineTablePerson(), mapping);
assertEquals(1, records.get(0).getValueInteger("id"));
assertEquals("John", records.get(0).getValueString("firstName"));
assertNull(records.get(0).getValueString("lastName"));
}
}