]> git.lizzy.rs Git - rust.git/commitdiff
libgetopts -- fix unsafe sharing in closures
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 9 Feb 2014 12:37:03 +0000 (07:37 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 11 Feb 2014 21:55:24 +0000 (16:55 -0500)
src/libgetopts/lib.rs

index e5e7c50d2cecd83363dacf8208e34a854ca06923..34e09ac1913db23a645e5edf45188f8df7e395fa 100644 (file)
@@ -775,14 +775,13 @@ enum LengthLimit {
     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 @@ enum LengthLimit {
             (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;