
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
PATM is extremely faster pattern match library.
Features: Match value/classes, Capture, Array/Hash decomposition.
require 'patm'
# With DSL
class A
extend ::Patm::DSL
define_matcher :match1 do|r|
p = Patm
r.on [:x, p._1, p._2] do|m|
[m._1, m._2]
end
end
define_matcher :match2 do|r|
r.on [:a, Patm._xs & Patm._1] do|m, _self|
_self.match1(m._1)
end
# ...
r.else do
nil
end
end
end
A.new.match1([:x, 1, 2])
# => [1, 2]
# With case(simple but slow)
def match(obj)
p = Patm
_xs = Patm._xs
case obj
when m = Patm.match([:x, p._1, p._2])
[m._2, m._1]
when m = Patm.match([1, _xs&p._1])
m._1
end
end
match([1, 2, 3])
# => [2, 3]
match([:x, :y, :z])
# => [:z, :y]
match([])
# => nil
# With pre-built Rule
rule = Patm::Rule.new do|r|
p = Patm
_xs = Patm._xs
r.on [:x, p._1, p._2] do|m|
[m._2, m._1]
end
r.on [1, _xs&p._1] do|m|
m._1
end
end
rule.apply([1,2,3])
# => [2, 3]
rule.apply([:x, :y, :z])
# => [:z, :y]
rule.apply([])
# => nil
class PatternMatcher
extend Patm::DSL
define_matcher(:match) do|r| # r is instance of Patm::Rule
# r.on( PATTERN ) {|match, _self|
# First argument is instance of Patm::Match. Use it to access captured value.
# ex. m._1, m._2, ..., m[capture_name]
#
# Second argument is instance of the class. Use it to access other methods.
# ex. _self.other_method
# }
#
# r.else {|value, _self|
# First argument is the value. Second is instance of the class.
# }
end
end
matcher = PatternMatcher.new
matcher.match(1)
Value patterns such as 1, :x, String, ...
matches if pattern === target_value
is true.
A = Struct.new(:x, :y)
# ...
define_matcher :match_struct do|r|
# use Patm[struct_class].( ... ) for match struct
# argument is a Hash(member_name => pattern) or patterns that correspond struct members.
r.on Patm[A].(x: 1, y: Patm._1) {|m| m._1 }
r.on Patm[A].(2, Patm._1) {|m| m._1 }
end
[1, 2, _any]
matches [1, 2, 3]
, [1, 2, :x]
, etc.
[1, 2, _xs]
matches [1, 2]
, [1, 2, 3]
, [1, 2, 3, 4]
, etc.
[1, _xs, 2]
matches [1, 2]
, [1, 10, 2]
, etc.
Note: More than one _xs
in same array is invalid.
{a: 1}
matches {a: 1}
, {a: 1, b: 2}
, etc.
{a: 1, Patm.exact => true}
matches only {a: 1}
.
{a: 1, b: Patm.opt(2)}
matches {a: 1}
, {a: 1, b: 2}
.
_1
, _2
, etc matches any value, and capture the value as correspond match group.
Pattern#[capture_name]
also used for capture.Patm._any[:foo]
capture any value as foo
.
Captured values are accessible through Match#_1, _2, ...
and Match#[capture_name]
_1&[_any, _any]
matches any two element array, and capture the array as _1.
Patm.or(1, 2)
matches 1 or 2.
see benchmark code for details
Machine: MacBook Air(Late 2010) C2D 1.8GHz, OS X 10.9.2
RUBY_VERSION: 2.1.2 p95
Benchmark: Empty(x10000)
user system total real
manual 0.010000 0.000000 0.010000 ( 0.012252)
patm 0.060000 0.000000 0.060000 ( 0.057050)
pattern_match 1.710000 0.010000 1.720000 ( 1.765749)
Benchmark: SimpleConst(x10000)
user system total real
manual 0.020000 0.000000 0.020000 ( 0.018274)
patm 0.060000 0.000000 0.060000 ( 0.075068)
patm_case 0.160000 0.000000 0.160000 ( 0.161002)
pattern_match 1.960000 0.020000 1.980000 ( 2.007936)
Benchmark: ArrayDecomposition(x10000)
user system total real
manual 0.050000 0.000000 0.050000 ( 0.047948)
patm 0.250000 0.000000 0.250000 ( 0.254039)
patm_case 1.710000 0.000000 1.710000 ( 1.765656)
pattern_match 12.890000 0.060000 12.950000 ( 13.343334)
Benchmark: VarArray(x10000)
user system total real
manual 0.050000 0.000000 0.050000 ( 0.052425)
patm 0.210000 0.000000 0.210000 ( 0.223190)
patm_case 1.440000 0.000000 1.440000 ( 1.587535)
pattern_match 10.050000 0.070000 10.120000 ( 10.898683)
else
, Patm::NoMatchError
raised(Instead of return nil).Patm._1 & Array
.pattern[number_or_name]
or Patm._1, _2, ...
instead.[Patm.or()]
FAQs
Unknown package
We found that patm demonstrated a not healthy version release cadence and project activity because the last version was released 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
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.