Как в этом коде работает условие проверки размера ссылки в файле символьных ссылок? - PullRequest
0 голосов
/ 11 марта 2012

Вот фрагмент кода из файла lib / xreadlink.c в GNU Coreutils ..

  /* 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 Ответ

1 голос
/ 11 марта 2012

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. Предположительно, этот код написан для защиты от теоретически возможного, но никогда не видимого,системы.)

...