Link to Forked JS Calculator Codepen:
https://codepen.io/nwbnwb/full/rNeypVE
This one switches out the current math operator with the operator of the button just clicked except for x-, *-, /-, ± to account for negative values.
Link to Original JS Calculator Codepen:
https://codepen.io/nwbnwb/pen/JjXdzXB
The original code doesn’t allow a math operator to be replaced by another math operator but still can yield negative values/numbers when the calculation is performed.
I kindly inquire: Why aren’t either of them passing the test?
Hello~!
I think I spoke with you on the freeCodeCamp GitHub issue.
It looks like you’ve modified the code to accept negative numbers, which is good! However, now it does not override the operators correctly.
If I input 5*-+5
, I should get 5+5
. Instead, I get 5*-5
.
Thank you for coming to my help. Do you have any suggestions how I could do that without having to rewrite a large part of my code?
When I wrote mine, I checked if the last input was an operator. If it was, I replaced it.
I also checked if the current input was -
, then I appended it.
Finally I checked if the last input was a -
, then I replaced that and the previous character if it was also an operator.
Did you use eval() in your code?
I did. I sanitised the input first, though, just to play it safe.
This was a while ago that I did the project, however. When I approach it to refactor, I’ll be looking at using the math.js
library.
When I was writing the code, I would try different things in the example and the calculator on my computer and I tried to write code that covered those cases. The main regex I use to make everything work is complex (at least for me it was/is, it took me a while to write it)… I’m not for sure that I’m going to be able to easily modify my code to get it to pass the 13th test.
How did you sanitise eval()?
input.replace(/[^-()\d/*+.]/g, "")
A regex that strips out any characters that my calculator doesn’t have buttons for. XD
EDIT: This is to prevent the injection of script by modifying the text content of the display window before calling the function.
I don’t quite understand the regex, if you don’t mind, please explain it, break it down for me.
If you don’t use an input element and you use eval(), is sanitization still necessary?
If you don’t us eval() at all, is it necessary to sanitize it?
I ask because I used two p elements (one for input, one for output) which can only be edited by the calculator buttons.
P.S.
I forked my code again and just modified the code to pass the 13th test and then I submitted it to FreeCodeCamp. But I still like my other two calculator codes better, especially the one I forked and modified from the original.
Sure! The regex /[^-()\d/*+./
will match any character that is not one of the buttons on my calculator. So, any character that is not 0-9, +
, *
, -
, /
, or ()
. The g
flag ensures it matches everything instead of stopping at the first match. The replace
function will take all of those matched values and replace them with the second argument - in my case, the second argument is a null space ""
, so the replace is effectively removing any characters that match the regex.
Sanitising the possible input is still necessary, yes. For a standard end-user, there is little risk of using eval
in this case. However, if your code is written to get the innerText
of the display box and uses eval
on that value, there becomes a risk in that I can edit the HTML code to change the value of that display box. If I pass malicious code into that display box and then click your =
button, your code would run eval
on the script I just wrote because it grabs that value straight from the DOM.
But how exactly do they pass malicious code into the display box by entering the HTML code if the innerText of the display can only be changed by the calculator buttons?
Do they open the console and do it that way or some other way?
Close. You can do this by opening the dev tools in your browser and editing the code directly.
I’ve edited the content of your display box here. If you were passing an unsanitised input into the eval
call, this could actually trigger an alert box in my browser.
If passing an unsantised input into eval could actaully trigger an alert box in your browser, wouldn’t that only affect your browser and no one else’s?
You are correct - the dangers of eval
are mitigated by the fact that there is no server-side code.
However, it is generally bad practise to use eval
. Yesterday I refactored my calculator and removed the eval
, using the math.js
library to run the calculation instead.
Okay. That’s good to know.
I read somewhere (I can’t remember exactly where) that it’s okay to use eval if you control the input. So I gathered from that, that it would be okay to use eval() for a calculator as long as the eval() only evaluates the code inputted in the calculator onto the webpage it is on (as you said, no server-side code).
Was math.js easy to implement within your calculator application?
It was surprisingly easy once I found the CDN link.
I used math.js
in another project, so I’m somewhat familiar with the package, but the docs are clear enough that implementing it for the calculator should not have too steep of a learning curve.