extlinux: fix multiple directory-parsing bugs.
authorhpa <hpa>
Sun, 3 Apr 2005 00:00:36 +0000 (00:00 +0000)
committerhpa <hpa>
Sun, 3 Apr 2005 00:00:36 +0000 (00:00 +0000)
NEWS
extlinux.asm
extlinux/extlinux.c

diff --git a/NEWS b/NEWS
index 03a81a8..9071f35 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Changes in 3.08:
        * libutil: Add SHA-1 and base64 functions.
        * Simple menu system: add password support.
        * EXTLINUX: Sparse files now handled correctly.
+       * EXTLINUX: Large directories now handled correctly.
 
 Changes in 3.07:
        * Fix chainloading (chain.c32).
index 4de7992..999d402 100644 (file)
@@ -853,7 +853,7 @@ getonesec_ext:
                mov bp,1
 
 getlinsec_ext:
-               cmp eax,[ClustSize]
+               cmp eax,[SecPerClust]
                jae getlinsec                   ; Nothing fancy
 
                ; If we get here, at least part of what we want is in the
@@ -976,6 +976,11 @@ open_inode:
                inc eax                         ; s_first_data_block+1
                mov cl,[ClustShift]
                shl eax,cl
+               push edx
+               shr edx,SECTOR_SHIFT
+               add eax,edx
+               pop edx
+               and dx,SECTOR_SIZE-1
                call getcachesector             ; Get the group descriptor
                add si,dx
                mov esi,[gs:si+bg_inode_table]  ; Get inode table block #
@@ -1062,6 +1067,7 @@ searchdir:
                call getfssec
                pop bx
                pushf                   ; Save EOF flag
+               push si                 ; Save filesystem pointer
 .getent:
                cmp dword [bx+d_inode],0
                je .endblock
@@ -1078,6 +1084,7 @@ searchdir:
                jmp .getent
 
 .endblock:
+               pop si
                popf
                jnc .readdir            ; There is more
 .failure:
@@ -1093,17 +1100,19 @@ searchdir:
                
                ; It's a match, but it's a directory.
                ; Repeat operation.
+               pop bx                  ; Adjust stack (di)
+               pop si
                call close
-               pop si                  ; Adjust stack (di)
-               pop si                  ; Adjust stack (flags)
+               pop bx                  ; Adjust stack (flags)
                inc di                  ; Skip slash
                jmp .searchloop
                
 
 .finish:       ; We found it; now we need to open the file
+               pop bx                  ; Adjust stack (di)
+               pop si
                call close              ; Close directory
-               pop si                  ; Adjust stack (di)
-               pop si                  ; Adjust stack (flags)
+               pop bx                  ; Adjust stack (flags)
                call open_inode
 .done:
                pop di
@@ -1331,6 +1340,12 @@ getfssec:
                push eax
                push edx
                push edi
+
+               movzx ecx,cx
+               cmp ecx,[si]                    ; Number of sectors left
+               jbe .lenok
+               mov cx,[si]
+.lenok:
 .getfragment:
                mov eax,[si+file_sector]        ; Current start index
                mov edi,eax
@@ -1369,9 +1384,9 @@ getfssec:
                pop bp
                add [si+file_sector],ebp        ; Next sector index
                sub [si],ebp                    ; Sectors consumed
-               jz .done
                jcxz .done
-               jmp .getfragment
+               jnz .getfragment
+               ; Fall through
 .done:
                cmp dword [si],1                ; Did we run out of file?
                ; CF set if [SI] < 1, i.e. == 0
index 05f6cf3..195b4e5 100644 (file)
@@ -416,7 +416,8 @@ get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
   geo->start     = 0;
 
   if ( !opt.sectors && !opt.heads )
-    fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n",
+    fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
+           "         (on hard disks, this is usually harmless.)\n",
            geo->heads, geo->sectors);
 
   return 1;