diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-02-09 07:37:03 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-02-11 16:55:24 -0500 |
| commit | c7560387afc9660b4ea6a15eef1f387182c6ae51 (patch) | |
| tree | 2f1167f3e7c619cfcc5e8439103a12b84ec60217 | |
| parent | 7ffa67ce924352d4ac726bec48e4e554b5bb0f8c (diff) | |
libgetopts -- fix unsafe sharing in closures
| -rw-r--r-- | src/libgetopts/lib.rs | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index e5e7c50d2ce..34e09ac1913 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -775,14 +775,13 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool) let mut lim = lim; let mut cont = true; - let slice: || = || { cont = it(ss.slice(slice_start, last_end)) }; // if the limit is larger than the string, lower it to save cycles if lim >= fake_i { lim = fake_i; } - let machine: |(uint, char)| -> bool = |(i, c)| { + let machine: |&mut bool, (uint, char)| -> bool = |cont, (i, c)| { let whitespace = if ::std::char::is_whitespace(c) { Ws } else { Cr }; let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim }; @@ -794,24 +793,49 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool) (B, Cr, OverLim) if (i - last_start + 1) > lim => fail!("word starting with {} longer than limit!", ss.slice(last_start, i + 1)), - (B, Cr, OverLim) => { slice(); slice_start = last_start; B } - (B, Ws, UnderLim) => { last_end = i; C } - (B, Ws, OverLim) => { last_end = i; slice(); A } - - (C, Cr, UnderLim) => { last_start = i; B } - (C, Cr, OverLim) => { slice(); slice_start = i; last_start = i; last_end = i; B } - (C, Ws, OverLim) => { slice(); A } - (C, Ws, UnderLim) => { C } + (B, Cr, OverLim) => { + *cont = it(ss.slice(slice_start, last_end)); + slice_start = last_start; + B + } + (B, Ws, UnderLim) => { + last_end = i; + C + } + (B, Ws, OverLim) => { + last_end = i; + *cont = it(ss.slice(slice_start, last_end)); + A + } + + (C, Cr, UnderLim) => { + last_start = i; + B + } + (C, Cr, OverLim) => { + *cont = it(ss.slice(slice_start, last_end)); + slice_start = i; + last_start = i; + last_end = i; + B + } + (C, Ws, OverLim) => { + *cont = it(ss.slice(slice_start, last_end)); + A + } + (C, Ws, UnderLim) => { + C + } }; - cont + *cont }; - ss.char_indices().advance(|x| machine(x)); + ss.char_indices().advance(|x| machine(&mut cont, x)); // Let the automaton 'run out' by supplying trailing whitespace while cont && match state { B | C => true, A => false } { - machine((fake_i, ' ')); + machine(&mut cont, (fake_i, ' ')); fake_i += 1; } return cont; |
