2012-03-11 54 views
0

下面是從GNU Coreutils的的lib/xreadlink.c文件中的一段代碼..如何檢查符號鏈接文件中的鏈接大小是否過大,是否適用於此代碼?

/* Call readlink to get the symbolic link value of FILENAME. 
    + SIZE is a hint as to how long the link is expected to be; 
    + typically it is taken from st_size. It need not be correct. 
     Return a pointer to that NUL-terminated string in malloc'd storage. 
     If readlink fails, return NULL (caller may use errno to diagnose). 
     If malloc fails, or if the link value is longer than SSIZE_MAX :-), 
     give a diagnostic and exit. */ 

char * xreadlink (char const *filename) 
{ 
    /* The initial buffer size for the link value. A power of 2 
     detects arithmetic overflow earlier, but is not required. */ 
    size_t buf_size = 128; 

    while (1) 
    { 
     char* buffer = xmalloc(buf_size); 
     ssize_t link_length = readlink(filename, buffer, buf_size); 
     if(link_length < 0) 
     { 
     /*handle failure of system call*/ 
     } 

     if((size_t) link_length < buf_size) 
     { 
      buffer[link_length] = 0; 
      return buffer; 
     } 

     /*size not sufficient, allocate more*/ 
     free (buffer); 
     buf_size *= 2; 
     /*Check whether increase is possible*/ 
     if (SSIZE_MAX < buf_size || (SIZE_MAX/2 < SSIZE_MAX && buf_size == 0)) 
      xalloc_die(); 
    } 
} 

的代碼是可以理解的,除了我不明白爲什麼在檢查鏈接的大小是過大的作品,即行:

 if (SSIZE_MAX < buf_size || (SIZE_MAX/2 < SSIZE_MAX && buf_size == 0)) 

此外,

 (SIZE_MAX/2 < SSIZE_MAX) 

條件如何可以是真正的任何系統上???

回答

1

SSIZE_MAX是已簽署的各種size_t最大值。舉例來說,如果size_t只有16位(不太可能這些天),SIZE_MAX是65535,而ssize_max爲32767。更可能的是32位(分別給予4294967295至2147483647),或甚至64位(提供具體數字太大了,在這裏輸入: - ))。

在這裏解決的基本問題是:readlink返回一個符號值,即使SIZE_MAX是一個無符號的一個......所以一旦buf_size超過SSIZE_MAX,這是不可能的閱讀環節,爲一體的大型正值會導致負返回值。

至於「進一步」的一部分:它很可能不能,即,你說得對。無論如何,至少在任何一個健全的系統中。 (這在理論上是可能有,例如,一個32位SIZE_MAX但33位有符號整數,這樣SSIZE_MAX也是4294967295想必這碼寫入防範理論上,可能的,但從未真正見過,系統。 )