Re[4]: А отрефакторю-ка я сейчас всё. Mемуар.
От: мыщъх США http://nezumi-lab.org
Дата: 19.05.15 17:27
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, мыщъх, Вы писали:


М>>выход за границы буфера это такой протокол общения кода с аллокатором

VTT>

простреливание ноги это такой повод сходить к врачу

давайте так. в си нет [нормальной] поддержки массивов. malloc вообще возвращает не массив, а указатель. если это чужой malloc, то за массивом может быть пустота, обращение к которой поимеет непредсказуемые последствия. если же это наш malloc, то мы гарантируем, что за массивом то, что нужно. грубо говоря, возвращаем структуру. кстати, в этой структуре явно прописан размер.

это _сильно_ все упрощает. теперь не нужно передавать функциям указатель на данные и размер данных. скажу больше. если у нас есть функция поиска подстроки в строке и эта строка лежит где-то в середине большого блока данных, то мы передаем указатель на начало данных. да! на начало данных. там есть структура в которой размер данных и индекс строки.

проблема переполняющихся буферов решается сама собой, т.к. любая функция на любом уровне вложенности может проверить что она не выходит за границы буфера, ибо имеет в своем распоряжении всю необходимую инфу. типа if (scb->idx > scb->len) return -1; какие у вас возражения против кастомного аллокатора?


VTT>На самом деле можно было начать просто с изложения причин использования такого подхода. Такая каша же не просто так заварилась?

угу. там были свои причины. сначала появился api и был задокументирован, а затем его потребовалось расширить без изменения инклудов и прочей бодяги.

VTT> А если жизненную необходимость прыгать за границу массива для "общения" с аллокатором

VTT> не удается внятно объяснить в письменной форме другим людям, то это явный повод не говнокодить.
это был исследовательский код и объяснений не требовалось. на самом деле даже обычный malloc зачастую возвращает структуру типа: [служебные данные][буфер данных], вот только указатель не на начало служебных данных, а на буфер. это, разумеется, недокументированно. но если мы сами пишем аллокатор и сами же пишем остальной код, то мы точно знаем что там за служебные данные и они у нас в распоряжении.

на самом деле у нас есть паблик инклуд для аллокатора с malloc и free и приватный инклуд, где описаны внутренние структуры данных. чтобы не включать приватный инклуд в остальной код там хитрый ход котом. там метапрограммирование. там программа читает приватный инклуд и генерирует остальной код на си, где смещения захардкорены, но этот код генерируется автоматом и перегенерируется при изменении служебных структур. генератор — в билд системе, т.е. за пределами программы. но все работает и работает абсолютно корректно на любой платформе.

на самом деле ошибка не у меня, ошибкой были многочисленные попытки рефракторить код, сгенерированный автоматом. он выглядит ужасно, да. но он работает. и он, кстати, делает оптимизацию на графах и этому оптимизатору доступны данные недоступные компилятору и потому оптимизация таки рулит.

VTT>То, что С обделен многими плюшками и сахарком других языков, вовсе не принуждает писать на нем нечитаемый код.

согласен. но проблема гораздо глубже. и проблема тут не в си. тут проблема в ореентации (не сексуальной).

VTT> Затем, заметив баг, он переписал if(p[0] == '.') и чувством выполненного долга пошел в бар.

...пошел празновать увольнение? а если там ../foo/././../../bar/foo/baz/../././ -- это алисас или нет? пикантая подробность -- bar это хардлик на baz. так что на уровне разбора строки эта проблема не разрешима вообще. и даже если вас устраивает частичное решение, то это очень сложный код и в этом коде у ms было аж три ошибки переполнения буфера. потому что писали на си. потому что сложно на самом деле это.

> а том, что кто-то пренебрег ясным изложением смысла этого сравнения,

> которое на самом деле должно было определять, показывать файл или нет
у ms в этом месте был код, который допускал передачу управления на хакерский шелл-код, засунутый в этом самый путь и ms исправила ошибку только с третьей попытки. сначала ошибку исправили только для "/", на второй итерации для "\\". наконец, исправили ситуацию в которой хакер использовал "\\" и "/" в _одном_ пути.

> В данном случае ему повезло, но обычно такие фокусы кончаются плохо.

угу. у ms все было хуже и там была дыра, которую хрен исправить.

VTT> Так что по мне подобное срезание углов на ровном месте — просто признак лени и некомпетентности.

в вашем примере -- не срезание углов, а просто некомпетентность, т.к. если немного подумать, то становится ясно, что тут нужна функция на 100500 строк, которая все равно не будет работать, т.к. на ANSI C ее написать невозможно в принципе.

в моем случае -- не было никакого "срезания углов". там был автоматически генеририруемый код, который править нельзя. вернее, можно, но бессмысленно. если уж приспичило, то править код генератора.

признаю, что дизайн был ужасным. но именно совершая ошибки и наступая на грабли мы понимаем как нужно писать программы и чем хороший код от плохого отличается. но с учетом что я не девелопер и никогда им не был и что в job description от меня требовали выполнение исследований с последующим изложением мыслей на БУМАГЕ, то... этоо сильно другая ситуация, не?

мой поинт в том, что исследовательский код на уровне прототипа, будучи полигоном для обкатки различных идей, нужно писать с нуля. даже не переписывать, а именно дизайнить с нуля. если вам говорят построить самый быстрый в мире автомобиль, то вы еще не знаете каким он будет. электромобиль? или присобачить реактивный двигатель от самолета? будут там колеса или монорельс? хз. нужно пробовать и то, и другое. наконец, оно таки работает. теперь можно работать над дизайном конструкции с учетом наработок в этой области.

срезание углов имело место быть на вышестоящем уровне, когда руководство посмотрело на мой макет и сказало: качество кода выше среднего по рынку и потому включаем его в продакшен как есть. а через лет пять или шесть код решили отрефракторить, когда ни меня, ни того кто принял решение о его включении в продакшен уже не было. кстати, это вторая ошибка. "работает -- не трожь". ну или трожь, только переписывай заново, благо алгос уже запатетован и в патенте все подробно изложено как оно устроено.

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

> Я вполне уверен, что и в данном случае можно было все четко запрограммировать и не доводить людей до инфаркта.

можно, конечно. но можно было и не пытаться это рефракторить. давайте так: если код плохой и неправильный, причем не на уровне наименования отдельных переменных, а на уровне дизайна, то этот код или не включать в продакшен или включать, но мириться с тем, что рефракторить его нужно с носителями знаний. попытка рефракторить код с плохим дизайном без носителей знаний... особенно, поручая это людям со слабым сердцем... это уже садизм в особо обостренной форме.

VTT> Еще интересно, как там различался ошибочный выход за границы массива от целенаправленного?

различается очень просто. дизайн специально разработан так, чтобы исключить ошибочный выход за границы массива. за это отвечает часть кода на си, которая генерирует другую часть кода на си и если там ошибка, то она на стадии работы билд-системы.

невозможность выхода за границы массива обеспечивается как раз за счет того, что я прикрутил к си полноценную поддержку массивов, а не просто указателей на безразмрную память. "прикрутил" за счет метапрограммирования. и это сработало. после чего о выходе за границы было можно не парится. более того, исчезли проверки выхода за границы в рантайме и они были перенесены на стадию трансляции. разумеется не стадию трансляции си, т.к. си не располагает подобной инфой.

тут, конечно, можно поспорить насколько оправданы подобные выходки. но! я тупо учился программировать. это был лабораторный исследовательский код. однако, каким-то чудом он работал и работал без нареканий.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.