Skip to content


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.


How to configure email and name in Git

I’m using SourceTree as a Git GUI for the sake of simplicity, but some settings are still hard to find. Among those, how to set up (or change) the name and email that you’ll automatically attach to your commits, either system-wide or for the current repository.
Gladly, it’s easy enough to do via the command line: for the current repository, that would be simply:

git config user.email "me@example.com"
git config user.name "My Name"

If you want to set those globally, just add a --global flag, e.g.:

git config --global user.email "me@example.com"

Posted in programming.