Giter Club home page Giter Club logo

asterisklint's People

Contributors

havoc83 avatar jjsearle avatar wdoekes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asterisklint's Issues

Add writesql+= syntax support for func_odbc.conf

When i check my extensions conf, i have got an error:
func_odbc.conf:6 E_CONF_KEY_INVALID: expected valid var/object or new context, got 'writesql+'
My func_odbc.conf:

[ADD]
prefix=REPORTS
synopsis=Get report values from VAL1 and add it to the reports table
dsn=int-dsn-asterisk
writesql=INSERT INTO pbx.call_reports (values_list)
writesql+=VALUES ('${SQL_ESC(${VAL1})}')

Inclusion of commas inside of brackets raise an exception

I'm not saying that the Pattern Matching syntax is correct here, but it raised an exception
exten => _XXX[1,2,3,7,8]XXX,1,NoOp(DEBUG)

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.8/site-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.8/site-packages/asterisklint/dialplan.py", line 507, in from_varset
    pattern = pattern and Pattern(pattern, varset.where) or None
  File "/usr/local/lib/python3.8/site-packages/asterisklint/pattern.py", line 107, in __init__
    self.values = self.parse(pattern)
  File "/usr/local/lib/python3.8/site-packages/asterisklint/pattern.py", line 116, in parse
    return tuple([Pattern.IS_A_PATTERN] + cls.parse_pattern(raw[1:]))
  File "/usr/local/lib/python3.8/site-packages/asterisklint/pattern.py", line 143, in parse_pattern
    range_end = raw.index(0x5d)  # ']'
ValueError: 93 is not in list

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.8/site-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.8/site-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.8/site-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.8/site-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions.conf:4079

I already fixed the expression to:
exten => _XXX[1-378]XXX,1,NoOp(DEBUG)

The exception is not raised anymore, so the commas inside of brackets make it break.

Nested function causes exception

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/dialplan.py", line 508, in from_varset
    app = App(app, varset.where)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/application.py", line 111, in __init__
    self.parse()
  File "/usr/local/lib/python3.6/site-packages/asterisklint/application.py", line 134, in parse
    self.data = self.parse_inner(self.data)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/application.py", line 149, in parse_inner
    data = VarLoader().parse_variables(data, self.where)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/varfun.py", line 289, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/varfun.py", line 330, in _process_variable
    return FuncLoader().process_read_function(data, where)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/varfun.py", line 178, in process_read_function
    loaded_func = FuncLoader()._get_and_check_availability(func, where)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/varfun.py", line 206, in _get_and_check_availability
    loaded = FuncLoader().get(func.lower())
AttributeError: 'list' object has no attribute 'lower'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.6/site-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.6/site-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.6/site-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: ./extensions.conf:1069

The line of dialplan that caused the exception

same => n,Set(is_open=${ODBC_CHECK_TIMESET_${TOUPPER(${STRFTIME(,,%a)})}(${ARG1})})

func_odbc-check does not recognize [general] context

In func_odbc.conf it's possible to specify general options for ODBC through the [general] context.

However, Asterisk Lint does not seem to recognize this. These are the validation errors returned for a func_odbc.conf with a [general] context.

./func_odbc.conf:17 W_ODBC_BADTOKENS: odbc function 'general' should be uppercase with A-Z0-9_ only
./func_odbc.conf:22 E_CONF_KEY_INVALID: expected valid var/object or new context, got 'single_db_connection'
./func_odbc.conf:17 E_ODBC_NOSQL: a readsql and/or writesql (and insertsql) statement is required

RFE: Add Set(ARRAY(column_count...)=${FUNC_ODBC_FUNC()}) checks

Now that we have initial support for func_odbc SQL column counts, we could add support for (at least) counting the number of returned arguments.

E.g.

[FUNC]
readsql=SELECT a, b, c FROM table WHERE id = ${ARG1}

same => n,Set(ARRAY(LOCAL(a),LOCAL(b))=${ODBC_FUNC(1)})
;                                    ^ E_SOMETHING: missing return value 'c'

regex producing invalid priority error

OpenBSD 6.8
Asterisk 18.1.1

asterisklint dialplan-check extensions.conf produces error:

extensions.conf:9 E_DP_PRIO_INVALID: invalid priority '3]XX'

Content of extensions.conf:

[general]
static=yes
writeprotect=yes
clearglobalvars=no

[globals]

[phones]
exten => _[2,3]XX,1,NoOp(Incoming call for ${EXTEN})

E_APP_ARG_MANY gosub freeze endless check with 100% cpu core load

I have make syntax mistake - added excess comma before opening bracket in gosub:
exten => _7495XXXXXXX,1,Gosub(sub-dial,${EXTEN},1,(${SOME_VARIABLE}))

When i start asterisklint dialplan-check extensions.conf it freeze with 100% one core cpu load and this message in console:
extensions.conf:44 E_APP_ARG_MANY: too many arguments for app 'Gosub', maximum is 3

P.S. I broke by this error your site: https://asterisklint.osso.pub/
I'm sorry! :))

Feature to disable special types of errors

Without it, for example, we get plenty of errors on standard Freepbx config:

b.com/FreePBX/core.git
Cloning into 'core'...
remote: Counting objects: 10137, done.
remote: Total 10137 (delta 0), reused 0 (delta 0), pack-reused 10137
Receiving objects: 100% (10137/10137), 6.99 MiB | 91.00 KiB/s, done.
Resolving deltas: 100% (6560/6560), done.
Checking connectivity... done.
root@as-05:~# cd core/etc/
root@as-05:~/core/etc# ../../asterisklint/scripts/asterisklint dialplan-check ./extensions.conf
./extensions.conf:29 W_PP_INCLUDE_MISSING: the #include file 'extensions_override_freepbx.conf' could not be found
./extensions.conf:30 W_PP_INCLUDE_MISSING: the #include file 'extensions_additional.conf' could not be found
./extensions.conf:31 W_PP_INCLUDE_MISSING: the #include file 'extensions_custom.conf' could not be found
./extensions.conf:35 H_WSV_CTX_BETWEEN: expected one or two lines between non-tiny contexts
./extensions.conf:99 W_DP_PRIO_BADORDER: bad priority order for pattern '_+1NXXNXXXXXX/_NXXNXXXXXX' and prio 2
./extensions.conf:101 W_DP_PRIO_BADORDER: bad priority order for pattern '_+1NXXNXXXXXX/_011NX.' and prio <unset>
./extensions.conf:105 W_DP_PRIO_BADORDER: bad priority order for pattern '_[0-9+]./_NXXNXXXXXX' and prio <unset>
./extensions.conf:107 W_DP_PRIO_BADORDER: bad priority order for pattern '_[0-9+]./_011NX.' and prio <unset>
./extensions.conf:110 W_DP_PRIO_BADORDER: bad priority order for pattern 's/_NXXNXXXXXX' and prio <unset>
./extensions.conf:112 W_DP_PRIO_BADORDER: bad priority order for pattern 's/_011NX.' and prio <unset>
./extensions.conf:148 W_APP_NEED_PARENS: app 'Answer' should have parentheses (only NoOp is exempt)
./extensions.conf:151 W_APP_BAD_CASE: app 'Playtones' does not have the proper Case 'PlayTones'
./extensions.conf:153 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:154 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:155 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:159 H_WSV_CTX_BETWEEN: expected one or two lines between non-tiny contexts
./extensions.conf:201 H_WSV_CTX_BETWEEN: expected one or two lines between non-tiny contexts
./extensions.conf:232 E_FUNC_MISSING: function 'DB' does not exist (or func_odbc created?)
./extensions.conf:234 W_DP_PRIO_BADORDER: bad priority order for pattern 's' and prio 200
./extensions.conf:235 W_DP_PRIO_BADORDER: bad priority order for pattern 's' and prio 300
./extensions.conf:241 W_WSH_EOL: unexpected trailing whitespace
./extensions.conf:298 E_FUNC_MISSING: function 'DB' does not exist (or func_odbc created?)
./extensions.conf:310 E_FUNC_MISSING: function 'DB_EXISTS' does not exist (or func_odbc created?)
./extensions.conf:315 E_FUNC_MISSING: function 'DB' does not exist (or func_odbc created?)
./extensions.conf:317 E_APP_MISSING: app 'Authenticate' does not exist, dialplan will halt here!
./extensions.conf:318 E_APP_MISSING: app 'AGI' does not exist, dialplan will halt here!
./extensions.conf:325 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:329 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:337 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:351 E_FUNC_MISSING: function 'DB' does not exist (or func_odbc created?)
./extensions.conf:353 E_APP_MISSING: app 'AGI' does not exist, dialplan will halt here!
./extensions.conf:358 W_APP_NEED_PARENS: app 'Hangup' should have parentheses (only NoOp is exempt)
./extensions.conf:372 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:377 H_WSV_CTX_BETWEEN: expected one or two lines between non-tiny contexts
./extensions.conf:410 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:411 E_FUNC_MISSING: function 'MD5' does not exist (or func_odbc created?)
./extensions.conf:415 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:417 E_DP_PRIO_INVALID: invalid priority 'tts+101'
./extensions.conf:427 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:428 E_FUNC_MISSING: function 'MD5' does not exist (or func_odbc created?)
./extensions.conf:434 E_DP_PRIO_INVALID: invalid priority 'tts+101'
./extensions.conf:443 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:444 E_FUNC_MISSING: function 'MD5' does not exist (or func_odbc created?)
./extensions.conf:450 E_DP_PRIO_INVALID: invalid priority 'tts+101'
./extensions.conf:459 W_APP_BAD_CASE: app 'Noop' does not have the proper Case 'NoOp'
./extensions.conf:460 E_FUNC_MISSING: function 'MD5' does not exist (or func_odbc created?)
./extensions.conf:0 H_DP_GENERAL_MISPLACED: [general] context not found or not at top of file
./extensions.conf:0 H_DP_GLOBALS_MISPLACED: [globals] context not found or not at position two

pre-commit hook extension

The pre-commit hook as-is displays a lot (arguably) irrelevant stuff if other files than changed ones trigger warnings. A possible solution would be to use the output of the following:

git diff --cached --name-only --diff-filter=ACM

Only staged changes would then trigger the dialplan-check.

The full pre-commit file:

#!/bin/sh
export ALINT_IGNORE=  # adjust as needed

for c in $(git diff --cached --name-only --diff-filter=ACM);
do
    asterisklint dialplan-check /PATH/TO/extensions.conf/$c
done

ret=$?
if test $ret -ne 0; then
    echo >&2
    echo 'One or more dialplan syntax errors. Please fix before committing.' >&2
    exit $ret
fi

exit 0

RFE: pjsip support

The chan_sip seems to be deprecated in favor of pjsip. Would be nice if pjsip.conf and pjsip_wizard.conf support were added to this tool.

missing asterisk built in functions

AttributeError: 'list' object has no attribute 'split' with v0.40

asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions_choosevoice.conf:6

Here are lines 5,6 and 7 of the offending file:

same => n,Verbose(1,${languages})
same => n,While($["${SET(languagenumber=${SHIFT(languages)})}" != ""])
same => n,Gosub(choosevoice,getlangitems,1(${languagenumber}))

And here is the error in full:

/etc/asterisk# asterisklint dialplan-check extensions.conf
func_odbc.conf:88 E_CONF_KEY_INVALID: expected valid var/object or new context, got 'syntax'
func_odbc.conf:89 W_CONF_KEY_LATE: expected varset 'synopsis' earlier, fix your ordering
func_odbc.conf:96 W_WSV_EOF: unexpected vertical space at end of file
extensions.conf:97 W_APP_BAD_CASE: app 'agi' does not have the proper Case 'AGI'
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 591, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 499, in from_varset
    app = App(app, varset.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 111, in __init__
    self.parse()
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 134, in parse
    self.data = self.parse_inner(self.data)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 149, in parse_inner
    data = VarLoader().parse_variables(data, self.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 284, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 288, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 329, in _process_variable
    return FuncLoader().process_read_function(data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 178, in process_read_function
    loaded_func(args, where=where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/func/vall/func_logic.py", line 43, in __call__
    VarLoader().parse_assignment(data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 236, in parse_assignment
    dest, value = data.split('=', 1)
AttributeError: 'list' object has no attribute 'split'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/main.py", line 147, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions_choosevoice.conf:6
root@televox:/etc/asterisk# asterisklint dialplan-check extensions.conf
func_odbc.conf:88 E_CONF_KEY_INVALID: expected valid var/object or new context, got 'syntax'
func_odbc.conf:89 W_CONF_KEY_LATE: expected varset 'synopsis' earlier, fix your ordering
func_odbc.conf:96 W_WSV_EOF: unexpected vertical space at end of file
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 591, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 499, in from_varset
    app = App(app, varset.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 111, in __init__
    self.parse()
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 134, in parse
    self.data = self.parse_inner(self.data)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 149, in parse_inner
    data = VarLoader().parse_variables(data, self.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 284, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 288, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 329, in _process_variable
    return FuncLoader().process_read_function(data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 178, in process_read_function
    loaded_func(args, where=where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/func/vall/func_logic.py", line 43, in __call__
    VarLoader().parse_assignment(data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 236, in parse_assignment
    dest, value = data.split('=', 1)
AttributeError: 'list' object has no attribute 'split'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/main.py", line 147, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions_choosevoice.conf:6```

asterisk regex causes python errors

OpenBSD 6.8
Asterisk 18.1.1

asterisklint dialplan-check extensions.conf produces a python error:

Traceback (most recent call last):
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/dialplan.py", line 507, in from_varset
    pattern = pattern and Pattern(pattern, varset.where) or None
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/pattern.py", line 107, in __init__
    self.values = self.parse(pattern)
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/pattern.py", line 116, in parse
    return tuple([Pattern.IS_A_PATTERN] + cls.parse_pattern(raw[1:]))
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/pattern.py", line 143, in parse_pattern
    range_end = raw.index(0x5d)  # ']'
ValueError: 93 is not in list

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/ugisu/.pyenv/versions/3.8.0/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/Users/ugisu/.pyenv/versions/3.8.0/lib/python3.8/site-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions.conf:15

if extensions.conf has this content:

[general]
static=yes
writeprotect=yes
clearglobalvars=no

[globals]

[phones]
exten => _00XX.,1,NoOp(Outgoing call to +${EXTEN:2})
same => n,Set(zeroesExten=+${EXTEN:2})
same => n,Gosub(set-caller-id,s,1)
same => n,Dial(PJSIP/${zeroesExten}@sometrunk)
same => n,Hangup()

exten => _004490[0,1,6].,1,NoOp(Some number ${EXTEN})
same => n,Wait(1)
same => n,Playback(t26/premium-numbers)
same => n,Hangup()

[set-caller-id]
exten => s,1,NoOp(Set caller ID)
same => n,Set(caller_ext=${CALLERID(num)})
same => n,ExecIf($[${REGEX("^2[0-9][0-9]$" ${caller_ext})} = 1]?Set(CALLERID(num)=+441234567890))
same => n,Return()

if we change exten => _004490[0,1,6].,1,NoOp(Some number ${EXTEN}) with exten => _004490(0|1|6).,1,NoOp(Some number ${EXTEN}) there are no errors, but the regex in Asterisk is not working.

Can make it crash with a CPLAYBACKOFFSET

Summary: AssertionError: CPLAYBACKOFFSET=0

CPLAYBACKOFFSET=0 is indeed wrong, but makes asterisklint crash.

Offending code

exten => s,1,Verbose(1,Context:${CONTEXT} Extension:${EXTEN} foldercount:${foldercount} numberOfTracks:${numberOfTracks} currentTrackFileName:${currentTrackFileName} pathDepth:${pathDepth} scanPath:${scanPath} CPLAYBACKOFFSET:${CPLAYBACKOFFSET=0})

Full output

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 588, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/dialplan.py", line 496, in from_varset
    app = App(app, varset.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 120, in __init__
    self.parse()
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 142, in parse
    self.data = self.parse_inner(self.data)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/application.py", line 164, in parse_inner
    data = VarLoader().parse_variables(data, self.where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 217, in parse_variables
    inner_data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 267, in _process_variable
    self.count_var(data, where)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/varfun.py", line 305, in count_var
    for i in varname), varname
AssertionError: CPLAYBACKOFFSET=0

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/main.py", line 147, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/commands/modules-show.py", line 74, in main
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.5/dist-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: ./extensions_star_help_handler.conf:102```


cannot handle hints (and crash on W_ARROW)

exten => 151,hint,Custom:test,CustomPresence:mypresence01

leads to

./dialplan.conf:70 I_NOTIMPL_HINT: the dialplan hint directive has not been implemented yet

exten = 151,hint,Custom:test,CustomPresence:mypresence01

which is a valid Asterisk syntax for defining hints
leads to a crash:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/dialplan.py", line 473, in from_varset
    assert varset.arrow  # W_ARROW
AssertionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.6/dist-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: ./dialplan.conf:12

app NoCDR not supported

asterisklint will throw an error when using NoCDR() in the dialplan, even when module app_cdr.so is loaded:

/etc/asterisk# asterisk -rx 'module show' | grep app_cdr
app_cdr.so Tell Asterisk to not maintain a CDR for 0 Running core

/etc/asterisk# grep NoCDR extensions.conf
exten => _X.,1,NoCDR()

/etc/asterisk# git commit -a
/etc/asterisk/extensions.conf:xxx E_APP_MISSING: app 'NoCDR' does not exist, dialplan will halt here!

(using asterisklint version 0.2.1)

Refactor code in ConfigParser.preprocessor() to separate methods

These bits can be easily moved to a separate splitting method.

if rest[0] == '"' and rest[-1] == '"':
...

And this can be moved to a rest-extracting method:

        if not rest or ord(rest[0]) > 32:
            E_CONF_BAD_LINE(where, startswith=text[0:16])
            return

        for idx, ch in enumerate(rest):
            if ord(ch) > 32:
                break
        else:
            # Nothing after the #include/#tryinclude/#exec.
            E_CONF_BAD_LINE(where, startswith=text[0:16])
            return

        if (not all(i == ' ' for i in rest[0:idx]) and
                not all(i == '\t' for i in rest[0:idx])):
            W_WSH_CTRL(where)
        rest = rest[idx:]

RFE: Alter func_odbc-annotate --collapse that collapses expanded func_odbc.conf files

If we use annotate and annotate --collapse as idempotent commands, we can make func_odbc editing a lot easier. (We probably don't want a separate func_odbc-collapse command, seeing that the functionality it so closely tied.)

Also: if possible, we'll want an "edit-inline" flag, so we can rewrite the files instead of spitting out the output. Otherwise #includes won't be editable.

Missing AUDIOHOOK_INHERIT

./extensions.conf:1966 E_FUNC_MISSING: function 'AUDIOHOOK_INHERIT' does not exist (or func_odbc created?)

Basic loop controls like While, Endwhile, ControlPlayback etc not recognised

I know that Authenticate and AGI is on the to-do list, but the rest are fairly standard, long-standing basic everyday applications. Not whining because this is a great app, just pointing it out!

; WARNING: The following unknown applications were seen:
; (none), ControlPlayback, EndWhile, ExitWhile, VMSayName, While, agi

app originate args

./extensions.conf:480 E_APP_ARG_MANY: too many arguments for app 'Originate', maximum is 6

^-

Originate(tech_data,type,arg1[,arg2[,arg3[,timeout[,options]]]])

(ast 16)

In vg dialplan-check we get dupe message for i18n/conf and 27/31/32

[context]
exten => _X!,1,Set(i18n_region=default)
exten => _X!,2,Return()

[context]
exten => 27,1,Set(i18n_region=ZA)
exten => 31,1,Set(i18n_region=NL)
exten => 32,1,Set(i18n_region=BE)
exten => _X!,1,Set(i18n_region=default)
exten => _X!,2,Return()

How should we handle this? Fix VG context to drop older context if new one is found? How does Ast handle it?

Become aware of eventual syntax changes in Asterisk versions

Imagine, if you will, that Asterisk 20 introduces a new, optional syntax to extensions.conf. Now imagine that, by mistake, I put a new-syntax extensions.conf in my Asterisk 18 installation. It is invalid, but asterisklint will flag it as valid. My suggestion is to take an optional argument, saying what Asterisk version we're checking against. This could apply to other subcommands too, not only dialplan-check.

asterisklint dialplan-check -a 18 ~/mystagindir/extensions.conf

Or

asterisklint -a 18 dialplan-check ~/mystagindir/extensions.conf

Could also be an environment variable:

ALINT_ASTVER=18 asterisklint dialplan-check ~/mystagindir/extensions.conf

RFE: Alter func_odbc-annotate so it expands the func_odbc.conf files

Make two commands: func_odbc-annotate and func_odbc-collapse.

The first one should convert this:

; somefunc is awesome
[SOMEFUNC]
readsql=SELECT id AS col1, 'hardcoded' AS col2 FROM table

into this:

; > ODBC_SOMEFUNC
; >
; > read return values: (1) col1, (2) col2
[SOMEFUNC]
readsql=SELECT id AS col1, 'hardcoded' AS col2
  FROM table

and the second one should convert it back to:

; > ODBC_SOMEFUNC
; >
; > read return values: (1) col1, (2) col2
; somefunc is awesome
[SOMEFUNC]
readsql=SELECT id AS col1, 'hardcoded' AS col2 FROM table

This makes for easier editing of long SQL statements.

We have a partial implementation which right now spits out sql format:

[ACCOUNT_ZIPCODE]
;; ACCOUNT_ZIPCODE returns the zipcode for the account that is placing a call.
prefix=MY
readhandle=my_db
readsql=SELECT zip_code FROM account_account WHERE account_id = '${SQL_ESC(${ARG1})}'

becomes:

-- MY_ACCOUNT_ZIPCODE
-- .
-- FUNCTION TYPE: read
-- COLUMNS:
--  1. zip_code
SELECT zip_code
FROM account_account
WHERE account_id = '${SQL_ESC(${ARG1})}';

asterisklint-hooks? (RfC-ish)

I see references to "hooks" in one or two issues but I couldn't actually find anything. Since I use pre-commit in most of my projects, I went ahead and wrote some first-class pre-commit hooks for it. It just mirrors the current version of asterisklint so it should track that whenever you make a new release. We've been waiting (and waiting) for a certain project to spring loose but I got busy waiting and haven't actually touched it for a while. You can try it just like any of the usual python/cmake/other hooks here: https://github.com/VCTLabs/asterisklint-hooks

Any feedback is welcome - thanks!

walk_jump_destinations: UnboundLocalError: local variable 'i' referenced before assignment

walter@walter-dev:0:~/asterisklint$ ./scripts/asterisklint dialplan-check bug.conf 
bug.conf:0 H_DP_GENERAL_MISPLACED: [general] context not found or not at top of file
bug.conf:0 H_DP_GLOBALS_MISPLACED: [globals] context not found or not at position two
Traceback (most recent call last):
  File "./scripts/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/home/walter/asterisklint/asterisklint/main.py", line 147, in main
    return command_module.main(args, envs)
  File "/home/walter/asterisklint/asterisklint/commands/dialplan-check.py", line 49, in main
    dialplan.walk_jump_destinations()
  File "/home/walter/asterisklint/asterisklint/dialplan.py", line 181, in walk_jump_destinations
    extension, priority)
  File "/home/walter/asterisklint/asterisklint/dialplan.py", line 281, in match_pattern
    if pattern.matches_extension(extension):
  File "/home/walter/asterisklint/asterisklint/pattern.py", line 375, in matches_extension
    value = self.values[i + 2]
UnboundLocalError: local variable 'i' referenced before assignment
walter@walter-dev:1:~/asterisklint$ cat bug.conf 
[context]
exten => s,1,GotoIf($["${CALLERID(num):0:1}"="+"]?${EXTEN:1},1) ; strip + if it is there

Argument as a substring int causes exception

This sample extensions.conf

[macro-callerid-name-shorten]
exten => s,1,Set(CALLERID(name)=${CALLERID(name):0:${ARG1}})

causes an exception in asterisklint

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/dialplan.py", line 508, in from_varset
    app = App(app, varset.where)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/application.py", line 111, in __init__
    self.parse()
  File "/usr/local/lib/python3.9/site-packages/asterisklint/application.py", line 134, in parse
    self.data = self.parse_inner(self.data)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/application.py", line 149, in parse_inner
    data = VarLoader().parse_variables(data, self.where)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/varfun.py", line 288, in parse_variables
    inner_data = self._process_variable(
  File "/usr/local/lib/python3.9/site-packages/asterisklint/varfun.py", line 330, in _process_variable
    return FuncLoader().process_read_function(data, where)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/varfun.py", line 182, in process_read_function
    return ReadFuncSlice(func, args, start=start, length=length)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/variable.py", line 257, in __init__
    if length < 0:
TypeError: '<' not supported between instances of 'Var' and 'int'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/usr/local/lib/python3.9/site-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/usr/local/lib/python3.9/site-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/usr/local/lib/python3.9/site-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: extensions.conf:2

Replacing ${ARG1} with a hardcoded integer works as expected, but for my logic, it must be a variable.

I can't find a decent workaround as wrapping ARG1 with TRUNC and MATH function also produce similar comparison exceptions but different instances instead of 'Var', 'ReadFunc' and 'Expr' respectively.

testing on Asterisk master: AssertionError => ProgrammingError

Testing as in running as a pre-commit hook on the example configs in Asterisk repo results in:

$ pre-commit try-repo ../mirrors-asterisklint dialplan-check --verbose --all-files
[WARNING] Creating temporary repo with uncommitted changes...
===============================================================================
Using config:
===============================================================================
repos:
-   repo: /tmp/tmpy_9oi7z_/shadow-repo
    rev: a0a794368016cda785cef32e75de44de13982d18
    hooks:
    -   id: dialplan-check
===============================================================================
[INFO] Initializing environment for /tmp/tmpy_9oi7z_/shadow-repo.
[INFO] Installing environment for /tmp/tmpy_9oi7z_/shadow-repo.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
dialplan-check...........................................................Failed
- hook id: dialplan-check
- duration: 0.15s
- exit code: 1

configs/basic-pbx/extensions.conf:1 H_DP_GLOBALS_MISPLACED: [globals] context not found or not at position two
configs/basic-pbx/extensions.conf:9 W_WSH_VARSET: expected no horizontal whitespace around equals operator
Traceback (most recent call last):
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/config.py", line 186, in __iter__
    self.on_varset(element)
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/dialplan.py", line 600, in on_varset
    dialplanvarset = DialplanVarset.from_varset(varset)
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/dialplan.py", line 473, in from_varset
    assert varset.arrow  # W_ARROW
AssertionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/bin/asterisklint", line 34, in <module>
    sys.exit(main(sys.argv[1:], os.environ))
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/main.py", line 178, in main
    return command_module.main(args, envs)
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/mainutil.py", line 35, in __call__
    return self.handle_args(args)
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/commands/dialplan-check.py", line 50, in handle_args
    dialplan = next(iter(parser))
  File "/tmp/tmpy_9oi7z_/repo_urfu3v9/py_env-python3.9/lib/python3.9/site-packages/asterisklint/config.py", line 192, in __iter__
    raise ProgrammingError(str(element.where)) from exc
asterisklint.config.ProgrammingError: An unexpected exception was raised. This is most likely a bug in the asterisklint library. If you can reproduce the problem and file an issue on the bug tracker, that would be nice. Further info: configs/basic-pbx/extensions.conf:9

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.