Динамическая подсветка синтаксиса с помощью AngularJS и Highlight.Яш

Я создаю сайт, который иллюстрирует общие уязвимости приложений, такие как SQL-инъекция. Я использую AngularJS и выделить.js для создания интерактивных примеров.

как я могу сделать AngularJS и выделить.js обновляет мои фрагменты кода?

пример

Эта Скрипка показано, как войти ' OR 1=1 -- в поле электронной почты может изменить предполагаемое поведение запроса если ввод пользователя не проверен или не санирован.

SELECT * FROM dbo.Users WHERE Email='{{email}}' AND Password='{{password}}'  

когда пользователь вводит адрес электронной почты и пароль, Angular обновляет запрос. Однако подсветка синтаксиса не обновляется.

SELECT * FROM dbo.Users WHERE Email='user@domain.com' AND Password=''

Я попытался повторно инициализировать hljs, но когда я делаю угловые остановки обновления запроса.

hljs.initHighlighting.called = false;
hljs.initHighlighting();

приложение

<script>
    var app = angular.module("app", ['hljs']);
    app.controller("controller", function($scope) {
        $scope.email = "user@domain.com";
        $scope.password = "";
    })
</script>
<div ng-app="app" ng-controller="controller">
    <div>
        <div class="row">
            <div class="col-sm-4">Email
                <input type="text" class="form-control" ng-model="email">
            </div>
            <div class="col-sm-4">Password
                <input type="text" class="form-control" ng-model="password">
            </div>
        </div>
        <br>
        <div hljs include="'compile-me'" compile="true" language="sql"></div>
    </div>
    <script type="text/ng-template" id="compile-me">
        SELECT * FROM dbo.Users WHERE Email = '{{email}}'
        AND Password = '{{password}}'
    </script>
</div>

2 ответов


в jsfiddle, который вы предоставили, вы используете угловой-highlightjs который в вашем случае в основном:

  1. выбирает шаблон, который вы предоставили с С angular-highlightjs что наблюдается, но я думаю, что проще построить пользовательскую директиву.

    трюк здесь состоит в том, чтобы вручную интерполировать и выделять контент. Я обновил ваш скрипка и highlight директива, которая представляет идею:

    app.directive('highlight', function($interpolate, $window){
        return {
        restrict: 'EA',
        scope: true,
        compile: function (tElem, tAttrs) {
          var interpolateFn = $interpolate(tElem.html(), true);
          tElem.html(''); // stop automatic intepolation
    
          return function(scope, elem, attrs){
            scope.$watch(interpolateFn, function (value) {
              elem.html(hljs.highlight('sql',value).value);
            });
          }
        }
      };
    });
    

более простой способ, который я только что нашел, - использовать фильтр:

app.filter('highlight', function($sce) {
  return function(input, lang) {
    if (lang && input) return hljs.highlight(lang, input).value;
    return input;
  }
}).filter('unsafe', function($sce) { return $sce.trustAsHtml; })

затем вы можете сказать:

<pre><code ng-bind-html="someScopeVariable | highlight | unsafe"></code></pre>

$sce должен быть введен в ваше приложение и сообщает Angular для отображения HTML raw - что вы ему доверяете.