Hacker News new | past | comments | ask | show | jobs | submit login
Writing a Polyglot Script (nkanaev.github.io)
88 points by BerislavLopac on Jan 25, 2020 | hide | past | favorite | 18 comments



Not exactly a polyglot script, but a while back I had to work on a cluster whose job management system always ran everything as shell scripts. Or rather, it had to be run as a shell script in order to set the right cluster options. I wanted to submit an R script, so what did I do? I wrote a file that was both a bash script and an R script. When run as an R script, it does what I want it to do. When run as a bash script, it runs itself as an R script (after setting the cluster options). Problem "solved".

Here is is, if anyone's interested: https://gist.github.com/DarwinAwardWinner/2eb3705fb6ddab08ee...

And here's the Python version: https://gist.github.com/DarwinAwardWinner/8a631d897d45f00552...


Wouldn't it have been easier to submit:

    #!/bin/bash
    Rscript myscript.R


They may have only been able to submit the single file to the system. (In which case I would have generated the Rscript to a tmpfile, but maybe that wasn't allowed either.)


No, I totally could have written a separate R script that was then run by the bash script. I just wanted to have it all in one file, and I thought it was a fun challenge figuring out how to do it.


I've been collected hacks for a couple languages and tools here: https://git.io/shebang


I think the difference with mine is that I actually need to squeeze some shell code in there as well, to set up the cluster environment before "handing off" to R/Python.


Slightly modified so that it runs either a Ruby file or a Python one:

  (0 and eval(IO.read("ruby.rb"))) or eval(compile(open("python.py").read(), "", "exec"))
Granted, this doesn’t close the Python file, which is delayed until garbage collection or program termination.


You could also do `__import__("/abs/path/to/python.py")` (I think, I'm not completely sure on the rules for passing paths to `__import__`)


  /*<?php
  //*/public class PhpJava { public static void main(String[] args) { System.out.printf("/*%s",
  //\u000A\u002F\u002A
  class PhpJava {
      static function main() {
          echo(//\u000A\u002A\u002F
          "Hello World!");
  }}
  //\u000A\u002F\u002A
  PhpJava::main();
  //\u000A\u002A\u002F
It's both valid PHP and Java.

Not mine, stolen from https://gist.github.com/forairan/b1143f42883b3b0ee1237bc9bd0....


On a similar topic, PoC||GTFO [0] features files that are valid with multiple file formats. Issue 19 [1], for instance, "is valid as a PDF document, a ZIP archive, and a HTMLpage. It is also available as a Windows PE executable, a PNG image and an MP4 video" (see "technical note"). They are made by Ange Albertini [2] who has a great talk [3] on how he does this kind of things

[0] https://www.alchemistowl.org/pocorgtfo/ [1] https://www.alchemistowl.org/pocorgtfo/pocorgtfo19.pdf [2] https://github.com/angea/pocorgtfo [3] https://www.youtube.com/watch?v=W9WnnMJ0RKg


What I would like to see is a way to use multiple languages within the same script, to use the different abilities of different languages. For eg: Query a database via Ruby using ActiveRecord, then do some number crunching in Python using numPy or Pandas, and finally plot some statistical charts using R.

Jupyter's multiple language kernels come close to this, but not quite.


You can do this with GraalVM. Here's an example: https://github.com/graalvm/graalvm-demos/tree/master/polyglo...

And here's a polyglot notebook example: https://fniephaus.com/2019/px19-polyglot-notebooks.pdf

And finally, here's our GraalVM-powered Jupyter kernel: https://github.com/hpi-swa/ipolyglot


Bonus points if someone makes it into a polyglot quine somehow



Behold my masterpiece

  p='"%s"';r="'%s'";_='p=%s;r=%s;_=%s;print(_%%((0and[r%%p,p%%r,r%%_])or(tuple([r%%p,p%%r,r%%_]))))';print(_%((0and[r%p,p%r,r%_])or(tuple([r%p,p%r,r%_]))))
with inspiration from https://stackoverflow.com/q/6223285 and https://stackoverflow.com/a/2475931


Almost since doesn't quite work in Ruby:

Evaluating:

    p='"%s"';r="'%s'";_='p=%s;r=%s;_=%s;print(_%%((0and[r%%p,p%%r,r%%_])or(tuple([r%%p,p%%r,r%%_]))))';print(_%((0and[r%p,p%r,r%_])or(tuple([r%p,p%r,r%_]))))
becomes:

    p='"%s"';r="'%s'";_='p=%s;r=%s;_=%s;print(_%%((0and[r%%p,p%%r,r%%_])or(tuple([r%%p,p%%r,r%%_]))))'%_]))))

Too many '%'s in some places


Wait, it doesn’t? What’s your setup?


In 2011 a PoC virus was described, that was a polyglot JS, VBS, Batch and MatLab: https://github.com/SPTHvx/SPTH/blob/master/articles/files/xs...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: