Bug Bytes I: Fixing the bug with the download click button
So with this starts one of my other series where I discuss bugs and as it goes with few years of building stuff and being a C.S soon to be graduate , I can safely assume I have seen my share good bugs that we can talk about. In the series I will talk about how I go about fixing bugs that i encounter from time to time in my own apps or others. No this is not about BUG BOUNTIES !!!! I am not yet that good . I just prefer having good software’s being non buggy, which may also involve at times bug leading to intrusions hence maybe HACKING !!! ( That term is the most misused one by the way). Let’s begin !
So today’s subject is my own college website aec.ac.in . Now don’t go around hitting that website with paid DDoS , you will be caught by the authorities. 😬 In case you visited the site, ya that’s my college. The bug was present in the notification tab. When you click on the Attachment for any one of the files in the Notice section , Firefox fails at opening download dialogue box.
BUG: Click on “Attachment button” in notification tab does not work in Firefox browser for the website in subject.
Not considering you have Internet Download Manager installed the click is not captured. Apparantly IDM has deeper hooks than React. 😕 . But it fails at getting the correct file.
This meant the problem was on the Front-end. Which meant in deed there is something I could find or learn. Before I dig in , I knew the site was build using React and was transpiled by it’s own transpiler for JSX . I am not an expert in neither of those and kind of biased towards Angular due to it’s closeness towards MV* style. Yaa !! I am biased until my job asks me to deal with React , So ya moving on I open up the inspector , located the code for the click button. I knew the click was triggered , which I was doubting first. But no it was clicked because animation of the click was playing.
The onClick()
event was triggered , so problem lied in the fetch code.
//onClick
function(e, t) {
var n = this,
r = this.state.bb;
r[t] = !0, this.setState({
bb: r
}), fetch("http://14.139.221.35:5000/api/notice/attachment/" + e + "/" + t, {
method: "GET"
}).then(function(e) {
return e.blob()
}).then(this.showFile.bind(this)).then(function() {
r[t] = "", n.setState({
bb: r
})
})
}
The code receives the content from the Promise returns by the then on the fetch , which actually is a blob file. I didn’t knew this is a more recent trend rather than the age old Ajax requests. They still are same though , but this one’s returning a promise falls better in paradigm of having request and response object that can be handled by other services. You can read the MDN doc of fetch . Now looking at the code I am not sure is it bad naming or is it obfuscated or generated by react. I will stick to react. So now I suppose React work upon binding events , where event handlers themselves are structured inside some kind of object for the respective events. None the less we need the showFile event or it’s name. Here is the code for it.
// showFile code
function (e) {
var t = new Blob([e], {
type: 'application/pdf'
});
if (window.navigator && window.navigator.msSaveOrOpenBlob) return void window.navigator.msSaveOrOpenBlob(t);
var n = window.URL.createObjectURL(t),
r = document.createElement('a');
r.href = n,
r.download = this.props.headline + '.pdf',
r.click(),
setTimeout(function () {
window.URL.revokeObjectURL(n)
})
}
Ya this one actually looks for whether the window API directly supports for calling the dialog box of saving binary files , or do we need to go through some effort of making it happen programmatically. Which involves creating a pseudo anchor element and then binding the filename and the created URL to it and then making a click event on it.
For simplicity and testing sake , I manually copied the code sections and then pasted them on the Console , gave the two if cases different function names and then tested them out for one specific file. “dl()” is the API call and the “dl2()” is the work around for the function.
Let’s test the next part of the code i.e the one done with artificial anchor click
Now if something works in IE and EDGE , not in Firefox , I consider it to be the worst case. It really came to me as surprise when it worked on IE. So a solution was needed. I knew there was an artificial click created. I also knew form previous experience such clicks sometimes failed for unknown and long security reasons otherwise almost every site will make you click all the adds present on it right. 😝
So the line r.click()
must be changed. I googled once about anchors being clicked artificially and the first result. Now for the “NOVICE” out there always read the entire comment and solution thread on StackOverflow. You will always find that one guy who has a complain for the solution and someone solving that. 😆 That is what I did. I read it through and found that one default click alternative which actually used a custom click event using dispatchEvent()
. And so it worked on our subject site on the subject platform.
So I didn’t knew much about the code base or the entire Javascript (JSX ) we are dealing with here. I was unaware of anything. I just knew basic Js and how to use the debugger/profiler. I did thought of going through the stack trace but it would be too time consuming and I would like the devs to go through that pain. For now we conquered the bug. 😃
Also people who are new to developing webpaged and websites can get hints at how to debug various stuff, from this and also my future shots at other bugs.
PS: I have informed the guy in contact with dev team yesterday and it appears they don’t care much about it. So not my agenda or issue. Just a poor message from them that don’t use Firefox on windows PC as it seems on mobile it works.
PPS: I though of starting this series because 1. People hate bugs 2. My friend asked me to write about bugs. Since i fix them in our project. That’s what I mostly do fix things.