Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
This document describes a language intended to be used in ServiceX and func_adl for messages which represent abstract syntax trees (ASTs). The trees specify columnar selections of HEP data.
ast
module in Python
ast
module, thus it is convenient to base everything at least loosely on Python's ASTs to ease translation. ASTs in Python, however, are extremely dense with information important for a full-featured general programming language but not relevant or useful for our purposes in forming selections of columns.Select
, SelectMany
, Where
, etc.) are those of LINQ, so many of the AST nodes will need to represent these operators.ast
that does not affect static translation into a columnar selction is removed.The syntax/grammar definition is discussed here. Like Lisp, the language consists solely of s-expressions. S-expressions here represent AST nodes and are either atoms--which include literals and identifiers--or composites of other s-expressions. Literals and names are nearly identical to those in Python. Composites are of the form:
(<composite node type> <s-expression 1> <s-expression 2> <s-expression 3> ...)
They look like bare lists from Lisp, with the first element describing the type of AST node, and the rest of the elements being the components of the node.
All defined s-expressions are listed here, though this specification will be expanded in the future. The symbol *
is used as a suffix here in its regex meaning (i.e., zero or more of the object that it follows are expected). Except where there is a restriction explicitly mentioned in the templates below, any type of s-expression can used as an element of a composite s-expression.
Atomic s-expressions (atoms):
True
, False
, and None
Composite s-expressions:
(list <item>*)
(dict <keys> <values>)
keys
and values
must each be a list
(attr <object> <attribute>)
attribute
must be a string literal(subscript <object> <subscript>)
(call <function> <argument>*)
(if <condition> <then> <else>)
(<operator> <operand>)
<operator>
must be not
or ~
(<operator> <operand> <operand>)
<operator>
must be one of +
, -
, *
, /
, %
, **
, //
, and
, or
, &
, |
, ^
, <<
, >>
, ==
, !=
, <
, <=
, >
, >=
(lambda <arguments> <expression>)
arguments
must be a list
containing only variable names(Where <source> <predicate>)
predicate
must be a lambda
with one argument(Select <source> <selector>)
selector
must be a lambda
with one argument(SelectMany <source> <selector>)
selector
must be a lambda
with one argument(First <source>)
(Last <source>)
(ElementAt <source> <index>)
index
must be an integer(Contains <source> <value>)
(Aggregate <source> <seed> <func>)
func
must be a lambda
with two arguments(Count <source>)
(Max <source>)
(Min <source>)
(Sum <source>)
(All <source> <predicate>)
predicate
must be a lambda
with one argument(Any <source> <predicate>)
predicate
must be a lambda
with one argument(Concat <first> <second>)
(Zip <source>)
(OrderBy <source> <key_selector>)
key_selector
must be a lambda
with one argument(OrderByDescending <source> <key_selector>)
key_selector
must be a lambda
with one argument(Choose <source> <n>)
n
must be an integerThe following query for eight columns:
data_column_source.Select("lambda Event: (Event.Electrons.pt(),
Event.Electrons.eta(),
Event.Electrons.phi(),
Event.Electrons.e(),
Event.Muons.pt(),
Event.Muons.eta(),
Event.Muons.phi(),
Event.Muons.e())")
becomes
(Select data_column_source
(lambda (list Event)
(list (call (attr (attr Event 'Electrons') 'pt'))
(call (attr (attr Event 'Electrons') 'eta'))
(call (attr (attr Event 'Electrons') 'phi'))
(call (attr (attr Event 'Electrons') 'e'))
(call (attr (attr Event 'Muons') 'pt'))
(call (attr (attr Event 'Muons') 'eta'))
(call (attr (attr Event 'Muons') 'phi'))
(call (attr (attr Event 'Muons') 'e')))))
See this Jupyter notebook for a more thorough example.
The mapping between Python and qastle expressions is not strictly one-to-one. There are some Python nodes with more specific functionality than needed in the textual AST representation. For example, all Python tuple
s are converted to (list)
s by qastle.
FAQs
Query AST Language Expressions
We found that qastle demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.