Index: /branches/vox-28/common/SelectionRange.js
===================================================================
--- /branches/vox-28/common/SelectionRange.js (revision 159)
+++ /branches/vox-28/common/SelectionRange.js (revision 163)
@@ -106,8 +106,12 @@
         range2.collapse( true );
         var offset = 0;
+        var offsets = {};
         var steps = 0;
-        
-        // bail after 1k iterations in case of borkage
-        while( (test = range2.compareEndPoints( compareType, range )) != 0 ) {
+        var broken = false;
+        
+        /* this breaks if the user selects all, where the selection endpoint is at the end of body */
+        /* hence storing previously-visited offsets */
+        
+        while( test = range2.compareEndPoints( compareType, range ) ) {
             if( test < 0 ) {
                 range2.move( "character", delta );
@@ -117,14 +121,29 @@
                 offset -= delta;
             }
+            
             delta = max( 1, finiteInt( delta * 0.5 ) );
+            
+            /* visited this offset before? */
+            if( offsets[ offset ] === offset ) {
+                broken = true;
+                break;
+            }
+            offsets[ offset ] = offset;
+            
+            /* infinite loop bug */
             steps++;
-            if( steps > 1000 )
-                throw "unable to find textrange endpoint in " + steps + " steps";
-        }
-        
-        // this breaks if the user selects all, where the selection endpoint is at the
-        // end of body
-        
-        //log( "steps: " + steps );
+            if( steps > 1000 || (offset < 0 || offset > length + 1) ) {
+                broken = true;
+                break;
+            }
+        }
+        
+        /*
+        if( broken )
+            log( "BROKEN: " + parent.tagName + " " + length + " " + compareType + " " + test + " " + delta + " " + offset );
+        else
+            log( "GOOD: " + parent.tagName + " " + offset );
+        */
+        
         return DOM.Proxy.findTextPosition( parent, offset );
     },
