string.gsub returns 2 values, the new string and the number of
replacements made. It also has a 4th argument, the number of
replacements to make. So when you use the return value of gsub as the
3rd argument, and no replacements were made, it instructs the next call
to not make any replacements. Thanks to Ron Bowes for reporting this
issue.
A user reported this crash when scanning a target whose name contained
the '%' character:
NSE: Script Engine Scan Aborted.
An error was thrown by the engine: nse_main.lua:322: invalid capture index
stack traceback:
[C]: in function 'gsub'
nse_main.lua:322: in function 'd'
nse_main.lua:377: in function 'start'
nse_main.lua:912: in function 'run'
nse_main.lua:1390: in function <nse_main.lua:1293>
[C]: in ?
I'm not sure how a name with '%' got resolved, but I was able to
reproduce the crash by adding this line to /etc/hosts:
127.0.0.1 a%40b
and then running
./nmap --script=banner a%40b -d --top-ports 5
The gsub function recognizes "%d", where d is a digit, as a capture
index. The constructed string is then passed to print_debug, which is
like printf. Therefore we escape every occurrence of "%" twice, to get
"%%%%".
Changed indentation to 2 spaces, converted \r\n line endings to \n,
changed line-internal tabs to single space, removed whitespace at line
endings, reindented entire file with vim.
https://secwiki.org/w/Nmap/Code_Standards
Subclassed SyntaxError to provide some useful info when this happens. It
was happening with unittest.nse because it wasn't part of any category.
Previously, this would crash Zenmap because ScriptDBSyntaxError was
undefined. Now it crashes because there's really a syntax error (fixed
in previous revision)
These implementations were all functionally identical. The replacement
has an extra feature of returning the index where the value was found,
currently unused.
This function will format a MAC address as colon-separated hex bytes.
It's really very simple: stdnse.tohex(mac, {separator=":"})
This commit updates all the instances I could find of the varying
convoluted attempts at performing this conversion.
This saves a function call by using subclassing dict instead of using a
real dict. When a cache hit occurs, there is no overhead beyond a
standard dict lookup, which in most implementations is very fast. Cache
miss is similar performance to previous.
Also added a unittest for this functionality.
In general, it's better to use explicit flow control than to throw
and/or catch generic exceptions. Example:
try:
thing = d["key"]
except:
pass
This 1. catches an inspecific exception (probably KeyError), 2. can be
replaced with a check for ("key" is in d), and 3. can often be replaced
with d.get("key", some_default_value).
Issues fixed:
1 E111 indentation is not a multiple of four
1 E201 whitespace after '['
14 E251 no spaces around keyword / parameter equals
7 E301 expected 1 blank line, found 0
55 E302 expected 2 blank lines, found 1
69 E501 line too long (80 characters)
3 W291 trailing whitespace
4 W601 .has_key() is deprecated, use 'in'
Currently, this just uses Python's unittest module to autodiscover
tests, which may skip some, but is better than nothing. TODO: move tests
to their own module and let the zenmap_check target test them directly.
Replaced instances of this pattern:
if 'key' in somedict:
var = somedict['key']
else:
var = ""
...with this much simpler pattern:
var = somedict.get('key', "")
Some variations, like returning None if the key is not found were also
replaced.
Using the pep8 tool (https://pypi.python.org/pypi/pep8), fixed the
following style issues:
Count Issue
11 E201 whitespace after '['
8 E203 whitespace before ','
41 E211 whitespace before '('
11 E221 multiple spaces before operator
61 E225 missing whitespace around operator
237 E231 missing whitespace after ':'
91 E251 no spaces around keyword / parameter equals
19 E261 at least two spaces before inline comment
41 E301 expected 1 blank line, found 0
200 E302 expected 2 blank lines, found 1
356 E303 too many blank lines (2)
563 E501 line too long (106 characters)
39 E701 multiple statements on one line (colon)
13 E702 multiple statements on one line (semicolon)
4 W291 trailing whitespace
2 W293 blank line contains whitespace
8 W391 blank line at end of file
21 W601 .has_key() is deprecated, use 'in'
2 W602 deprecated form of raising exception
The remaining issues are long lines due to very deep data structures. I
chose not to alter them, as it would involve backslash-continuation
where whitespace is not permitted:
./zenmapGUI/ScanInterface.py:323:80: E501 line too long (90 characters)
./zenmapGUI/ScanInterface.py:456:80: E501 line too long (84 characters)
./zenmapGUI/ScanInterface.py:464:80: E501 line too long (84 characters)
./zenmapGUI/ScanInterface.py:472:80: E501 line too long (122 characters)
./zenmapGUI/ScanInterface.py:479:80: E501 line too long (122 characters)
./zenmapGUI/ScanInterface.py:920:80: E501 line too long (94 characters)
./zenmapGUI/ScanInterface.py:923:80: E501 line too long (93 characters)
./zenmapGUI/MainWindow.py:575:80: E501 line too long (99 characters)
./zenmapGUI/MainWindow.py:906:80: E501 line too long (99 characters)
When configuring --without-ncat, "make check" was trying to run Ncat's
test suite. This commit splits the check target into ncat_check and
nsock_check, and makes each conditional on that subsystem's configure
status.