Ему отдали не полностью заполненный буфер. Но читает он его неправильно. О 
чём
и должён сообщить, а не полагаться на проверку границ массива компилятором 
(которая
может и не помочь). Если бы он буфер не 8 байт а 128 выделил, то путешестоввал 
бы по
нему х\з сколько времени.

    Он попросил 1 элемент в буфере, и должен получить 1 элемент + признак 
окончания
(isc_info_end - который сетевой уровень 2.1 сейчас не пишет в _данном 
конкретном_ случае).
В общем - это либо небрежность, либо лень

Попытался я тут вкурить что ты сказал чтобы Карлосу сообщить и не понял что ты предлагаешь проверять.

Если ты имел ввиду метод


     public static int VaxInteger(byte[] buffer, int index, int length)
        {
            int newValue;
            int shift;

               try
               {
                    newValue = shift = 0;

                    int i = index;
                    while (--length >= 0)
                    {
                         newValue += (buffer[index++] & 0xff) << shift;
                         shift += 8;
                    }
               }
               catch (Exception e)
             {
                  throw;
             }

             return newValue;
        }


то у меня по нему больше вопросов чем ответов:

1) Чё это за хитрое выражение (buffer[index++] & 0xff). Здесь ведь массив байт. Получается что (buffer[index++] & 0xff) всегда равен просто buffer[index++]?

2) Нафиг он ввёл переменную i, а не использовал уже готовую index?

3) На кой там вобще

               catch (Exception e)
             {
                  throw;
             }


4) Допустим я вставлю перед циклом проверку типа

if (index >= buffer.Lengs)
  throw new Exception("бла-бла-бла").

что тогда ты предлагаешь там написать вместо бла-бла-бла? Ему и так фреймвёк вывалит сообщение со стектрейсом. Разве что можно имена переменных в сообщение добавить.


В общем я могу предложить такой вариант:

                public static int VaxInteger(byte[] buffer, int index, int 
length)
                {
                        if (index >= buffer.Length)
                                throw new ArgumentOutOfRangeException(
                                        "index",
                                        String.Format(
                                                "Index exceeds buffer length: 
buffer.Length = {0}, index = {1}.",
                                                buffer.Length,
                                                index)
                                );

                        int newValue = 0;
                        int shift = 0;

                        while (-- length >= 0)
                        {
                                newValue += buffer[index] << shift;
                                index ++;
                                shift += 8;
                        }

                        return newValue;
                }


Но он никаких технических преимуществ перед вариантом Карлоса не даёт. Только выглядит проще и красивее. Я даже не знаю как ему предложить такую переделку. По идее там весь проект можно пройти решарпером, отформатировать нормально, выкинуть мусор, но я не думаю что он захочет таким заниматься, а мне комитить никто ничё не даст.

Ещё вариант - это переделать вызов

   while ((type = buffer[pos++]) != IscCodes.isc_info_end)

но опять же какое исключение валить? Что не найден isc_info_end? Так тогда там наверное не одна сотня мест где такую проверку надо сделать. Я в принципе придерживаюсь мнения что если сервер должен возвращать этот isc_info_end, то на кой нужны лишние проверки в провайдере? Пофиксили багу в сервере и достаточно.

Ответить