Автор: Энди Ли
Карта вызовов — это инструмент для навигации по графикам вызовов на Python с планами поддержки других языков. граф вызовов — это естественный способ обхода кода, где узлы — это процедуры, а направленные ребра соединяют процедуры, которые вызывают друг друга. Многие редакторы и IDE отдают приоритет сначала тексту, затем структуре каталогов и, где-то дальше, навигации по графу вызовов. Карта вызовов, напротив, делает граф вызовов основным интерфейсом для навигации по коду.
При проверке кода мне нужно помнить о взаимосвязях между различными частями кода. Когда этих отношений слишком много, я не могу легко их запомнить. Вот почему я разработал Call Map — чтобы помочь вам понять смысл кода, отражая его естественную структуру.
Хотя карта вызовов предназначена для получения общего представления о кодовой базе, она также естественным образом подходит для отслеживания путей кода, что представляет собой важную проблему безопасности. Многие проблемы безопасности обнаруживаются путем нахождения пути кода, который связывает ввод пользователя с опасными шаблонами кодирования.
Для IDE и редакторов характерно иметь возможность переходить к определениям и использованиям; несмотря на это, граф вызовов остается невидимым и неявным. Эти IDE и редакторы часто сосредотачивают явное представление кода только на дереве каталогов и тексте. Если кто-то хочет отслеживать путь через граф вызовов, он должен вручную записывать каждый переход. Это медленно, поэтому я не делаю этого, если у меня нет веской причины. Но затем, когда я нахожу интересный путь, я часто лишь частично помню этот путь и должен возвращаться по своим следам. С Call Map я обнаружил, что больше не теряюсь (каламбур).
Установка
Чтобы использовать Call Map, вам понадобится Python 3.5 с установленным PyQt5.
Вы можете получить Call Map на https://github.com/nccgroup/call_map.
Чтобы установить его, запустите:
# from the directory where you want to put the call_map source code
git clone https://github.com/nccgroup/call_map
cd call_map
pip3 install -e .
Начиная
В следующем примере я буду использовать библиотеку toolz
1 в качестве цели для исследования, так как это то, что вы установили как зависимость от Call Map.
Перейдите в новый каталог для экспериментов и запустите Call Map в первый раз, выполнив:
# -d -- project directory (will be created if it does not exist)
# -m -- modules to inspect
call_map -d cm_proj -m toolz
Это запускает call_map
, загружает модуль, указанный в командной строке, и сохраняет состояние проекта Call Map в каталоге cm_proj
. Вы должны увидеть пакет toolz
в правом верхнем углу виджета карты.
Если вы закроете карту вызовов, вы можете снова открыть проект с помощью:
call_map -d cm_proj
Те же модули и скрипты будут готовы к проверке. Другие настройки также будут сохранены.
Для получения дополнительной справки и сведений о других параметрах, например о том, как проверить пакеты, которые не установлены в вашей среде Python (возможно, нацелены на другую версию Python), выполните:
call_map -h
Навигация по диаграмме вызовов
Виджет карты в левом верхнем углу представляет график вызовов. Первый крайний левый столбец — это список модулей и скриптов, которыми может управлять пользователь. Продолжая пример из предыдущего раздела, нажмите toolz
, затем functoolz
, затем compose
. Теперь вы должны увидеть:
Когда вы выбираете элемент в столбце с помощью клавиш со стрелками или мыши, виджет карты отображает вызывающих, вызываемых и подэлементы элемента в следующем столбце. (Подэлементы класса включают его методы, а подэлементы модуля включают функции, определенные в модуле.)
Вызывающие объекты отмечены ⊲
, подэлементы отмечены ・
, а вызываемые объекты не отмечены. Классы обозначаются префиксом c:
, модули обозначаются префиксом m:
, а функции не имеют префикса.
По умолчанию выбранный элемент также выделяется в правом верхнем углу окна просмотра текста. Это поведение можно изменить в меню Вид. Некоторая метаинформация о выбранном элементе, такая как его модуль, тип и местоположение, отображается в левом нижнем углу.
Если вы выберете вызов, местоположение вызова будет выделено. После выбора вызова, если вы хотите увидеть соответствующее определение, выберите элемент [sig]
в следующем столбце.
Несколько предметов могут иметь одну и ту же метку. Каждый экземпляр представляет собой отдельный вызов или использование. Эти элементы можно отличить, взглянув на информацию в информационном виджете в левом нижнем углу и просмотрев исходный код.
Вы можете заметить, что Map Widget содержит больше информации, чем содержится в графиках вызовов, строго говоря. Карта вызовов задумана как практический инструмент и представляет другую полезную информацию, которую естественно включить в вызовы процедур.
Закладки
Проблемы с безопасностью часто обнаруживаются путем отслеживания данных, исходящих от пользовательского ввода, когда они перемещаются по графу вызовов, чтобы в конечном итоге достичь конфиденциального кода. Таким образом, карта вызовов предлагает возможность добавлять в закладки кодовые пути. Виджет закладок находится в нижней правой панели управления на вкладке закладки.
Нажмите Добавить, чтобы создать закладку. После перехода в другое место выберите закладку и нажмите Посетить, чтобы вернуться к закладке.
На вкладке закладки (json) ваши закладки отображаются в виде объекта JSON, поэтому вы можете легко копировать их и делиться ими.
Рабочий процесс
Карта вызовов предназначена для использования в сочетании с редактором. Текстовое представление задумано как простое средство предварительного просмотра и не имеет функций навигации и поиска, которые можно ожидать от текстового редактора. Вы можете нажать одну из кнопок Открыть в информационном виджете в левом нижнем углу, чтобы открыть соответствующий путь в редакторе. Поведение настраивается пользователем. Популярные редакторы, такие как Vim и Emacs, можно запускать как серверы, и вы можете настроить Call Map для отправки им команды на открытие файлов с определенными номерами строк.
Просмотрев код в текстовом редакторе, вы можете найти то, что хотите проверить. В работающем сеансе карты вызовов вы можете добавить модули и сценарии для проверки на вкладках «модули» и «скрипты» в виджете настроек, расположенном в правом нижнем углу. В будущем я планирую добавить связь через сокеты из редактора в карту вызовов, чтобы редактор мог заставить карту вызовов быстро переходить к элементу, который в данный момент находится под курсором редактора.
Продолжаются улучшения для более плавной интеграции карты вызовов с типичными рабочими процессами.
Дорожная карта
На данный момент карта вызовов поддерживает только анализ кода Python. Я хотел бы добавить поддержку других языков, вероятно, через Language Server Protocol.
Я надеюсь, что Call Map может стать надежной платформой для более глубокого анализа. Я планирую добавить функции запросов, чтобы помочь обнаружить проблемы безопасности в коде, начиная с простых функций поиска и фильтрации и заканчивая более сложными уровнями. Например, запрос может быть указан для путей графа вызовов, которые начинаются с процедуры, принимающей пользовательский ввод, и заканчиваются определенной конфиденциальной функцией, с ограничением, что ввод не проходит через конкретную функцию очистки.
- Библиотека функционального программирования. См. https://github.com/pytoolz/toolz. ↩
Первоначально опубликовано на www.nccgroup.trust.