How to add conditions in process.stdin's readable event? - javascript

Well, I'm trying to pass a simple if statement to a process.stdin readable stream in NodeJS. But it doesn't seem working. Here's the code :
process.stdin.on('readable', function() {
var chunk = process.stdin.read();
if (chunk !== null && chunk == 'foo') {
process.stdout.write('true\n');
} else if (chunk !== null) {
process.stdout.write('false\n');
}
Does anyone know, what am I doing wrong here? I also tried chunk == 'foo\n' but, had no luck. The only time it works is when I set chunk value to a number, like chunk == 10.

#Siam the issue here is that the chunk is of Buffer type, and not a string. You can use chunk.toString() to make it a string, and then compare it with "foo\n" and it would work
So your code would look something like this:
process.stdin.on('readable', function() {
var chunk = process.stdin.read();
if (chunk !== null && chunk.toString() == 'foo\n') {
process.stdout.write('true\n');
} else if (chunk !== null) {
process.stdout.write('false\n');
}
});
EDIT 1:
Make sure that you are using compare string same as the input. for e.g in the above case, New line character can be CRLF or \r\n on windows based systems, while on Unix based systems its LF or \n. Hence, try using "foo\r\n" for comparison, if on windows

You can use the .prompt() (example) method

Related

Why is a simple test failing and split() not working properly

I am trying to create a simple code which splits a string at ',' . The expected string is a list of numbers separated by commas. I have to print the sum of those numbers. My code is here:
function add(numbers) {
if (numbers === "")
{
return 0;
}
else if (typeof parseInt(numbers) == 'number')
{
return parseInt(numbers);
}
else
{
let numArray = numbers.toString().split(',');
console.log(numArray);
let value = numArray.every(checkElement);
if (value) {
return (getSum(numArray));
}
else
{
return "Error in formatting";
}
}
}
function checkElement(element)
{
return (typeof parseInt(element) == 'number')
}
function getSum(numArray)
{
let total = 0;
for (let i = 0; i < numArray.length; i++)
{
total += numArray[i];
}
return total
}
module.exports = add
My Jest code is:
const add = require('../sum.js')
test('Returns sum of numbers', () => {
expect (
add("225,75")
).toBe(300)
})
I am getting this error:
● Returns sum of numbers
expect(received).toBe(expected) // Object.is equality
Expected: 300
Received: 225
17 | add("225,75")
> 18 | ).toBe(300)
| ^
19 | })
at Object.toBe (js/Testing/sum.test.js:18:7)
Moreover, my VS Code is not printing any console.log if I try to run the my js file using node filename.js command. It just starts a new terminal line. Not sure what's going wrong. The error looks like split() isn't working properly - it's only ever returning the 1st element (don't understand why) and VS Code won't print my console logs to check where it is stuck.
instead of typeof parseInt(numbers) ,
you should have done
typeof numbers
as even typeof NaN is also a number and thus wrong result.
My process of checking the typeof parseInt("some possible not number") itself is faulty. As parsing anything to int produces a number, I should have checked with isNaN instead. I think we can close off this question. It certainly did help in enhancing my knowledge of small things like parseInt's actions.
The issue is with the attempt to handle the case of "just one number" in a special way. It turns out the result of parseInt("") is always of type "number". So, the answer is:
Scrap the special case and all will be well.

When reading minified Javascript, how am I supposed to read this return statement with commas, &&, and || operators?

I have this source code:
function findMessageErrors(btn) {
var error = "";
var message = $(btn).parent().siblings().find("textarea[name='message']").val();
if (message === "") {
error += "*Please enter a message.<br/>";
}
if (!$(btn).parent().siblings().find('input[name="agree"]').prop('checked')) {
error += "*Please agree.<br/>";
}
return error;
}
This gets minified. After minification, it looks like this in the Chrome Dev tools Sources tab:
function findMessageErrors(btn) {
var error = "";
return "" === $(btn).parent().siblings().find("textarea[name='message']").val() && (error += "*Please enter a message.<br/>"),
$(btn).parent().siblings().find('input[name="agree"]').prop("checked") || (error += "*Please agree.<br/>"),
error
}
I understand how the comma operator 'runs a series of expressions, in order, and then returns the result of the last of them' (from here). But I'm having a hard time understanding how those OR and AND operators are working in building that string that gets returned in the minified code.
Does anyone have a helpful way of reading that out loud that will help me understand how that works? I guess I don't see how 2 independent IF statements in the source gets minified into a series of && then ||. I don't want to have to look up the source every time I want to understand the logic of how the minified code works.
Where possible, use source maps rather than trying to read minified code.
But that doesn't mean you don't want to know how to read complex statements; sometimes humans write them. :-)
I've done some formatting and inline comments to explain:
function findMessageErrors(btn) {
var error = "";
return (
(
"" === $(btn).parent().siblings().find("textarea[name='message']").val()
&&
// This only runs if the === above is true, because of the &&
(error += "*Please enter a message.<br/>")
)
,
( // This runs regardless of the above
$(btn).parent().siblings().find('input[name="agree"]').prop("checked")
||
// This only runs if prop("checked") returned a falsy value, because of ||
(error += "*Please agree.<br/>")
)
,
( // This runs regardless, of the above...
// ...and this is the ultimate value of the return
error
)
);
}
The outer () are just added because a linebreak after return triggers (the horror that is) automatic semicolon insertion. Other () are added for clarity of explanation.

Good way to obfuscate Javascript code in Gulp [duplicate]

This question already has answers here:
How can I obfuscate (protect) JavaScript? [closed]
(22 answers)
Closed 3 years ago.
This question knowing that obfuscation is by no means a strong way to protect code...
Using Gulp, I'm looking for a way to prevent my app's content to appear in a too obvious manner. Not manipulating sensitive data, but I'd still not want my minified code to look too obvious to modify.
Been trying gulp-minify and gulp-uglify, but either my use of them is wrong, either they don't fill my need.
Needs being:
- function renaming
- variable renaming
- string obfuscation (at least prevent the string from being human readable at first glance)
- not more than 2x the storage needs
What would be the suggested approaches, leads, plugins?
Thanks in advance,
Just try this: Javascript Obfuscator.
As far as I know, it's almost impossible to revert the obfuscated code back to the original.
So far, the most effective (in my case) is to pipe the following code, which just applies character rotation:
function obfuscate(text, key, n = 126) {
// return String itself if the given parameters are invalid
if (!(typeof(key) === 'number' && key % 1 === 0)
|| !(typeof(key) === 'number' && key % 1 === 0)) {
return text.toString();
}
var chars = text.toString().split('');
for (var i = 0; i < chars.length; i++) {
var c = chars[i].charCodeAt(0);
if (c <= n) {
chars[i] = String.fromCharCode((chars[i].charCodeAt(0) + key) % n);
}
}
return chars.join('');
},
function defuse(text, key, n = 126) {
// return String itself if the given parameters are invalid
if (!(typeof(key) === 'number' && key % 1 === 0)
|| !(typeof(key) === 'number' && key % 1 === 0)) {
return text.toString();
}
return obfuscate(text.toString(), n - key);
}
You may want to consider gulp-javascript-obfuscator. It's a node module and version ^1.1.5 worked very well for me. It also has the option to minify with the following code:
// Imports ...
obfuscator = require('gulp-javascript-obfuscator')
// ... Other code
gulp.src('my_file.js')
.pipe(obfuscator({compact:true}))
.pipe(gulp.dest('dist'));

Cannot check for an equal number using string

I have what I thought would be a simple logic check. In my code
$scope.seatMap.PlaneTypeCode = "175"
However, when I set
$scope.seatMap.PlaneTypeCode === "175" //my debugger returns <b>false </b>
parseInt($scope.seatMap.PlaneTypeCode,10) ===175 // equals 17
I added a few zeros on the radix but that did nothing to help.
I am not sure how to do a comparison check. Any insight on this would be hugely appreciated.
Here is my full if statement
if (parseInt(col.name,10) ===4 && parseInt($scope.seatMap.PlaneTypeCode,10) ===175 && $scope.TripSummary) {
col.available = false;
}
****** Changed my response to this
if (parseInt(col.name,10) ===4 && $scope.seatMap.PlaneTypeCode ==="175" && $scope.TripSummary) {
col.available = false;
} // still getting false
=== is a best practice, you should use it. Review the reference provided by #Joyson
You don't need the ,10 in parseInt because it is the default.
var PlaneTypeCode = "175";
if (parseInt(PlaneTypeCode) === 175) {
console.log('equal');
}
If PlaneTypeCode is a code and can contain anything other than digits, a better comparison would be:
if (PlaneTypeCode === "175")
You can use == instead of ===
$scope.seatMap.PlaneTypeCode == "175"
Please refer to Difference between == and === to know more
use angular.equals($scope.seatMap.PlaneTypeCode,"175")

Determine if string is in base64 using JavaScript

I'm using the window.atob('string') function to decode a string from base64 to a string. Now I wonder, is there any way to check that 'string' is actually valid base64? I would like to be notified if the string is not base64 so I can perform a different action.
If you want to check whether it can be decoded or not, you can simply try decoding it and see whether it failed:
try {
window.atob(str);
} catch(e) {
// something failed
// if you want to be specific and only catch the error which means
// the base 64 was invalid, then check for 'e.code === 5'.
// (because 'DOMException.INVALID_CHARACTER_ERR === 5')
}
Building on #anders-marzi-tornblad's answer, using the regex to make a simple true/false test for base64 validity is as easy as follows:
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
base64regex.test("SomeStringObviouslyNotBase64Encoded..."); // FALSE
base64regex.test("U29tZVN0cmluZ09idmlvdXNseU5vdEJhc2U2NEVuY29kZWQ="); // TRUE
Update 2021
Following the comments below it transpires this regex-based solution provides a more accurate check than simply try`ing atob because the latter doesn't check for =-padding. According to RFC4648 =-padding may only be ignored for base16-encoding or if the data length is known implicitely.
Regex-based solution also seems to be the fastest as hinted by kai. As jsperf seems flaky atm i made a new test on jsbench which confirms this.
This should do the trick.
function isBase64(str) {
if (str ==='' || str.trim() ===''){ return false; }
try {
return btoa(atob(str)) == str;
} catch (err) {
return false;
}
}
If "valid" means "only has base64 chars in it" then check against /[A-Za-z0-9+/=]/.
If "valid" means a "legal" base64-encoded string then you should check for the = at the end.
If "valid" means it's something reasonable after decoding then it requires domain knowledge.
I would use a regular expression for that. Try this one:
/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/
Explanation:
^ # Start of input
([0-9a-zA-Z+/]{4})* # Groups of 4 valid characters decode
# to 24 bits of data for each group
( # Either ending with:
([0-9a-zA-Z+/]{2}==) # two valid characters followed by ==
| # , or
([0-9a-zA-Z+/]{3}=) # three valid characters followed by =
)? # , or nothing
$ # End of input
This method attempts to decode then encode and compare to the original. Could also be combined with the other answers for environments that throw on parsing errors. Its also possible to have a string that looks like valid base64 from a regex point of view but is not actual base64.
if(btoa(atob(str))==str){
//...
}
This is how it's done in one of my favorite validation libs:
const notBase64 = /[^A-Z0-9+\/=]/i;
export default function isBase64(str) {
assertString(str); // remove this line and make sure you pass in a string
const len = str.length;
if (!len || len % 4 !== 0 || notBase64.test(str)) {
return false;
}
const firstPaddingChar = str.indexOf('=');
return firstPaddingChar === -1 ||
firstPaddingChar === len - 1 ||
(firstPaddingChar === len - 2 && str[len - 1] === '=');
}
https://github.com/chriso/validator.js/blob/master/src/lib/isBase64.js
For me, a string is likely an encoded base64 if:
its length is divisible by 4
uses A-Z a-z 0-9 +/=
only uses = in the end (0-2 chars)
so the code would be
function isBase64(str)
{
return str.length % 4 == 0 && /^[A-Za-z0-9+/]+[=]{0,2}$/.test(str);
}
Implementation in nodejs (validates not just allowed chars but base64 string at all)
const validateBase64 = function(encoded1) {
var decoded1 = Buffer.from(encoded1, 'base64').toString('utf8');
var encoded2 = Buffer.from(decoded1, 'binary').toString('base64');
return encoded1 == encoded2;
}
I have tried the below answers but there are some issues.
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
base64regex.test(value)
when using this it will be true with "BBBBB" capital letters. and also it will be true with "4444".
I added some code to work correctly for me.
function (value) {
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
if (base64regex.test(value) && isNaN(value) && !/^[a-zA-Z]+$/.test(value)) {
return decodeURIComponent(escape(window.atob(value)));
}
Throwing my results into the fray here.
In my case, there was a string that was not base64 but was valid base64 so it was getting decoded into gibberish. (i.e. yyyyyyyy is valid base64 according to the usual regex)
My testing resulted in checking first if the string was a valid base64 string using the regex others shared here and then decrypting it and testing if it was a valid ascii string since (in my case) I should only get ascii characters back. (This can probably be extended to include other characters that may not fall into ascii ranges.)
This is a bit of a mix of multiple answers.
let base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
function isBase64(str) {
if (str ==='' || str.trim() ===''){ return false; }
try {
if (base64regex.test(str)) {
return /^[\x00-\x7F]*$/.test(atob(str));
} else {
return false
}
} catch (err) {
// catch
}
}
As always with my JavaScript answers, I have no idea what I am doing. So there might be a better way to write this out. But it works for my needs and covers the case when you have a string that isn't supposed to be base64 but is valid and still decrypts as base64.
I know its late, but I tried to make it simple here;
function isBase64(encodedString) {
var regexBase64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
return regexBase64.test(encodedString); // return TRUE if its base64 string.
}

Categories