neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

secure.c (2875B)


      1 #include <lua.h>
      2 #include <stdbool.h>
      3 #include <string.h>
      4 
      5 #include "nvim/ascii_defs.h"
      6 #include "nvim/charset.h"
      7 #include "nvim/errors.h"
      8 #include "nvim/ex_cmds_defs.h"
      9 #include "nvim/gettext_defs.h"
     10 #include "nvim/lua/executor.h"
     11 #include "nvim/lua/secure.h"
     12 #include "nvim/memory.h"
     13 #include "nvim/message.h"
     14 
     15 #include "lua/secure.c.generated.h"
     16 
     17 char *nlua_read_secure(const char *path)
     18 {
     19  lua_State *const lstate = get_global_lstate();
     20  const int top = lua_gettop(lstate);
     21 
     22  lua_getglobal(lstate, "vim");
     23  lua_getfield(lstate, -1, "secure");
     24  lua_getfield(lstate, -1, "read");
     25  lua_pushstring(lstate, path);
     26  if (nlua_pcall(lstate, 1, 1)) {
     27    nlua_error(lstate, _("vim.secure.read: %.*s"));
     28    lua_settop(lstate, top);
     29    return NULL;
     30  }
     31 
     32  size_t len = 0;
     33  const char *contents = lua_tolstring(lstate, -1, &len);
     34  char *buf = NULL;
     35  if (contents != NULL) {
     36    // Add one to include trailing null byte
     37    buf = xcalloc(len + 1, sizeof(char));
     38    memcpy(buf, contents, len + 1);
     39  }
     40 
     41  lua_settop(lstate, top);
     42  return buf;
     43 }
     44 
     45 static bool nlua_trust(const char *action, const char *path)
     46 {
     47  lua_State *const lstate = get_global_lstate();
     48  const int top = lua_gettop(lstate);
     49 
     50  lua_getglobal(lstate, "vim");
     51  lua_getfield(lstate, -1, "secure");
     52  lua_getfield(lstate, -1, "trust");
     53 
     54  lua_newtable(lstate);
     55  lua_pushstring(lstate, "action");
     56  lua_pushstring(lstate, action);
     57  lua_settable(lstate, -3);
     58  if (path == NULL) {
     59    lua_pushstring(lstate, "bufnr");
     60    lua_pushnumber(lstate, 0);
     61    lua_settable(lstate, -3);
     62  } else {
     63    lua_pushstring(lstate, "path");
     64    lua_pushstring(lstate, path);
     65    lua_settable(lstate, -3);
     66  }
     67 
     68  if (nlua_pcall(lstate, 1, 2)) {
     69    nlua_error(lstate, _("vim.secure.trust: %.*s"));
     70    lua_settop(lstate, top);
     71    return false;
     72  }
     73 
     74  bool success = lua_toboolean(lstate, -2);
     75  const char *msg = lua_tostring(lstate, -1);
     76  if (msg != NULL) {
     77    if (success) {
     78      if (strcmp(action, "allow") == 0) {
     79        smsg(0, "Allowed in trust database: \"%s\"", msg);
     80      } else if (strcmp(action, "deny") == 0) {
     81        smsg(0, "Denied in trust database: \"%s\"", msg);
     82      } else if (strcmp(action, "remove") == 0) {
     83        smsg(0, "Removed from trust database: \"%s\"", msg);
     84      }
     85    } else {
     86      semsg(e_trustfile, msg);
     87    }
     88  }
     89 
     90  lua_settop(lstate, top);
     91  return success;
     92 }
     93 
     94 void ex_trust(exarg_T *eap)
     95 {
     96  const char *const p = skiptowhite(eap->arg);
     97  char *arg1 = xmemdupz(eap->arg, (size_t)(p - eap->arg));
     98  const char *action = "allow";
     99  const char *path = skipwhite(p);
    100 
    101  if (strcmp(arg1, "++deny") == 0) {
    102    action = "deny";
    103  } else if (strcmp(arg1, "++remove") == 0) {
    104    action = "remove";
    105  } else if (*arg1 != NUL) {
    106    semsg(e_invarg2, arg1);
    107    goto theend;
    108  }
    109 
    110  if (path[0] == NUL) {
    111    path = NULL;
    112  }
    113 
    114  nlua_trust(action, path);
    115 
    116 theend:
    117  xfree(arg1);
    118 }