diff --git a/Units/parser-html.r/file-offset-crlf-crash.d/.gitattributes b/Units/parser-html.r/file-offset-crlf-crash.d/.gitattributes new file mode 100644 index 0000000000..c399786831 --- /dev/null +++ b/Units/parser-html.r/file-offset-crlf-crash.d/.gitattributes @@ -0,0 +1 @@ +/input.html binary \ No newline at end of file diff --git a/Units/parser-html.r/file-offset-crlf-crash.d/args.ctags b/Units/parser-html.r/file-offset-crlf-crash.d/args.ctags new file mode 100644 index 0000000000..c6e1f305b7 --- /dev/null +++ b/Units/parser-html.r/file-offset-crlf-crash.d/args.ctags @@ -0,0 +1 @@ +--sort=no \ No newline at end of file diff --git a/Units/parser-html.r/file-offset-crlf-crash.d/expected.tags b/Units/parser-html.r/file-offset-crlf-crash.d/expected.tags new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Units/parser-html.r/file-offset-crlf-crash.d/input.html b/Units/parser-html.r/file-offset-crlf-crash.d/input.html new file mode 100644 index 0000000000..ff47486fbc --- /dev/null +++ b/Units/parser-html.r/file-offset-crlf-crash.d/input.html @@ -0,0 +1,2 @@ + +
Hi
diff --git a/main/read.c b/main/read.c index 2118ec1e99..44a1f792c0 100644 --- a/main/read.c +++ b/main/read.c @@ -417,8 +417,20 @@ extern MIOPos getInputFilePositionForLine (unsigned int line) extern long getInputFileOffsetForLine (unsigned int line) { compoundPos *cpos = getInputFileCompoundPosForLine (line); - long r = cpos->offset - (File.bomFound? 3: 0) - cpos->crAdjustment; + long bomOffset = File.bomFound ? 3 : 0; + + // The position stored for this line was captured before processing this line's CRLF, + // but crAdjustment includes this line's CRLF. Use previous line's adjustment. + long relevantCrAdjustment = 0; + if (line > 1) { + // For line N > 1, use adjustment from line N-1 + compoundPos *prevCpos = getInputFileCompoundPosForLine(line - 1); + relevantCrAdjustment = prevCpos->crAdjustment; + } + + long r = cpos->offset - bomOffset - relevantCrAdjustment; Assert (r >= 0); + return r; } @@ -608,11 +620,30 @@ static int compoundPosForOffset (const void* oft, const void *p) const compoundPos *pos = p; const compoundPos *next = (compoundPos *)(((char *)pos) + sizeof (compoundPos)); - if (offset < (pos->offset - pos->crAdjustment)) + // For consistency with getInputFileOffsetForLine, use previous line's crAdjustment + // for position calculation to account for timing mismatch + long relevantCrAdjustment = 0; + if (pos > File.lineFposMap.pos) { + // Not the first position, use previous position's crAdjustment + const compoundPos *prevPos = pos - 1; + relevantCrAdjustment = prevPos->crAdjustment; + } + + long nextRelevantCrAdjustment = 0; + if (next <= File.lineFposMap.pos + File.lineFposMap.count - 1) { + // Not past the last position + if (next > File.lineFposMap.pos) { + // Not the first position, use previous position's crAdjustment + const compoundPos *nextPrevPos = next - 1; + nextRelevantCrAdjustment = nextPrevPos->crAdjustment; + } + } + + if (offset < (pos->offset - relevantCrAdjustment)) return -1; - else if (((pos->offset - pos->crAdjustment) <= offset) + else if (((pos->offset - relevantCrAdjustment) <= offset) && (pos->open - || (offset < (next->offset - next->crAdjustment)))) + || (offset < (next->offset - nextRelevantCrAdjustment)))) return 0; else return 1;