Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/lib/msf/ui/text/dispatcher_shell_spec.rb
Views: 11766
require 'spec_helper'1require 'readline'23RSpec.describe Rex::Ui::Text::DispatcherShell do4let(:prompt) { '%undmsf6%clr' }5let(:prompt_char) { '%clr>' }6let(:subject) do7dummy_class = Class.new8dummy_class.include described_class9dummy_class.new(prompt, prompt_char)10end1112def mock_dispatcher_for(completions:)13dispatcher = double :mock_dispatcher14allow(dispatcher).to receive(:tab_complete_helper) do |_current_word, _preceding_words|15completions16end17dispatcher18end1920describe '#tab_complete' do21let(:dispatcher_stack) do22[23mock_dispatcher_for(completions: completions)24]25end2627before(:each) do28allow(subject).to receive(:dispatcher_stack).and_return(dispatcher_stack)29end3031context 'when tab completing options' do32let(:completions) { ['username=', 'password='] }33[34{ input: '', expected: nil },35{ input: ' ', expected: [' username=', ' password='] },36{ input: ' u', expected: [' username='] },37{ input: 'password=abc user', expected: ['password=abc username='] },38{ input: 'password=a\\ b\\ c user', expected: ['password=a\\ b\\ c username='] },39{ input: "'password=a b c' user", expected: ["'password=a b c' username="] },40{ input: "password='a b c' user", expected: ["password='a b c' username="] },41{ input: "password='a b c' user", expected: ["password='a b c' username="] },42{ input: 'username=', expected: ['username='] },43{ input: 'password=abc ', expected: ['password=abc username=', 'password=abc password='] }44].each do |test|45it "provides completion for #{test[:input].inspect}" do46expect(subject.tab_complete(test[:input])).to eql(test[:expected])47end48end49end5051context 'when tab completing paths' do52context 'when the paths are relative' do53let(:completions) { ['$Recycle.Bin', 'Program Files (x86)', 'Program Files', 'Documents and Settings'] }5455[56{ input: '', expected: nil },57{ input: 'cd ', expected: ['cd $Recycle.Bin', 'cd Program\\ Files\\ (x86)', 'cd Program\\ Files', 'cd Documents\\ and\\ Settings'] },58{ input: 'cd P', expected: ['cd Program\\ Files\\ (x86)', 'cd Program\\ Files'] },59{ input: "cd 'Progra", expected: ["cd 'Program Files (x86)'", "cd 'Program Files'"] },60{ input: 'cd "Program"', expected: ['cd "Program Files (x86)"', 'cd "Program Files"'] },61{ input: "cd 'Program Files", expected: ["cd 'Program Files (x86)'", "cd 'Program Files'"] },62{ input: "cd 'Program\\ Files", expected: [] },63{ input: "cd 'Program\\\\ Files", expected: [] },64{ input: 'cd Program\\ Files', expected: ['cd Program\\ Files\\ (x86)', 'cd Program\\ Files'] },65].each do |test|66it "provides completion for #{test[:input].inspect}" do67expect(subject.tab_complete(test[:input])).to eql(test[:expected])68end69end70end7172context 'when the paths are absolute' do73let(:completions) { ['C:\\$Recycle.Bin', 'C:\\Program Files (x86)', 'C:\\Program Files', 'C:\\Documents and Settings'] }7475[76{ input: '', expected: nil },77{ input: 'cd ', expected: ['cd C:\\\\$Recycle.Bin', 'cd C:\\\\Program\\ Files\\ (x86)', 'cd C:\\\\Program\\ Files', 'cd C:\\\\Documents\\ and\\ Settings'] },78{ input: 'cd C:', expected: ['cd C:\\\\$Recycle.Bin', 'cd C:\\\\Program\\ Files\\ (x86)', 'cd C:\\\\Program\\ Files', 'cd C:\\\\Documents\\ and\\ Settings'] },79{ input: "cd 'C:\\Progra", expected: ["cd 'C:\\Program Files (x86)'", "cd 'C:\\Program Files'"] },80{ input: 'cd "C:\\Program"', expected: ['cd "C:\\Program Files (x86)"', 'cd "C:\\Program Files"'] },81{ input: "cd 'C:\\Program Files", expected: ["cd 'C:\\Program Files (x86)'", "cd 'C:\\Program Files'"] },82{ input: "cd 'C:\\Program\\ Files", expected: [] },83{ input: "cd 'C:\\Program\\\\ Files", expected: [] },84{ input: 'cd C:\\\\Program\\ Files', expected: ['cd C:\\\\Program\\ Files\\ (x86)', 'cd C:\\\\Program\\ Files'] },85].each do |test|86it "provides completion for #{test[:input].inspect}" do87expect(subject.tab_complete(test[:input])).to eql(test[:expected])88end89end90end91end92end9394describe '#shellsplitex' do95[96{97input: '',98expected: {99tokens: [100]101}102},103104{105input: ' ',106focus: true,107expected: {108tokens: [109]110}111},112113{114input: 'foo bar',115focus: true,116expected: {117tokens: [118{ begin: 0, value: 'foo', quote: nil },119{ begin: 10, value: 'bar', quote: nil }120]121}122},123124{125input: 'dir',126expected: {127tokens: [128{ begin: 0, value: 'dir', quote: nil }129]130}131},132133{134input: 'dir "/"',135expected: {136tokens: [137{ begin: 0, value: 'dir', quote: nil },138{ begin: 4, value: '/', quote: '"' }139]140}141},142143{144input: 'dir "/',145expected: {146tokens: [147{ begin: 0, value: 'dir', quote: nil },148{ begin: 4, value: '/', quote: '"' }149]150}151},152153{154input: 'dir "/Program',155expected: {156tokens: [157{ begin: 0, value: 'dir', quote: nil },158{ begin: 4, value: '/Program', quote: '"' }159]160}161},162163{164input: 'dir "/Program/',165expected: {166tokens: [167{ begin: 0, value: 'dir', quote: nil },168{ begin: 4, value: '/Program/', quote: '"' }169]170}171},172173{174input: 'dir C:\\Pro',175expected: {176tokens: [177{ begin: 0, value: 'dir', quote: nil },178{ begin: 4, value: 'C:Pro', quote: nil }179]180}181},182183{184input: 'dir "C:\\Pro"',185expected: {186tokens: [187{ begin: 0, value: 'dir', quote: nil },188{ begin: 4, value: 'C:\\Pro', quote: '"' }189]190}191},192193{194input: "dir 'C:\\Pro'",195expected: {196tokens: [197{ begin: 0, value: 'dir', quote: nil },198{ begin: 4, value: 'C:\\Pro', quote: "'" }199]200}201},202203{204input: "dir 'C:\\ProgramData\\jim\\bob.rb'",205expected: {206tokens: [207{ begin: 0, value: 'dir', quote: nil },208{ begin: 4, value: 'C:\\ProgramData\\jim\\bob.rb', quote: "'" }209]210}211},212213{214input: "dir 'C:\\ProgramData\\jim\\'",215expected: {216tokens: [217{ begin: 0, value: 'dir', quote: nil },218{ begin: 4, value: 'C:\\ProgramData\\jim\\', quote: "'" }219]220}221},222223{224input: 'dir "C:\\Pro',225expected: {226tokens: [227{ begin: 0, value: 'dir', quote: nil },228{ begin: 4, value: 'C:\\Pro', quote: '"' }229]230}231},232233{234input: 'dir "C: \\Pro',235expected: {236tokens: [237{ begin: 0, value: 'dir', quote: nil },238{ begin: 4, value: 'C: \\Pro', quote: '"' }239]240}241},242243{244input: 'dir "C:\\Program F',245expected: {246tokens: [247{ begin: 0, value: 'dir', quote: nil },248{ begin: 4, value: 'C:\\Program F', quote: '"' },249]250}251},252253{254input: 'cd C:\\\\Program\\ F',255expected: {256tokens: [257{ begin: 0, value: 'cd', quote: nil },258{ begin: 4, value: 'C:\\Program F', quote: nil },259]260}261},262263{264input: 'cd "C:\\Program F',265expected: {266tokens: [267{ begin: 0, value: 'cd', quote: nil },268{ begin: 4, value: 'C:\\Program F', quote: '"' },269]270}271},272273{274input: "cd 'C:\\\\Program F",275expected: {276tokens: [277{ begin: 0, value: 'cd', quote: nil },278{ begin: 4, value: 'C:\\Program F', quote: "'" },279]280}281},282283{284input: "cd 'Progra",285expected: {286tokens: [287{ begin: 0, value: 'cd', quote: nil },288{ begin: 4, value: 'Progra', quote: "'" },289]290}291},292293{294input: 'pass=a\\ b\\ c user',295expected: {296tokens: [297{ begin: 0, value: 'pass=a b c', quote: nil },298{ begin: 13, value: 'user', quote: nil },299]300}301},302303{304input: "'pass=a b' username=\"",305expected: {306tokens: [307{ begin: 0, value: 'pass=a b', quote: "'" },308{ begin: 11, value: 'username=', quote: '"' },309]310}311},312313{314input: "pass='a b' user",315expected: {316tokens: [317{ begin: 0, value: 'pass=a b', quote: "'" },318{ begin: 11, value: 'user', quote: nil },319]320}321},322].each do |test|323it "correctly parses #{test[:input]}" do324expect(subject.shellsplitex(test[:input])).to eql(test[:expected])325end326end327end328end329330331