Show me dog/cat pictures!

So very recently, our professor tasked us with working on Brave. It’s a lightweight browser with AdBlock being their main focus. A pretty cool idea, if you ask me.

For this piece of work, he wanted us to see what Brave would do when you gave it certain queries in it’s URL bar, to see how it would behave. Then we would compare that to the other main browsers like IE, FireFox, and Chrome, to see how they handle where Brave breaks. So below are the tests, and the outcomes.

Tests
"dog"
Brave: Passed
FireFox: Passed
Chrome: Passed
MS Edge: Passed
" dog "
Brave: Passed
FireFox: Passed
Chrome: Passed
MS Edge: Passed
" dog cat "
Brave: Passed
FireFox: Passed
Chrome: Passed
MS Edge: Passed
"https://www.google.ca/search?q=dog"
Brave: Passed
FireFox: Passed
Chrome: Passed
MS Edge: Passed
" https://www.google.ca/search?q=dog "
Brave: Passed
FireFox: Passed
Chrome: Passed
MS Edge: Passed
"https://www.google.ca/search?q=dog cat"
Brave: Search successful, but url in search box
FireFox: Passed
Chrome: Passed
MS Edge: Passed
" https://www.google.ca/search?q=dog cat "
Brave: Search successful, but url in search box
FireFox: Passed
Chrome: Passed
MS Edge: Passed
"C:\Users\Abdul\Desktop\dog cat.txt"
Brave: Directs to Google with file path in search bar
FireFox: Opened file
Chrome: Opened file
MS Edge: Opened file
" C:\Users\Abdul\Desktop\dog cat.txt "
Brave: Directs to Google with file path in search bar
FireFox: Opened file
Chrome: Opened file
MS Edge: Opened file
"file:///C:\Users\Abdul\Desktop\dog cat.txt"
Brave: Opened file
FireFox: Opened file
Chrome: Opened file
MS Edge: Opened file
" file:///C:\Users\Abdul\Desktop\dog cat.txt "
Brave: Opened file
FireFox: Opened file
Chrome: Opened file
MS Edge: Opened file

view raw
Test-results.txt
hosted with ❤ by GitHub

So as you can see, Brave is decent, but when you give it certain queries, it doesn’t know how to handle them like the other browsers do. So lets fix that!

Implementing a fix

To be honest, finding the issue wasn’t hard, primarily because our professor told us exactly where to look, so it was now just a matter of implementing a fix.

First, lets look at the first mistake in Brave’s code

/// Original Brave Code ///
// for cases:
// – starts with "?" or "."
// – contains "? "
// – ends with "." (and was not preceded by a domain or /)
const case2Reg = /(^\?)|(\?.+\s)|(^\.)|(^[^.+]*[^/]*\.$)/
/// Fix ////
const case2Reg = /(^\?)|(\?\s+)|(^\.)|(^[^.+]*[^/]*\.$)/

view raw
firstProblem.js
hosted with ❤ by GitHub

This came from their urlutil.js file, as you can see by reading the comments they themselves had, the comments didn’t actually accurately represent what the code was doing. So my guess is, whomever was making the code, didn’t read the comment properly, so I went with that and decided to change the regex. The change was VERY minuscule. But that wasn’t all!

We now needed a way for it to properly parse file systems that don’t contain the word ‘file’ in them as you saw in the above tests.

Since I’m a Windows users, of course I decided to implement a Windows solution first, and here it is!

const windowsFileScheme = /[a-z]:\\/i
We need this in order to even recognize windows file schemes in the first place.  But that wasn’t all we needed, we needed a way to test to see if the given input even had a windows file scheme, so a test was put in place.

if (windowsFileScheme.test(input)) {
input = input.replace(/\\/g, '/')
input = `${fileScheme}/${input}`
}

view raw
urlutil.js
hosted with ❤ by GitHub

A very simple test, really. Does the input match our expression? (Meaning does it contain a windows file scheme) Oh? Then replace the back ticks with forward ticks and lets add “file://” to it. Very simple, really.

Lastly, we needed to check to see if the file we’re trying to open is on a Unix or a Windows machine. Luckily, the check isn’t hard at all, I mean, we already had half of it above. So just copy and paste, and create one for Unix. Here it is!

// Original
if (case2Reg.test(str) || !case3Reg.test(str) || (scheme === undefined && /\s/g.test(str))) {
return true
}
// Fix
const case5Reg = /(?:^\/)|(?:^[a-zA-Z]:\\)/
if (case2Reg.test(str) || !case3Reg.test(str) || (scheme === undefined && /\s/g.test(str) && !case5Reg.test(str))) {
return true
}

view raw
urlutil-second.js
hosted with ❤ by GitHub

As you can see, it really isn’t very hard. However, I did manage to learn quite a bit about how browsers parse URLs that are given to them!

Aftermath

So now that we implemented our fix, let me show you how it looks. Of course I did A LOT of tests above, so I’m only going to show you two, but believe me, everything else works!

Test: https://www.google.ca/search?q=dog cat

Before

0a44949a9198f8e28d562721454e9aa7

After

after1.png

Test: C:\Users\Abdul\Desktop\dog cat.txt

Before

c51d30d644be54a33c338b4e5facf3fe-png

After

after2.png

And just like that, the test was complete!

Testing it all

Now it was time to write tests and make sure what I implemented didn’t A) break what was already working and B) actually worked. So I wrote two tests of my own. Now the reason I only wrote two is because I’ll be uploading this change to Github, it wouldn’t make sense to make a test that would require an absolute path. Because if you took my code, you would have to go through the trouble of changing the tests to fit your absolute paths. So I only wrote the two URL tests it was initially failing. Here is how they look

it('is a valid search with space inside of search', function () {
assert.equal(urlUtil.isNotURL('https://www.google.ca/search?q=dog cat'), false)
})
it('is a valid search with leading and trailing spaces', function () {
assert.equal(urlUtil.isNotURL(' https://www.google.ca/search?q=dog cat '), false)
})

view raw
urlutiltest.js
hosted with ❤ by GitHub

Wasn’t a lot to write, but it worked!

c03b6769e4588b7c36bf94876934de30

As you can see, all two of my tests pass, and I didn’t break any of the previous tests!

 

Conclusion

Ultimately, though this wasn’t really ‘hard’, it was still fun. It taught me quite a bit about the troubles of parsing different strings, and how to effectively do it for each case.

I’d like to thank you for taking the time to read this far. If you have any questions, please don’t hesitate to leave them in the comments section!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s