Skip to content

Commit 04a88b4

Browse files
authored
Refactor + security improvements (#8)
1 parent f42c309 commit 04a88b4

File tree

2 files changed

+52
-32
lines changed

2 files changed

+52
-32
lines changed

README.md

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,33 +74,41 @@ password = neveryoumind
7474
7575
# ↑ that config was there before
7676
# ↓ this config is what we added
77-
[client-mydb]
77+
[clientMyDb]
7878
database = mydb
7979
```
8080

8181
## Usage
8282

83-
Create a new file whose name ends with `.sql`, adding the following two lines in the very beginning of the file:
83+
Create a new file whose name ends with `.sql`, adding the following three lines in the very beginning of the file:
8484

8585
```sql
86-
-- --defaults-group-suffix=ExampleTest -t
86+
-- --defaults-group-suffix=ExampleTest
87+
-- -t
8788
--
8889
```
8990

90-
Then add your sql statements following the two lines. Here is a sample of the `sql` file:
91+
Notes:
92+
93+
- The first line with `--default-group-suffix` identifies the configuration **suffix**, defined above. i.e. we're entering `ExampleTest` not `ClientExampleTest`. To use the 2nd configuration example you'd use `--default-group-suffix=MyDb`.
94+
95+
- The -t option means output as a table. You can ommit this if you want bare output.
96+
97+
- Each mysql option **must** be on its own line.
98+
99+
Then add your sql statements following the three lines. Here is a sample of the `sql` file:
91100

92101
```sql
93-
-- --defaults-group-suffix=ExampleTest -t
102+
-- --defaults-group-suffix=ExampleTest
103+
-- -t
94104
--
95-
96-
select * from user;
97-
```
98105

99-
**Note**: The `--default-group-suffix` option is a *suffix*, i.e. we're entering `ExampleTest` not `ClientExampleTest`. To use the 2nd configuration example you'd use `--default-group-suffix=mydb`.
106+
SELECT * FROM USER;
107+
```
100108

101109
- Move the caret to the line `select * from user;` and type `<leader>rr` in VIM normal mode to run the line;
102110

103-
- Move the caret to the table name (such as `user`) and type `<leader>ds` (stands for "Describe") to show the columns of the table, type `<leader>ss` to `select *` from the table;
111+
- Move the caret to the table name (such as `user`) and type `<leader>ds` (stands for "Descript") to show the columns of the table, type `<leader>ss` to `SELECT *` from the table;
104112

105113
- Using VIM visual mode to select a range of statement and type `<leader>rs` to execute the selected statements;
106114

@@ -116,6 +124,16 @@ If you find it difficult to use this plugin, please open issues or help to impro
116124

117125
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
118126
<!-- prettier-ignore -->
119-
| [<img src="https://avatars3.githubusercontent.com/u/15965696?v=4" width="50px;"/><br /><sub><b>kezhenxu94</b></sub>](https://kezhenxu94.me)<br />[💻](https://github.com/kezhenxu94/vim-mysql-plugin/commits?author=kezhenxu94 "Code") | [<img src="https://avatars2.githubusercontent.com/u/13188781?v=4" width="50px;"/><br /><sub><b>jfecher</b></sub>](http://antelang.org/)<br />[💻](https://github.com/kezhenxu94/vim-mysql-plugin/commits?author=jfecher "Code") |
127+
| [<img src="https://avatars3.githubusercontent.com/u/15965696?v=4" width="50px;"/><br /><sub><b>kezhenxu94</b></sub>](https://kezhenxu94.me)<br />[💻](https://github.com/kezhenxu94/vim-mysql-plugin/commits?author=kezhenxu94 "Code") | [<img src="https://avatars2.githubusercontent.com/u/13188781?v=4" width="50px;"/><br /><sub><b>jfecher</b></sub>](http://antelang.org/)<br />[💻](https://github.com/kezhenxu94/vim-mysql-plugin/commits?author=jfecher "Code")<br />[Artful Robot](https://artfulrobot.uk) |
120128
| :---: | :---: |
121129
<!-- ALL-CONTRIBUTORS-LIST:END -->
130+
131+
## Change log
132+
133+
- Security improvement: all shell commands are escaped with shellescape(). This means MySQL command options must now be one-per-line.
134+
135+
- Security improvement: Previously SQL with double quotes `"` that was run with `<Leader>rr` would escape the shell argument, meaning the following code was run in the shell(!). This would potentially do very bad things.
136+
137+
- Code refactor: all SQL execution now uses the same method (write it to a /tmp file and `<` redirect it into the command; we no longer use `-e` with SQL on the command line)
138+
139+
- Timings: An additional query is run to report on the execution time.

plugin/vim-mysql-plugin.vim

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
" Plugin: vim-mysql-plugin
22
" Author: Ke Zhenxu <[email protected]>
3-
" License: GPL
3+
" License: Apache License, Version 2.0
44
" Origin: https://github.com/kezhenxu94/vim-mysql-plugin
55

66
if exists("g:vim_mysql_plugin_loaded") || &cp
@@ -40,50 +40,52 @@ fun! g:GetSelection()
4040
return lines
4141
endfun
4242

43-
fun! g:RunSelection()
44-
let l:Selection = g:GetSelection()
45-
if len(l:Selection) == 0
43+
fun! g:RunArray(sqlarray, timing)
44+
if len(a:sqlarray) == 0
4645
echohl Error | echon 'Nothing Selected' | echohl None
4746
return
4847
endif
49-
call writefile(l:Selection, '/tmp/vim-mysql-plugin.sql')
5048

51-
let l:Command = s:GetCommand() . ' < ' . '/tmp/vim-mysql-plugin.sql'
52-
let l:Command = escape(l:Command, '%#\`')
49+
if a:timing
50+
let l:thesql = ['SELECT NOW(3)+0 INTO @startTime;'] + a:sqlarray + ['SELECT CONCAT(ROUND(NOW(3) - @startTime, 3), "s") Took']
51+
else
52+
let l:thesql = a:sqlarray
53+
endif
54+
call writefile(l:thesql, '/tmp/vim-mysql-plugin.sql')
55+
let l:Command = s:GetCommand() . ' </tmp/vim-mysql-plugin.sql'
5356
call g:RunShellCommand(l:Command)
5457
endf
5558

59+
fun! g:RunSelection()
60+
let l:Selection = g:GetSelection()
61+
call g:RunArray(l:Selection, 1)
62+
endfun
63+
64+
5665
func! g:SelectCursorTable()
57-
let l:Table = '`' . expand('<cword>') . '`'
58-
let l:Command = s:GetCommand() . ' -e ' . '"select * from ' . l:Table . '"'
59-
let l:Command = escape(l:Command, '$!%#\`')
60-
call g:RunShellCommand(l:Command)
66+
let l:Table = expand('<cword>')
67+
call RunArray(['SELECT * FROM `' . l:Table . '` LIMIT 100;'], 0)
6168
endfun
6269

6370
func! g:DescriptCursorTable()
64-
let l:Table = '`' . expand('<cword>') . '`'
65-
let l:Command = s:GetCommand() . ' -e ' . '"show full columns from ' . l:Table . '"'
66-
let l:Command = escape(l:Command, '$!%#\`')
67-
call g:RunShellCommand(l:Command)
71+
let l:Table = expand('<cword>')
72+
call RunArray(['SHOW FULL COLUMNS FROM `' . l:Table . '`;'], 0)
6873
endfun
6974

7075
fun! g:RunInstruction()
7176
let l:PrevSemicolon = search(';', 'bnW')
7277
let l:NextSemicolon = search(';', 'nW')
7378
let l:Lines = getline(l:PrevSemicolon, l:NextSemicolon)[1:]
74-
let l:Lines = map(l:Lines, "substitute(v:val, '--.*$', '', 'g')")
75-
let l:CurrentInstruction = join(l:Lines, ' ')
76-
let l:Command = s:GetCommand() . ' -e "' . l:CurrentInstruction . '"'
77-
let l:Command = escape(l:Command, '$!%#\`')
78-
call g:RunShellCommand(l:Command)
79+
call g:RunArray(l:Lines, 1)
7980
endfun
8081

8182
fun! s:GetCommand()
8283
let l:Command = 'mysql '
8384
let l:LineNum = 1
8485
let l:Line = getline(l:LineNum)
8586
while l:Line != '--'
86-
let l:Command .= substitute(l:Line, '^--\s*\(.*\)$', '\1', 'g')
87+
let l:arg = shellescape(substitute(l:Line, '^--\s*\(.*\)$', '\1', 'g'))
88+
let l:Command .= l:arg . ' '
8789
let l:LineNum = l:LineNum + 1
8890
let l:Line = getline(l:LineNum)
8991
endwhile

0 commit comments

Comments
 (0)