Skip to content

Document comparison crashes when the revised file contains tracked changes (w:ins/w:del) #3698

@IuLeon

Description

@IuLeon

Description

When using setRevisedFile() to compare two documents, the editor crashes if the revised file (the file passed to setRevisedFile) contains tracked changes (<w:ins>, <w:del> elements in the docx XML).

Steps to Reproduce

1.Open a clean document (no tracked changes) in edit mode
2.Call setRevisedFile({ url: '...', fileType: 'docx' }) with a file that contains tracked changes (revision marks from previous editing sessions)
3.Click "Yes" on the confirmation dialog ("All tracked changes will be considered accepted")
4.Editor crashes with a TypeError

Version 9.3.1:

TypeError: Cannot read properties of undefined (reading 'da')
at sj (sdk-all.js:9247:115)
at Oa.D9c (sdk-all.js:12899:322)
at A.compare (sdk-all.js:12863)

Version 9.4.0.1:

TypeError: Cannot read properties of undefined (reading 'Split2')
at CRunCollector.splitCurrentRun (sdk-all.js:628537:15)
at CLabelChange.apply (sdk-all.js:624316:30)
at resolveTypesWithPartner (sdk-all.js:624132:12)
at CDocumentComparison.applyChangesToParagraph (sdk-all.js:626856:4)
at CDocumentComparison.compare (sdk-all.js:626734:13)

Root Cause Analysis

In CRunCollector.splitCurrentRun:

CRunCollector.prototype.splitCurrentRun = function (bAfter) {
    const oRun = this.getRun();
    return oRun.Split2(...); // oRun is undefined
};

CRunCollector.prototype.getRun = function () {
    const oContent = this.parent.Content;
    return oContent[this.runIndex]; // returns undefined
};

When the revised document contains tracked changes (<w:ins>/<w:del>), the comparison algorithm (CDocumentComparison) processes the document tree after the tracked changes have been "accepted" internally. This creates a mismatch between this.runIndex and the actual Content array length — the index points beyond the array bounds because the acceptance of tracked changes modified the content structure without updating the CRunCollector's index references.

Suggested Fix

In CDocumentComparison.compare() or CompareBinary(), before running the comparison algorithm, the revised document's tracked changes should be fully resolved (accepted/rejected) and the document model should be rebuilt/re-indexed. Alternatively, CRunCollector.getRun() should include a bounds check:

CRunCollector.prototype.getRun = function () {
    const oContent = this.parent.Content;
    if (this.runIndex >= oContent.length) return null;
    return oContent[this.runIndex];
};

CRunCollector.prototype.splitCurrentRun = function (bAfter) {
    const oRun = this.getRun();
    if (!oRun) return null;
    return oRun.Split2(bAfter ? this.runElementIndex + 1 : this.runElementIndex, this.parent, this.runIndex);
};

Workaround

Pre-process the revised file to strip all tracked changes from the docx XML before passing it to setRevisedFile():

Remove <w:del> elements entirely
Unwrap <w:ins> elements (keep inner content)
Remove *Change elements (<w:rPrChange>, <w:pPrChange>, etc.)

Environment

Document Server: 9.3.1 and 9.4.0.1
Browser: Chrome 148
OS: Windows 11

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions