Skip to content

Commit ccb2dfb

Browse files
committed
don't ICE on large files
This is an extremely marginal error, so the cost of properly threading `Handler` everywhere just not seemed justified. However, it's useful to panic when we create a file, and not when we slice strings with overflown indexes somewhere in the guts of the compiler. For this reason, while we provide safe `try_new_source_file`, we don't change the existing public interface and just panic more or less cleanly.
1 parent 70456a6 commit ccb2dfb

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

src/libsyntax/source_map.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ impl SourceMap {
191191
/// If a file already exists in the source_map with the same id, that file is returned
192192
/// unmodified
193193
pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
194+
self.try_new_source_file(filename, src)
195+
.unwrap_or_else(|OffsetOverflowError| {
196+
eprintln!("fatal error: rustc does not support files larger than 4GB");
197+
errors::FatalError.raise()
198+
})
199+
}
200+
201+
fn try_new_source_file(
202+
&self,
203+
filename: FileName,
204+
src: String
205+
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
194206
let start_pos = self.next_start_pos();
195207

196208
// The path is used to determine the directory for loading submodules and
@@ -212,7 +224,7 @@ impl SourceMap {
212224
was_remapped,
213225
Some(&unmapped_path));
214226

215-
return match self.source_file_by_stable_id(file_id) {
227+
let lrc_sf = match self.source_file_by_stable_id(file_id) {
216228
Some(lrc_sf) => lrc_sf,
217229
None => {
218230
let source_file = Lrc::new(SourceFile::new(
@@ -221,7 +233,7 @@ impl SourceMap {
221233
unmapped_path,
222234
src,
223235
Pos::from_usize(start_pos),
224-
));
236+
)?);
225237

226238
let mut files = self.files.borrow_mut();
227239

@@ -230,7 +242,8 @@ impl SourceMap {
230242

231243
source_file
232244
}
233-
}
245+
};
246+
Ok(lrc_sf)
234247
}
235248

236249
/// Allocates a new SourceFile representing a source file from an external

src/libsyntax_pos/lib.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,9 @@ impl ExternalSource {
859859
}
860860
}
861861

862+
#[derive(Debug)]
863+
pub struct OffsetOverflowError;
864+
862865
/// A single source in the `SourceMap`.
863866
#[derive(Clone)]
864867
pub struct SourceFile {
@@ -1040,7 +1043,7 @@ impl SourceFile {
10401043
name_was_remapped: bool,
10411044
unmapped_path: FileName,
10421045
mut src: String,
1043-
start_pos: BytePos) -> SourceFile {
1046+
start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> {
10441047
remove_bom(&mut src);
10451048

10461049
let src_hash = {
@@ -1054,11 +1057,14 @@ impl SourceFile {
10541057
hasher.finish()
10551058
};
10561059
let end_pos = start_pos.to_usize() + src.len();
1060+
if end_pos > u32::max_value() as usize {
1061+
return Err(OffsetOverflowError);
1062+
}
10571063

10581064
let (lines, multibyte_chars, non_narrow_chars) =
10591065
analyze_source_file::analyze_source_file(&src[..], start_pos);
10601066

1061-
SourceFile {
1067+
Ok(SourceFile {
10621068
name,
10631069
name_was_remapped,
10641070
unmapped_path: Some(unmapped_path),
@@ -1072,7 +1078,7 @@ impl SourceFile {
10721078
multibyte_chars,
10731079
non_narrow_chars,
10741080
name_hash,
1075-
}
1081+
})
10761082
}
10771083

10781084
/// Returns the `BytePos` of the beginning of the current line.

0 commit comments

Comments
 (0)