Skip to content


And this is how I switched back from Vivaldi to Firefox

When Vivaldi came out a bit more than a year ago, I was rather enthusiastic about it, even though I remembered what the same people did to Opera and even though it was yet another Blink-based browser aka Google slave. I was always happy to add new browsers to my panel, in order to run multiple sessions simultaneously, and after all it was nice to have a fast browser for a change (Firefox/Cyberfox were still quite slow for me as I was on Win 7: they seem to perform a lot better on Win 10).

However, things eventually changed. First, Cyberfox was discontinued, and on this occasion I found out that it’s possible (and trivial) to run multiple independent sessions simultaneously with just Firefox. That was quite the revelation, and I promptly dropped Cyberfox and also Pale Moon, which was getting a bit outdated and was now failing to run Flash (having a contained Flash environment was basically the only reason I kept it around). After that, I was basically 60% Firefox, 40% Vivaldi.

Second, Vivaldi was regularly updated and improved. However, version 1.9 was a disaster: it completely broke the autocompletion in the address bar (it already used to be inferior to the autocompletion in Firefox, it became even worse, only providing one unique suggestion and only if you typed the exact beginning of the URL – worthless). I’ve also always been very unhappy with the SOCKS proxy support in Vivaldi, which is the same as Chrome = use the system-defined (same as Internet Explorer) proxy settings. I use one SOCKS proxy per separate session, so a browser not able to live its own life, distinct from the system settings, was a drag. Last but not least, I’ve always been annoyed by how Vivaldi doesn’t remember where to save/pick files on a per-site basis like Firefox seems to do pretty well.

At this point, I had only 2 reasons to keep using Vivaldi: Speed Dial, for which Firefox doesn’t seem to provide a suitable equivalent (no I don’t want to install an add-on just for that), and the fact that I couldn’t be bothered to migrate my session manually.

That was, until disaster stroke. I sent a tab to a new window, forgot all about it, and when I closed the browser I closed the primary window first. In case that shit never happened to you, what happens then is that when you restart your browser, the last closed window is restored (so, the one with just a tab, instead of my primary window that had 20-ish tabs). In Firefox, the History menu allows you to restore your 2 latest closed windows, meaning that in case you fuck up like that, you can easily recover (it happened to me a bunch of times). In Vivaldi, you’re fucked.
So, bye bye Vivaldi, I’ll just keep you around for testing when doing web development…

Posted in Chrome/Chromium/Vivaldi, Firefox.


JavaScript: passing arguments to setTimeout()

JavaScript prides itself on by asynchronous, which I find causes more complications than it solves, as in most cases I need code to execute step by step and not all at the same time. It makes, in my opinion, a lot more sense to have extra complications in the rare cases where I need asynchronous than to have extra complications in the very common cases where I need synchronous.

Among the trivial things that get unnecessarily complicated with asynchronous by default, is pausing. In many programming languages, when you want to pause, it’s just a matter of a trivial line, for instance:
– in PHP: sleep(X)
– in Python: time.sleep(X) (you need to import time for this to work, though)

In JavaScript, you’ll have to refactor your code, putting what you want to delay inside a separate function, and use setTimout(). That is, unless you want to saturate the CPU with an infinite loop for X seconds.

setTimeout() looks simple enough at first:

setTimeout(myDelayedFunction, 1000);

But there is a catch if you want to pass arguments. For instance, this won’t work (arg1 and arg2 will appear to myDelayedFunction as undefined):

setTimeout(function(){
    myDelayedFunction(arg1, arg2);
}, 1000);

To passe arguments to the function inside, you’ll have to use this:

setTimeout(function(A, B){
    myDelayedFunction(A, B);
}, 1000, arg1, arg1);

Or also this should work too (not tested)

setTimeout(myDelayedFunction, 1000, arg1, arg1);

Source and other variations there on Stackoverflow

Posted in JavaScript / TypeScript / Node.js, programming.


How to run multiple independent Firefox sessions simultaneously

TL;DR: firefox -no-remote -P

For years (way over a decade, actually), I’ve used multiple browsers at the same time. What used to be a workaround to sites working better in some particular browser then became a very convenient way to keep several different sessions opened simultaneously (with 2 very separate “cookie world” and stuff). That’s useful for instance to be connected to 2 different mailboxes from the same provider, or to use different proxies simultaneously (one per browser).

But the browser world moves fast, and now it seems my favorite Firefox forks (Chrome support for SOCKS proxies is worthless so that’s not an option) are all vanishing: Pale Moon has been lagging behind for a long time, and now Cyberfox is being discontinued. Waterfox is still here, but they’re not really a fork, and they are so close to vanilla Firefox that they actually share its profiles and session (if you try to run Waterfox while Firefox is running, or the other way around, it will tell you Firefox is already running). So, it’s becoming hard to find distinct browsers.

In my despair, I tweeted to Waterfox about that problem of not being able to multi-session, and they pointed me to the -no-remote flag. I already used several Firefox profiles, but so far I was only able to run a single one at a time. What that flag does is that it basically allows to run several profiles at the same time (to use it, edit your Firefox shortcut and add it at the end of the command line). I guess I should have searched harder.
Problem solved already, then 🙂 But now, every time you run Firefox the profile manager will pop up. If you want to skip this, you can create separate links for each of your profiles, by adding also -P “profile_name” in the command line. Or even -profile “profile_path”, if you like moving stuff around 😉 All those options are detailed in the link I gave previously.

Last but not least, a little advice to avoid mixing up your sessions: set them up each with a different theme ^^

Posted in Firefox.


Please stop confusing deep web, dark web and dark net

Those are 3 different things. Let’s review.

Surface web

That’s the portion of the World Wide Web that is freely, directly accessible, and searchable with standard web search engines. Obviously you know that one and use it every day.

Deep web

It might come as a surprise for some of you, but surely you do use it every day too.
It’s basically the opposite of the surface web. Also called invisible web or hidden web, the deep web is all the parts of the World Wide Web that are not indexed by standard search engines. That’s the definition provided by Wikipedia, but I believe a site tagged “noindex” is still surface web, as long as access is free and doesn’t require registration or some specific technology (cf darknets below).
For instance, most parts of Facebook (all content that isn’t posted as “public”) is part of the deep web. Your web mail, your online banking accounts, contents behind a paywall, etc are “deep web” too. Told you you use it every day 😉

Dark net

Before talking about the dark web, we need to talk about dark nets (with an s).
Wikipedia provides a pretty good definition there: “a darknet (or dark net) is an overlay network that can only be accessed with specific software, configurations, or authorization, often using non-standard communications protocols and ports.”
Nothing to add, really. For instance, Tor is a darknet, Freenet is a darknet, GNUnet is a darknet, I2P is a darknet, etc. So, again, there are several darknets. Let’s say, about a dozen “big” ones.

Dark web

Wikipedia is straight to the point again: “The dark web is the World Wide Web content that exists on darknets” (so you see why I had to define a darknet first).
So whatever is on Tor, Freenet, etc, is on the dark web (and also on a dark net).

It is typically said that the dark web forms a small part of the deep web. I prefer to consider them as 2 distinct entities, as the barriers are distinct enough: the deep web is behind a login wall, the dark web is behind a networking technology “wall”. Also, some parts of the dark web (like some marketplaces) are behind both a networking technology and a login wall.
But if you are comfortable enough with those notions to start arguing about this detail, you know enough already 😉 (and sadly, you also know more than the average IT journalist :/ )

Bonus: clearnet, opennet, etc

Clearnet is a term used by dark web users to describe the regular internet. Since most darknets are focused on anonymity, it’s a convenient way to talk about “that part of internet where you are tracked”. Contrarily to what used to be mentioned on Wikipedia’s “surface web” page, clearnet is NOT synonymous with “surface web”. Facebook is clearnet, but as we saw earlier a lot (most?) of it is deep web.

Opennet is a more uncommon term. I only know about it in the context of Freenet. In the Freenet network, you can use 3 ways to connect: you can either connect only to people you know (real life friends), or connect to strangers, or do both. When you connect only to people you know, Freenet calls that “darknet”. When you connect to strangers, Freenet calls that “opennet”. Even though technically both are “dark nets” in the usual definition, at Freenet’s level the difference makes sense.

Posted in Internet, privacy.


Uninstalling dependencies of Python pip packages

pip is the package management system included in Python 2.7.9+ and 3.4+. It’s quite convenient to install packages, even though I’m not a big fan of having shitloads of packages around, particularly since their number can quickly grow to unreasonable proportions with all their dependencies. And as a matter of fact, pip installs package dependencies, but… it doesn’t uninstall those dependencies when you uninstall the package they were installed for.
For f***ing f*** sake.

Anyhow, there is a way to uninstall dependencies when uninstalling a package. It’s another package (which I believe has no dependencies itself), called pip-autoremove. So, basically, if you want to cleanly uninstall package “examplepackage”, you’d go:

pip install pip-autoremove
pip-autoremove examplepackage -y

It’s worth noting that, normally, it should only remove unused dependencies. It actually even provides a feature to just list packages which are not a dependency of any other package (-L flag)

Since it’s so short, here is the help:

> pip-autoremove --help
Usage: pip-autoremove [OPTION]... [NAME]...

Options:
  --version     show program's version number and exit
  -h, --help    show this help message and exit
  -l, --list    list unused dependencies, but don't uninstall them.
  -L, --leaves  list leaves (packages which are not used by any others).
  -y, --yes     don't ask for confirmation of uninstall deletions.

Posted in programming.


How to block base64 images with uBlock (and other things)

Some websites are really imaginative to try and bypass ad-blockers. Although their methods are interesting to study sometimes, usually when sites bother placing anti-ad-blocking code they tend to use it to place particularly annoying things.

One site I visit sometimes uses quite a dirty method: they place all ad images _inline_, as base64 encoded data.
I don’t think any uBlock filter catches those, as it would require site-specific filters instead of the usual advertising network-specific ones. However, you can easily make a filter yourself. Go to uBlock options (if you don’t know where to find them, click the uBlock icon to pop up the uBlock GUI then click the tiny cog in the top-left corner – yes I had a hard time finding it too a long time ago :s), then to the My filters tab. And add a line like:

example.com##img[src^="data:"]

And that’s all (make sure you replace example.com with your target site, of course). Just hit “Apply changes”, and when you reload the site the base64 images should be gone.

While I’m at it, here is some more useful filter syntax:

example.com

=> blocks a whole domain name. Useful to block an advertising network that isn’t supported yet in the published filters. Or also to block a site without installing a specific add-on such as BlockSite

example.com##.some-class

=> blocks all elements of class “some-class”.

example.com###some-id

=> blocks all elements of ID “some-id” (well, normally IDs should be unique so that would be only 1 element).

example.com##script:contains(sendAdBlockEventGA)

=> blocks script that contain the keyword “sendAdBlockEventGA”. I’m not really sure of the extent of what is blocked (just the line around the detected word, I assume?), and also maybe this only works on Firefox. Well, long story short that’s not a filter I actively use at the moment, but still I suppose it can be useful for instance to block those big fat popups saying “HEY YOU PLEASE TURN OFF THAT ADBLOCKER”. Yup, I should definitely try to remember to give it a spin next time I see one of those 😉

Posted in privacy.


How to generate a strong random hexadecimal string in Node.js

…and using TypeScript syntax. Simply use the “crypto” standard library.

import * as crypto from 'crypto';
const randomString = crypto.randomBytes(32).toString('hex');

Note that it will produce cryptographically strong pseudo-random data, but the drawback of this is that it will freeze a bit in case of a lack of entropy. As mentioned in the documentation, such lack of entropy shouldn’t ever create a noticeable delay, except right after system boot.

Posted in JavaScript / TypeScript / Node.js.


Passive data structure in TypeScript

I really like this kind of construct in C/C++

struct Point
{
  double x;
  double y;
};

as a way to have a structured dictionary that should have nice auto-completion.

After learning the TypeScript way to do it in a course I forgot it, before finding it back so I’ll save it here for safekeeping ^^ Basically, the TypeScript solution to create a PDS / “plain old data structure” / “POD-structs” (not really sure how to call those…) is to hijack the interface, like this:

interface Point
{
  number x;
  number y;
}

This way when you declare

let mypoint: Point = {x: 1, y: 5};

you’ll then have autocompletion to access mypoint.x and mypoint.y. And since TypeScript’s interfaces completely vanish during compilation, that “misuse” won’t have any consequence.

Thanks to this article with many strange data structures for pointing me to the solution 🙂

Posted in JavaScript / TypeScript / Node.js.


How to remove a printer that keeps coming back in Windows 7

I never had any trouble with the “Devices and Printers” control panel in Windows 7 before, apart from the usual difficulties when trying to connect to networks printers. So I was pretty puzzled when I got into trouble trying to disconnect from one.
Basically, I take my laptop at work, and when I changed office there was an old printer from the former office that I didn’t manage to delete: every time I deleted it, it would seem successful but it would come back whenever I restarted the computer (popping up a firewall alert in the process).

I eventually found a way to delete it manually, for good:
– go to Services (if you don’t know how, type “Services” in the start menu)
– find the Print Spooler service and stop it
– open Windows Explorer and go to the C:\Windows\System32\spool\Printers folder. That’s where things can get complicated: ideally, you should delete just the file related to the printer you want to remove (for me it was easy, I only had 2 files and the creation dates were different enough for me to be able to pick the right one). If you can’t identify the right file, I guess you can either remove them all (if you don’t mind losing your other printers’ settings), or make a backup of them and try to delete (and restore) the files one by one (NB: I didn’t try that so I’m not 100% sure making a backup of those files is enough to restore your settings – but I don’t see why it wouldn’t be).
– go back to Services and restart the Print Spooler service.

For me, that did the trick. If you still have difficulties, maybe check out this answer on Superuser, with more options like the use of printui

Posted in Windows Se7en.


How to get a random item from a JavaScript array

var myArray = ['a','b','c'];
var randomItem = myArray[Math.floor(Math.random()*myArray.length)]

Math.random() returns a number between 0 (included) and 1 (not included), which is why this piece of code won’t overshoot by picking a number equal to the array length (reminder: array indexes start at 0, meaning last index is length – 1).

Math.round() is not appropriate as it would result in sometimes hitting a number equal to the array length. Hence the Math.floor().

Posted in JavaScript / TypeScript / Node.js.