Skip to content

Off-by-One Error in SharedStrings After Windows Excel "Enable Editing and Save" #433

@arpitmantri7501

Description

@arpitmantri7501

Plugin Information
Package: excel (https://pub.dev/packages/excel)
Version: 4.0.6
Error Location: lib/src/parser/parse.dart line 686 in _parseCell() method

Issue Description
Excel files that are opened in Microsoft Excel on Windows with "Enable Editing" and then saved become corrupted and fail to parse with a null pointer exception.

Root Cause
When Windows Excel saves the file, it creates a sharedString reference with an out-of-bounds index:

The xl/sharedStrings.xml file contains 415 sharedString entries (indices 0-414)
A worksheet cell references sharedString index 415 (which doesn't exist)
The _SharedStringsMaintainer.value(index) method returns null for out-of-bounds indices
Code attempts to access .textSpan on the null value, causing crash
Reproduction Steps
Create/upload an Excel file that parses successfully
Open the file in Microsoft Excel on Windows
Click "Enable Editing" when prompted
Make any minor edit or just save the file (Ctrl+S)
Close Excel
Try to parse the file with Excel.decodeBytes()
Result: DartError: Unexpected null value at parse.dart:686
Error Logs
📝 Cell B87: SharedString type, elements count: 1
📝 Cell B87: v value = "415"
📝 Cell B87: Requesting sharedString at index 415
📝 Cell B87: sharedString result = NULL!
❌ Cell B87: SharedString at index 415 is NULL! Total sharedStrings: 415
❌ Cell B87: Error in sharedString processing: Unexpected null value.

DartError: Unexpected null value.
packages/excel/src/parser/parse.dart 686:52 [_parseCell]

Affected Code
lib/src/parser/parse.dart around line 610-620:
case 's':
final sharedString = _excel._sharedStrings
.value(int.parse(_parseValue(node.findElements('v').first)));
value = TextCellValue.span(sharedString!.textSpan); // <- Crashes here when sharedString is null
break;

Expected Behavior
The parser should:

Validate that the referenced index exists before accessing it
Handle out-of-bounds indices gracefully (use empty string or skip the cell)
Log a warning instead of crashing

Suggested Fix
case 's':
final index = int.parse(_parseValue(node.findElements('v').first));
final sharedString = _excel._sharedStrings.value(index);

if (sharedString == null) {
// Handle missing sharedString gracefully
print('Warning: Cell $cellRef references non-existent sharedString at index $index');
value = TextCellValue(''); // or null
} else {
value = TextCellValue.span(sharedString.textSpan);
}
break;

Workaround (Application-Level)
Pre-process the Excel bytes to add missing sharedString entries before parsing:
// Scan all worksheets for max referenced sharedString index
// If max index >= sharedStrings.length, add empty placeholders
// Update sst count and uniqueCount attributes
// Re-encode ZIP archive

Impact
Severity: High - Complete parsing failure on real-world files
Frequency: Very common - happens with any file edited in Windows Excel
User Experience: Files work initially but fail after normal editing workflow
Environment
Platform: Web (Flutter Web)
Excel Source: Files created and edited in Microsoft Excel (Windows)
File Format: .xlsx (OOXML)

Additional Notes
This appears to be a mismatch between how Windows Excel manages sharedStrings internally vs. the OOXML specification. The plugin should be robust enough to handle these real-world file variations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions