Fix: keyIn gets NL
This commit is contained in:
parent
4037ba9845
commit
6dffd81b65
6 changed files with 50 additions and 33 deletions
|
@ -252,12 +252,3 @@ Why did I choose it? :
|
||||||
|
|
||||||
+ The good modules (native addon) for synchronous execution exist. But node-gyp can't compile those in some platforms or Node versions.
|
+ The good modules (native addon) for synchronous execution exist. But node-gyp can't compile those in some platforms or Node versions.
|
||||||
+ I think that the security is important more than the speed. Some modules have problem about security. (Those don't protect data.) I think that the speed is not needed usually, because readlineSync is used while user types keys.
|
+ I think that the security is important more than the speed. Some modules have problem about security. (Those don't protect data.) I think that the speed is not needed usually, because readlineSync is used while user types keys.
|
||||||
|
|
||||||
## Release History
|
|
||||||
* 2015-02-22 v0.6.0 Add `setBufferSize()`.
|
|
||||||
* 2015-02-12 v0.5.5 Support the Synchronous Process Execution of Node v0.12(v0.11).
|
|
||||||
* 2015-01-27 v0.5.0 Add `options.noTrim`.
|
|
||||||
* 2014-07-12 v0.4.0 Add `options.noEchoBack`.
|
|
||||||
* 2014-07-12 v0.3.0 Add `setPrint()`.
|
|
||||||
* 2013-08-30 v0.2.0 Rewrite exporting methods.
|
|
||||||
* 2013-08-29 v0.1.0 Initial release.
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* readlineSync
|
||||||
|
* https://github.com/anseki/readline-sync
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 anseki
|
||||||
|
* Licensed under the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
var cipher = require('crypto').createCipher(
|
var cipher = require('crypto').createCipher(
|
||||||
process.argv[2] /*algorithm*/, process.argv[3] /*password*/),
|
process.argv[2] /*algorithm*/, process.argv[3] /*password*/),
|
||||||
stdin = process.stdin,
|
stdin = process.stdin,
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
/*jshint wsh:true */
|
/* jshint wsh:true */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readlineSync
|
||||||
|
* https://github.com/anseki/readline-sync
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 anseki
|
||||||
|
* Licensed under the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
var
|
var
|
||||||
FSO_ForReading = 1, FSO_ForWriting = 2,
|
FSO_ForReading = 1, FSO_ForWriting = 2,
|
||||||
|
|
20
lib/read.ps1
20
lib/read.ps1
|
@ -1,3 +1,8 @@
|
||||||
|
# readlineSync
|
||||||
|
# https://github.com/anseki/readline-sync
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 anseki
|
||||||
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
Param(
|
Param(
|
||||||
[string] $display,
|
[string] $display,
|
||||||
|
@ -38,22 +43,23 @@ if ($options.encoded) {
|
||||||
[bool] $isCooked = (-not $options.noEchoBack) -and (-not $options.keyIn)
|
[bool] $isCooked = (-not $options.noEchoBack) -and (-not $options.keyIn)
|
||||||
|
|
||||||
function writeTTY ($text) {
|
function writeTTY ($text) {
|
||||||
execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline') | Out-Null
|
execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline')
|
||||||
$script:isInputLine = $True
|
$script:isInputLine = $True
|
||||||
}
|
}
|
||||||
|
|
||||||
# Instant method that opens TTY without CreateFile via P/Invoke in .NET Framework
|
# Instant method that opens TTY without CreateFile via P/Invoke in .NET Framework
|
||||||
# **NOTE** Don't include special characters of DOS in $command when $getRes is True.
|
# **NOTE** Don't include special characters of DOS in $command when $getRes is True.
|
||||||
|
# [string] $cmdPath = $Env:ComSpec
|
||||||
|
# [string] $psPath = 'powershell.exe'
|
||||||
function execWithTTY ($command, $getRes = $False) {
|
function execWithTTY ($command, $getRes = $False) {
|
||||||
if ($getRes) {
|
if ($getRes) {
|
||||||
$res = (cmd.exe /C "<CON powershell.exe -Command $command")
|
$res = (cmd.exe /C "<CON powershell.exe -Command $command")
|
||||||
if ($LastExitCode -ne 0) { exit 1 }
|
if ($LastExitCode -ne 0) { exit 1 }
|
||||||
|
return $res
|
||||||
} else {
|
} else {
|
||||||
$command | cmd.exe /C ">CON powershell.exe -Command -"
|
$command | cmd.exe /C ">CON powershell.exe -Command -"
|
||||||
if ($LastExitCode -ne 0) { exit 1 }
|
if ($LastExitCode -ne 0) { exit 1 }
|
||||||
$res = ''
|
|
||||||
}
|
}
|
||||||
return $res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($options.display -ne '') {
|
if ($options.display -ne '') {
|
||||||
|
@ -76,11 +82,11 @@ while ($True) {
|
||||||
# ReadKey() may returns [System.Array], then don't cast data.
|
# ReadKey() may returns [System.Array], then don't cast data.
|
||||||
if ($chunk -isnot [string]) { $chunk = '' }
|
if ($chunk -isnot [string]) { $chunk = '' }
|
||||||
$chunk = $chunk -replace '[\r\n]', ''
|
$chunk = $chunk -replace '[\r\n]', ''
|
||||||
if ($chunk -eq '') { $isEol = $True } # NL or empty-text was input
|
if ($chunk -eq '') { $atEol = $True } # NL or empty-text was input
|
||||||
} else {
|
} else {
|
||||||
$chunk = execWithTTY 'Read-Host' $True
|
$chunk = execWithTTY 'Read-Host' $True
|
||||||
$chunk = $chunk -replace '[\r\n]', ''
|
$chunk = $chunk -replace '[\r\n]', ''
|
||||||
$isEol = $True
|
$atEol = $True
|
||||||
}
|
}
|
||||||
|
|
||||||
# other ctrl-chars
|
# other ctrl-chars
|
||||||
|
@ -95,10 +101,10 @@ while ($True) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$inputTTY += $chunk
|
$inputTTY += $chunk
|
||||||
if ($isEol -or ($options.keyIn -and ($inputTTY.Length -ge $reqSize))) { break }
|
if ($atEol -or ($options.keyIn -and ($inputTTY.Length -ge $reqSize))) { break }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((-not $isCooked) -and (-not ($options.keyIn -and (-not $isInputLine))))
|
if ((-not $isCooked) -and (-not ($options.keyIn -and (-not $isInputLine))))
|
||||||
{ execWithTTY 'Write-Host ''''' | Out-Null } # new line
|
{ execWithTTY 'Write-Host ''''' } # new line
|
||||||
|
|
||||||
return '''' + $inputTTY + ''''
|
return '''' + $inputTTY + ''''
|
||||||
|
|
11
lib/read.sh
11
lib/read.sh
|
@ -1,3 +1,8 @@
|
||||||
|
# readlineSync
|
||||||
|
# https://github.com/anseki/readline-sync
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 anseki
|
||||||
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
# getopt(s)
|
# getopt(s)
|
||||||
while [ $# -ge 1 ]; do
|
while [ $# -ge 1 ]; do
|
||||||
|
@ -62,11 +67,11 @@ do
|
||||||
if [ -z "$is_cooked" ]; then
|
if [ -z "$is_cooked" ]; then
|
||||||
chunk="$(dd if=/dev/tty bs=1 count=1 2>/dev/null)"
|
chunk="$(dd if=/dev/tty bs=1 count=1 2>/dev/null)"
|
||||||
chunk="$(printf '%s' "$chunk" | tr -d '\r\n')"
|
chunk="$(printf '%s' "$chunk" | tr -d '\r\n')"
|
||||||
[ -z "$chunk" ] && is_eol='true' # NL or empty-text was input
|
[ -z "$chunk" ] && at_eol='true' # NL or empty-text was input
|
||||||
else
|
else
|
||||||
IFS= read -r chunk </dev/tty || exit $?
|
IFS= read -r chunk </dev/tty || exit $?
|
||||||
chunk="$(printf '%s' "$chunk" | tr -d '\r\n')"
|
chunk="$(printf '%s' "$chunk" | tr -d '\r\n')"
|
||||||
is_eol='true'
|
at_eol='true'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# other ctrl-chars
|
# other ctrl-chars
|
||||||
|
@ -83,7 +88,7 @@ do
|
||||||
fi
|
fi
|
||||||
|
|
||||||
input="$input$chunk"
|
input="$input$chunk"
|
||||||
if [ -n "$is_eol" ] || \
|
if [ -n "$at_eol" ] || \
|
||||||
( [ -n "$options_keyIn" ] && [ ${#input} -ge $req_size ] ); then break; fi
|
( [ -n "$options_keyIn" ] && [ ${#input} -ge $req_size ] ); then break; fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,9 @@ function readlineSync(options) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function() { // try read
|
(function() { // try read
|
||||||
var buffer, reqSize, readSize, chunk, isEol, line, exclude,
|
var atEol, exclude,
|
||||||
isCooked = !options.noEchoBack && !options.keyIn;
|
isCooked = !options.noEchoBack && !options.keyIn,
|
||||||
|
buffer, reqSize, readSize, chunk, line;
|
||||||
|
|
||||||
// Node v0.10- returns an error if same mode is set.
|
// Node v0.10- returns an error if same mode is set.
|
||||||
function setRawMode(mode) {
|
function setRawMode(mode) {
|
||||||
|
@ -140,7 +141,7 @@ function readlineSync(options) {
|
||||||
}
|
}
|
||||||
buffer = new Buffer((reqSize = options.keyIn ? 1 : bufSize));
|
buffer = new Buffer((reqSize = options.keyIn ? 1 : bufSize));
|
||||||
|
|
||||||
if (options.exclude) {
|
if (options.keyIn && options.exclude) {
|
||||||
exclude = new RegExp(options.exclude, 'g' + (options.cs ? '' : 'i'));
|
exclude = new RegExp(options.exclude, 'g' + (options.cs ? '' : 'i'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,16 +158,13 @@ function readlineSync(options) {
|
||||||
}
|
}
|
||||||
chunk = readSize > 0 ? buffer.toString(encoding, 0, readSize) : '\n';
|
chunk = readSize > 0 ? buffer.toString(encoding, 0, readSize) : '\n';
|
||||||
|
|
||||||
if (!isCooked) {
|
if (typeof(line = (chunk.match(/^(.*?)[\r\n]/) || [])[1]) === 'string') {
|
||||||
chunk = chunk.replace(/[\r\n]/g, '');
|
|
||||||
if (!chunk) { isEol = true; } // NL or empty-text was input
|
|
||||||
} else if (typeof(line = (chunk.match(/^(.*?)[\r\n]/) || [])[1]) === 'string') {
|
|
||||||
chunk = line;
|
chunk = line;
|
||||||
isEol = true;
|
atEol = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk = chunk.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ''); // other ctrl-chars
|
chunk = chunk.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ''); // other ctrl-chars
|
||||||
if (chunk && options.keyIn && exclude) { chunk = chunk.replace(exclude, ''); }
|
if (chunk && exclude) { chunk = chunk.replace(exclude, ''); }
|
||||||
|
|
||||||
if (chunk && !isCooked) {
|
if (chunk && !isCooked) {
|
||||||
if (!options.noEchoBack) {
|
if (!options.noEchoBack) {
|
||||||
|
@ -177,7 +175,8 @@ function readlineSync(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
input += chunk;
|
input += chunk;
|
||||||
if (isEol || options.keyIn && input.length >= reqSize) { break; }
|
if (!options.keyIn && atEol ||
|
||||||
|
options.keyIn && input.length >= reqSize) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCooked && !silent) { fs.writeSync(fdW, '\n'); }
|
if (!isCooked && !silent) { fs.writeSync(fdW, '\n'); }
|
||||||
|
@ -454,7 +453,7 @@ exports.question = function(query, options) {
|
||||||
|
|
||||||
exports.keyIn = function(query, options) {
|
exports.keyIn = function(query, options) {
|
||||||
var limit = options ? flattenArray(options.limit, function(value) {
|
var limit = options ? flattenArray(options.limit, function(value) {
|
||||||
return typeof value === 'string' || typeof value === 'number'; }) : [],
|
return typeof value === 'string' || typeof value === 'number'; }).join('') : '',
|
||||||
readOptions = {
|
readOptions = {
|
||||||
/* jshint eqnull:true */
|
/* jshint eqnull:true */
|
||||||
display: query != null ? query + '' : '',
|
display: query != null ? query + '' : '',
|
||||||
|
@ -462,8 +461,8 @@ exports.keyIn = function(query, options) {
|
||||||
keyIn: true,
|
keyIn: true,
|
||||||
noEchoBack: !!(options && options.noEchoBack),
|
noEchoBack: !!(options && options.noEchoBack),
|
||||||
mask: mask,
|
mask: mask,
|
||||||
exclude: limit.length ?
|
exclude: limit ? '[^' +
|
||||||
'[^' + limit.join('').replace(/\W/g, '\\$&') + ']' : '',
|
limit.replace(/\n/g, '').replace(/\W/g, '\\$&') + ']' : '',
|
||||||
cs: !!(options && options.caseSensitive),
|
cs: !!(options && options.caseSensitive),
|
||||||
noTrim: true
|
noTrim: true
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue