input-remapper icon indicating copy to clipboard operation
input-remapper copied to clipboard

local variables

Open sezanzeb opened this issue 3 years ago • 1 comments

Currently, variables are global across all injections. This can cause issues if a variable is expected to be empty when applying a preset.

An alternative to the $ symbol could be used to query a local variable. ^foo, &bar or *qux or whatever, idk. And we would probably need set_local(foo, 1). Not very beautiful...

or there could be a macro that should run when applying a preset which resets all variables. cumbersome

sezanzeb avatar Apr 21 '22 11:04 sezanzeb

or

# For global variables that are available across all injection processes and remembered forever.
# Migrate all existing `set` macro calls to `set(shared.bar, 2)`,
# basically just replace `set(` with `set(shared.` and `$` with `$shared.`
set(shared.foo, 2) 
$shared.foo

# for local variables. Initialized with None when applying a preset.
set(bar, 2)
$bar

I like this

sezanzeb avatar Apr 21 '22 11:04 sezanzeb

in the migration, only add shared. to $foo if $foo occurs multiple times in all presets

sezanzeb avatar Oct 17 '22 07:10 sezanzeb

so, a few weeks ago I had a crazy Idea: Let's see if it is possible to use python as the macro language turns out, it totally is. Have a look at this: https://github.com/jonasBoss/key-mapper/commit/38972389822fdb33f5fcb06cf73c26d7a54d1f8d I know this is a huge security risk, which is why I didn't pursue it further. But I think It is possible to make it safe by analyzing the AST and running it in a separate process. And the payoff would be infinite possibilities and the easy to use python syntax for macros.

Let me elaborate a bit on my proof of concept:

  • The Macro class will parse the code into a AST object
  • The FindSharedAndSanitize node-visitor will make sure there is no code which might be unsafe (currently import statements) and it will collect all names marked as global.
  • The ParseMacroCode node-transformer will replace Name nodes by an access to the shared dict if the name was marked as global.
  • exec the AST within a custom scope. The custom scope can provide functions for use inside the macro and restrict the access to builtin functions like open()
  • extract the newly created run method from the scope
  • during injection we can now call the run function to run the macro.

The node-transformer can also replace things like a call to sleep with a async call and make sure a run function always exists. We can also provide arguments like the triggering key to the run function and have different functions when the macro is triggered and when it is released.

This would make more complicated and currently impossible stuff like this https://github.com/sezanzeb/input-remapper/discussions/465 possible.

I am not sure if the AST parsing and the custom scope is enough to ensure the safety of the macro. But if we run the macro parsing and the functions defined by the macro inside a separate process without privileges this might be a good solution to most all of the macro related feature requests and issues.

jonasBoss avatar Oct 17 '22 10:10 jonasBoss

I think I read somewhere that overwriting the scope is not secure. I don't remember the reason.

inside a separate process without privileges

Yeah, sandboxing is the only way. If we sandbox it as a non-privileged user (make input-remapper create a new "macro" user), I don't think we need to sanitize anything. That macro user would have less access than the regular user. If a hacker makes input-remaper execute malicious code, they could as well just use the .profile file of a regular user to do the same and get more access by doing so.

sezanzeb avatar Oct 17 '22 22:10 sezanzeb

Discussion continues here: https://github.com/sezanzeb/input-remapper/issues/500

sezanzeb avatar Oct 18 '22 07:10 sezanzeb