diff --git a/CHANGES.md b/CHANGES.md
index ba8708f5..f6f09a75 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,16 @@ Cobra Changelog
Here you can see the full list of changes between each Cobra release.
+Version 2.0.0-alpha.3
+---------------------
+
+Released on Sep 07 2017
+
+- 漏洞详情中增加CVI编号显示 #552
+- 支持非函数体预发解析(print/echo/eval/include)#551
+- 文件上传取消选择目录
+- 优化API文档
+
Version 2.0.0-alpha.2
---------------------
diff --git a/cobra/__version__.py b/cobra/__version__.py
index a5a44fb7..df73639c 100644
--- a/cobra/__version__.py
+++ b/cobra/__version__.py
@@ -7,7 +7,7 @@
__issue_page__ = 'https://github.com/wufeifei/cobra/issues/new'
__python_version__ = sys.version.split()[0]
__platform__ = platform.platform()
-__version__ = '2.0.0-alpha.2'
+__version__ = '2.0.0-alpha.3'
__author__ = 'Feei'
__author_email__ = 'feei@feei.cn'
__license__ = 'MIT License'
diff --git a/cobra/api.py b/cobra/api.py
index d021cb29..e97e91b0 100644
--- a/cobra/api.py
+++ b/cobra/api.py
@@ -167,7 +167,7 @@ def post():
'msg': 'success',
'sid': sid,
'status': result.get('status'),
- 'report': result.get('report'),
+ 'report': request.url_root + result.get('report'),
'still_running': result.get('still_running'),
'total_target_num': r_data.get('total_target_num'),
'not_finished': int(r_data.get('total_target_num')) - len(r_data.get('sids'))
@@ -312,7 +312,6 @@ def summary():
key=key)
status_url = 'http://{host}:{port}/api/status'.format(host=running_host, port=running_port)
- logger.critical(status_url)
post_data = {
'key': key,
'sid': a_sid,
@@ -340,7 +339,6 @@ def summary():
elif len(split_target) == 2:
target, branch = target_str, 'master'
else:
- logger.critical('[API] Target url exception: {u}'.format(u=target_str))
target, branch = target_str, 'master'
still_running[s_sid] = {'target': target,
'branch': branch}
@@ -373,7 +371,6 @@ def summary():
elif len(split_target) == 2:
target, branch = target_str, 'master'
else:
- logger.critical('Target url exception: {u}'.format(u=target_str))
target, branch = target_str, 'master'
target_info.update({
diff --git a/cobra/const.py b/cobra/const.py
index 6bff31fb..2e0d0940 100644
--- a/cobra/const.py
+++ b/cobra/const.py
@@ -31,7 +31,7 @@
# eval ($test + $test2);
# call_function ($exp);
#
-fpc = '\s*\((.*)(?:\))'
+fpc = '(\s*\((.*)(?:\))|\s*(.*\.)*\$.+)'
fpc_single = '[f]{fpc}'.format(fpc=fpc)
fpc_multi = '(?:[f]){fpc}'.format(fpc=fpc)
diff --git a/cobra/export.py b/cobra/export.py
index 4648dd4e..56850d91 100644
--- a/cobra/export.py
+++ b/cobra/export.py
@@ -14,7 +14,7 @@
import csv
import json
import os
-from codecs import open,BOM_UTF8
+from codecs import open, BOM_UTF8
from prettytable import PrettyTable
diff --git a/cobra/templates/asset/js/jquery.fileupload-process.js b/cobra/templates/asset/js/jquery.fileupload-process.js
new file mode 100644
index 00000000..dbe12c1c
--- /dev/null
+++ b/cobra/templates/asset/js/jquery.fileupload-process.js
@@ -0,0 +1,178 @@
+/*
+ * jQuery File Upload Processing Plugin
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2012, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * https://opensource.org/licenses/MIT
+ */
+
+/* jshint nomen:false */
+/* global define, require, window */
+
+;(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ './jquery.fileupload'
+ ], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS:
+ factory(
+ require('jquery'),
+ require('./jquery.fileupload')
+ );
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery
+ );
+ }
+}(function ($) {
+ 'use strict';
+
+ var originalAdd = $.blueimp.fileupload.prototype.options.add;
+
+ // The File Upload Processing plugin extends the fileupload widget
+ // with file processing functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ // The list of processing actions:
+ processQueue: [
+ /*
+ {
+ action: 'log',
+ type: 'debug'
+ }
+ */
+ ],
+ add: function (e, data) {
+ var $this = $(this);
+ data.process(function () {
+ return $this.fileupload('process', data);
+ });
+ originalAdd.call(this, e, data);
+ }
+ },
+
+ processActions: {
+ /*
+ log: function (data, options) {
+ console[options.type](
+ 'Processing "' + data.files[data.index].name + '"'
+ );
+ }
+ */
+ },
+
+ _processFile: function (data, originalData) {
+ var that = this,
+ dfd = $.Deferred().resolveWith(that, [data]),
+ chain = dfd.promise();
+ this._trigger('process', null, data);
+ $.each(data.processQueue, function (i, settings) {
+ var func = function (data) {
+ if (originalData.errorThrown) {
+ return $.Deferred()
+ .rejectWith(that, [originalData]).promise();
+ }
+ return that.processActions[settings.action].call(
+ that,
+ data,
+ settings
+ );
+ };
+ chain = chain.then(func, settings.always && func);
+ });
+ chain
+ .done(function () {
+ that._trigger('processdone', null, data);
+ that._trigger('processalways', null, data);
+ })
+ .fail(function () {
+ that._trigger('processfail', null, data);
+ that._trigger('processalways', null, data);
+ });
+ return chain;
+ },
+
+ // Replaces the settings of each processQueue item that
+ // are strings starting with an "@", using the remaining
+ // substring as key for the option map,
+ // e.g. "@autoUpload" is replaced with options.autoUpload:
+ _transformProcessQueue: function (options) {
+ var processQueue = [];
+ $.each(options.processQueue, function () {
+ var settings = {},
+ action = this.action,
+ prefix = this.prefix === true ? action : this.prefix;
+ $.each(this, function (key, value) {
+ if ($.type(value) === 'string' &&
+ value.charAt(0) === '@') {
+ settings[key] = options[
+ value.slice(1) || (prefix ? prefix +
+ key.charAt(0).toUpperCase() + key.slice(1) : key)
+ ];
+ } else {
+ settings[key] = value;
+ }
+
+ });
+ processQueue.push(settings);
+ });
+ options.processQueue = processQueue;
+ },
+
+ // Returns the number of files currently in the processsing queue:
+ processing: function () {
+ return this._processing;
+ },
+
+ // Processes the files given as files property of the data parameter,
+ // returns a Promise object that allows to bind callbacks:
+ process: function (data) {
+ var that = this,
+ options = $.extend({}, this.options, data);
+ if (options.processQueue && options.processQueue.length) {
+ this._transformProcessQueue(options);
+ if (this._processing === 0) {
+ this._trigger('processstart');
+ }
+ $.each(data.files, function (index) {
+ var opts = index ? $.extend({}, options) : options,
+ func = function () {
+ if (data.errorThrown) {
+ return $.Deferred()
+ .rejectWith(that, [data]).promise();
+ }
+ return that._processFile(opts, data);
+ };
+ opts.index = index;
+ that._processing += 1;
+ that._processingQueue = that._processingQueue.then(func, func)
+ .always(function () {
+ that._processing -= 1;
+ if (that._processing === 0) {
+ that._trigger('processstop');
+ }
+ });
+ });
+ }
+ return this._processingQueue;
+ },
+
+ _create: function () {
+ this._super();
+ this._processing = 0;
+ this._processingQueue = $.Deferred().resolveWith(this)
+ .promise();
+ }
+
+ });
+
+}));
\ No newline at end of file
diff --git a/cobra/templates/asset/js/jquery.fileupload-validate.js b/cobra/templates/asset/js/jquery.fileupload-validate.js
new file mode 100644
index 00000000..8e130bda
--- /dev/null
+++ b/cobra/templates/asset/js/jquery.fileupload-validate.js
@@ -0,0 +1,125 @@
+/*
+ * jQuery File Upload Validation Plugin
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2013, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * https://opensource.org/licenses/MIT
+ */
+
+/* global define, require, window */
+
+;(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ './jquery.fileupload-process'
+ ], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS:
+ factory(
+ require('jquery'),
+ require('./jquery.fileupload-process')
+ );
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery
+ );
+ }
+}(function ($) {
+ 'use strict';
+
+ // Append to the default processQueue:
+ $.blueimp.fileupload.prototype.options.processQueue.push(
+ {
+ action: 'validate',
+ // Always trigger this action,
+ // even if the previous action was rejected:
+ always: true,
+ // Options taken from the global options map:
+ acceptFileTypes: '@',
+ maxFileSize: '@',
+ minFileSize: '@',
+ maxNumberOfFiles: '@',
+ disabled: '@disableValidation'
+ }
+ );
+
+ // The File Upload Validation plugin extends the fileupload widget
+ // with file validation functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ /*
+ // The regular expression for allowed file types, matches
+ // against either file type or file name:
+ acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
+ // The maximum allowed file size in bytes:
+ maxFileSize: 10000000, // 10 MB
+ // The minimum allowed file size in bytes:
+ minFileSize: undefined, // No minimal file size
+ // The limit of files to be uploaded:
+ maxNumberOfFiles: 10,
+ */
+
+ // Function returning the current number of files,
+ // has to be overriden for maxNumberOfFiles validation:
+ getNumberOfFiles: $.noop,
+
+ // Error and info messages:
+ messages: {
+ maxNumberOfFiles: 'Maximum number of files exceeded',
+ acceptFileTypes: 'File type not allowed',
+ maxFileSize: 'File is too large',
+ minFileSize: 'File is too small'
+ }
+ },
+
+ processActions: {
+
+ validate: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var dfd = $.Deferred(),
+ settings = this.options,
+ file = data.files[data.index],
+ fileSize;
+ if (options.minFileSize || options.maxFileSize) {
+ fileSize = file.size;
+ }
+ if ($.type(options.maxNumberOfFiles) === 'number' &&
+ (settings.getNumberOfFiles() || 0) + data.files.length >
+ options.maxNumberOfFiles) {
+ file.error = settings.i18n('maxNumberOfFiles');
+ } else if (options.acceptFileTypes &&
+ !(options.acceptFileTypes.test(file.type) ||
+ options.acceptFileTypes.test(file.name))) {
+ file.error = settings.i18n('acceptFileTypes');
+ } else if (fileSize > options.maxFileSize) {
+ file.error = settings.i18n('maxFileSize');
+ } else if ($.type(fileSize) === 'number' &&
+ fileSize < options.minFileSize) {
+ file.error = settings.i18n('minFileSize');
+ } else {
+ delete file.error;
+ }
+ if (file.error || data.files.error) {
+ data.files.error = true;
+ dfd.rejectWith(this, [data]);
+ } else {
+ dfd.resolveWith(this, [data]);
+ }
+ return dfd.promise();
+ }
+
+ }
+
+ });
+
+}));
\ No newline at end of file
diff --git a/cobra/templates/asset/js/jquery.fileupload.js b/cobra/templates/asset/js/jquery.fileupload.js
index a5247782..d57fc04f 100755
--- a/cobra/templates/asset/js/jquery.fileupload.js
+++ b/cobra/templates/asset/js/jquery.fileupload.js
@@ -1122,8 +1122,9 @@
}, errorHandler);
}
} else if (entry.isDirectory) {
- dirReader = entry.createReader();
- readEntries();
+ $('#progress').empty();
+ $('#progress').html('禁止文件夹上传!');
+ return;
} else {
// Return an empy list for file system items
// other than files or directories:
diff --git a/cobra/templates/asset/js/report.js b/cobra/templates/asset/js/report.js
index e8522e64..a05f9718 100644
--- a/cobra/templates/asset/js/report.js
+++ b/cobra/templates/asset/js/report.js
@@ -108,7 +108,7 @@ $(function () {
$('.commit-author').text('@' + data.commit_author);
$('.commit-time').text('@' + data.commit_time);
$('.v-level').text(score2level[data.level]);
- $('.v-type').text(data.rule_name);
+ $('.v-type').text('CVI-' + data.id + ' ' + data.rule_name);
$('.v-solution').text(data.solution);
// $('.v-rule').text(data.match_result);
}
@@ -341,8 +341,8 @@ $(function () {
' data-start="1" data-line="1">' +
'MVE-' + (i + 1) + '
' + list[i].file_path + line + '
' +
'' +
- '' +
- ' => ' + list[i].commit_time +
+ '' + 'CVI-' + list[i].id +
+ ' => ' + list[i].rule_name +
'' +
'' +
'';
diff --git a/cobra/templates/index.html b/cobra/templates/index.html
index 721d7993..151aa983 100644
--- a/cobra/templates/index.html
+++ b/cobra/templates/index.html
@@ -102,8 +102,11 @@