Mis-code-ception


Radosław Bułat, github.com/radarek
KRUG, 17.10.2022

The goal is to

have fun

with unusual code.

Agenda

  • Does Ruby understand SQL?
  • How to check if a number is prime using regex?
  • Writing code using only symbol characters.
  • Deceptive code.

Does Ruby understand SQL?

SELECT `tags`.* FROM `tags`
[1] pry(main)> SELECT `tags`.* FROM `tags`
Errno::ENOENT: No such file or directory - tags
from (pry):1:in ``'

Do you see something interesting?

SELECT `tags`.* FROM `tags`

This SQL is syntatically valid Ruby code!

SELECT(`tags`.*(FROM(`tags`)))
`tags` # call system command "tags"
SELECT, FROM # method call
`x.*(y)` # x * y

Constant vs method

Array(1)   # method
Array()    # method
Array 1    # method
Array      # constant
Array.new  # constant.method

What about other SQL commands?

DROP TABLE IF EXISTS `tags`;
CREATE TABLE `tags`
  (id int);
ALTER TABLE `tags`
  ADD COLUMN name varchar(255);
INSERT INTO `tags`
  VALUES(1, "krug");
INSERT INTO `tags`
  VALUES(2, "ruby");
INSERT INTO `tags`
  VALUES(3, "programming");
SELECT `tags`.* FROM `tags`;
SELECT `tags`.* FROM `tags`
  WHERE name LIKE "%u%";
$ mysql -h host.docker.internal magic < demo.sql
id      name
1       krug
2       ruby
3       programming
id      name
1       krug
2       ruby
$ ruby -r./sql demo.sql
id      name
1       krug
2       ruby
3       programming
id      name
1       krug
2       ruby

Implementation idea

def DROP(...); end
def SELECT(...); end
# etc.

Conclusions

  • Methods can have capital letters.
  • Ruby distinguishes them from constants on syntax level.
  • A method and a constant with the same names can coexist.

How to check if a number is prime using regex?

What is a prime number?

It is an integer number > 1 that is divisible only by itself and 1.

6 is not prime because it is divisible by 1, 2, 3 and 6.

7 is prime because it is divisible only by 1 and 7.

Regex? Like this?

def prime?(n)
  n.to_s.match? /^(2|3|5|7)$/
end
(0..100).select { prime?(_1) }
#=> [2, 3, 5, 7]

What about 11, 13 and others?

There is something more clever.

Ready?

def prime?(n)
  '1'*n !~ /^1?$|^(11+?)\1+$/
end
(0..100).select { prime?(_1) }
#=> [2, 3, 5, 7, 11, (...), 89, 97]

How does it work?

'1'*n !~ /^1?$|^(11+?)\1+$/

What about performance?

'1111111' =~ /^(11+?)\1+$/

Conclusions

  • Regexes are usefull but can be tricky
  • Always test your regexes with different inputs
  • Think about worst cases
  • Don’t use it for primary number checking ;)
  • Read the book “Mastering Regular Expressions”

Writing code using only symbol characters.

Is it possible to write any Ruby code using only these characters?

!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Let’s start with something simple.

How to construct any string without using letters?

"Hello"

=>

"?????"

String#<<

https://ruby-doc.org/core-3.1.2/String.html#method-i-3C-3C
''<<72<<101<<108<<108<<111
#=> "Hello"

How to create any integer using only symbol characters?

1

=>

?

$$/$$
'$'=~/$/
-~($$[-$$])
'>'<=>'<'
$$[-$$]**$$[-$$]
_=$$/$$ #=> 1
__=_+_  #=> 2

H - 72

_+_...+_ # repeat 72 times
# or
(__*(__*(__*(__*(__*(__*_))+_))))

_=$$/$$;__=_+_;''<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)))+_))))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)+_)+_)

How to execute code from a string?

eval(string)

_=$$/$$;__=_+_
p eval(''<<(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_))))

What about symbolizing eval?

Ready?

->(&_){
  _['','eval','<code>']
}[&:"#{'send'}"]

source: https://youtu.be/6K7EmeptEHo?t=574

Let’s write a compiler.

def decompose(n)
  n == 0 ? '(_-_)' : '('+'__*'+decompose(n/2)+'+_'*(n%2)+')'
end

def s(str)
  ["''", *str.chars.map { decompose(_1.ord) }].join('<<')
end

def compile(code)
  "_=$$/$$;__=_+_;->(&___){___[''," +
  "#{s('eval')},#{s(code)}]}[&:\"\#{#{s('send')}}\"]"
end

puts compile(ARGF.read)
$ ruby compiler.rb helloworld.rb

_=$$/$$;__=_+_;->(&___){___['',''<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_))+_)+_))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_))),''<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_)))))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_))+_))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_))+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_)))+_)+_)<<(__*(__*(__*(__*(__*(__*(_-_)+_))))))<<(__*(__*(__*(__*(__*(__*(_-_)+_))))+_))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)))+_))))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)+_)+_)<<(__*(__*(__*(__*(__*(__*(_-_)+_))))))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_))+_))+_)+_)+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)+_)+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_)))+_))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_)))<<(__*(__*(__*(__*(__*(__*(_-_)+_)))))+_)<<(__*(__*(__*(__*(__*(__*(_-_)+_))))+_))<<(__*(__*(__*(__*(_-_)+_))+_))]}[&:"#{''<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)+_)))+_)+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_))+_)<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_))+_)+_)+_))<<(__*(__*(__*(__*(__*(__*(__*(_-_)+_)+_)))+_)))}"]

$ ruby compiler.rb helloworld.rb  | ruby
Hello World!

What if…

$ ruby compiler.rb compiler.rb > compiler2.rb

Conclusions

  • Generating code is fun
  • Generating useless code is uber fun ;)

Deceptive code

$ ls
innocent_code.rb
$ ruby innocent_code.rb 
This code is evil

Oh no 😱!

$ cat innocent_code.rb
puts "This code is innocent"

How?

File.write(__FILE__, <<CODE)
puts "This code is innocent"
CODE
puts "This code is evil"
$ ls
innocent_code2.rb
$ cat innocent_code2.rb
puts "This code is innocent"
$ more innocent_code2.rb
puts "This code is innocent"
$ ruby innocent_code2.rb
This code is evil
$ cat innocent_code2.rb
puts "This code is innocent"

How?

puts "This code is evil"||"^H^H^H^H^H^H^H^Hinnocent"

Conclusions

  • Don’t trust your intuition
  • If you think you know how something works then … you may be wrong

Thank you!