<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Thomas van der Berg</title>
    <description>Thomas van der Berg is a certified security professional (CRTP, 2025; PNPT, 2024; OSCP, 2018; CEH, 2016) from Leeuwarden, the Netherlands.
</description>
    <link>http://thomasvanderberg.nl/</link>
    <atom:link href="http://thomasvanderberg.nl/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 24 Dec 2025 21:56:44 +0100</pubDate>
    <lastBuildDate>Wed, 24 Dec 2025 21:56:44 +0100</lastBuildDate>
    <generator>Jekyll v3.9.0</generator>
    
      <item>
        <title>Christmas Kitty</title>
        <description>&lt;p&gt;Merry Christmas and happy new year! Thanks Hao Tian (田好) for making this Christmas Kitty:
&lt;img src=&quot;/images/Hao-Christmas-Kitty.jpeg&quot; alt=&quot;cat wearing a scarf and Christmas hat sitting on top of Christmas bells&quot; width=&quot;512&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 24 Dec 2025 21:51:11 +0100</pubDate>
        <link>http://thomasvanderberg.nl/blog/hao-christmas-kitty/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/hao-christmas-kitty/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Web pentesting with Firefox Containers and Container Proxy</title>
        <description>&lt;p&gt;I thought I’d share my workflow for web pentesting with Firefox containers. It has advantages by allowing you to be logged in to multiple accounts at the same time, which helps with authorization testing, and also makes it easy to separate traffic sent to the intercepting proxy and other traffic without configuring Foxyproxy patterns. I’ve been using it for years but I haven’t really seen it used much by other testers, so I thought I’d write about it as it can be useful for others.&lt;/p&gt;

&lt;p&gt;When performing web pentests we usually use an intercepting proxy such as &lt;a href=&quot;https://portswigger.net/burp&quot;&gt;Burp Suite&lt;/a&gt; to investigate the traffic of the web application. One of the problems with using an intercepting proxy is choosing which traffic to intercept and which to ignore, as you may want to use the same browser for other things as well. The traditional solution for this is to use &lt;a href=&quot;https://getfoxyproxy.org/&quot;&gt;Foxyproxy&lt;/a&gt;, but I never really liked this solution as it depends on configuring URL regexes, which is manual, error-prone and might cause you to miss traffic especially background traffic and redirects. Of course it’s also possible to use a different browser (like the Burp Browser) for testing, but this means you can’t use Firefox specific functionality in your test, such as Firefox containers.&lt;/p&gt;

&lt;p&gt;I’ve been using &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/&quot;&gt;Firefox Containers&lt;/a&gt; for a while, it allows you to have separate site storage for the same websites, which is great for pentesting. For example I might get four or more accounts for a pentest, such as admin and regular user accounts for different organizations in the webapp. And I also want to test anonymous access. Using containers, I can make different containers for each account and be logged in with every account at the same time as I test. This really makes the test easier and allows you to find more stuff.&lt;/p&gt;

&lt;p&gt;What really made me happy was when I found &lt;a href=&quot;https://addons.mozilla.org/nl/firefox/addon/container-proxy/&quot;&gt;Container Proxy&lt;/a&gt;. This addon allows you to configure a proxy differently for each Firefox container. By making a bunch of Burp Suite containers, I can easily separate testing traffic from other traffic in the same browser! No more foxyproxy patterns needed!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/container-config.png&quot; alt=&quot;Firefox container configuration with container proxy: this shows one admin container, three user containers, and an &amp;quot;anonymous&amp;quot; container, all configured to connect with a Burp Suite proxy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Containers also works well with another extension I use during pentesting, &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/cookie-quick-manager/&quot;&gt;Cookie Quick Manager&lt;/a&gt;. With this it’s possible to copy cookies from one container to another and edit them. Copying cookies is sometimes useful for example when the login flow doesn’t work well with Burp, one possible bypass is to log in without Burp and copy the cookie (of course you can also temporarily disable proxying during the login).&lt;/p&gt;

&lt;p&gt;That’s it! Just thought I’d finally document it as I think it’s a really effective way to test.&lt;/p&gt;

&lt;p&gt;So apparently it’s been one and a half year since my last blog post. I’m still here, just don’t always have much to say. Wish every reader a happy christmas and a nice 2026!&lt;/p&gt;
</description>
        <pubDate>Tue, 23 Dec 2025 21:13:54 +0100</pubDate>
        <link>http://thomasvanderberg.nl/blog/pentesting-firefox-containers/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/pentesting-firefox-containers/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Fix CJK font order on Linux (Ubuntu)</title>
        <description>&lt;p&gt;A short post for something I’ll probably need to remember in the future. In Unicode, Chinese simplified, traditional, and Japanese style characters all use the same glyphs. Font rendering is used to turn the glyph into a simplified, traditional, or Japanese style character. Today I found my Ubuntu system was using Japanese style characters while I wanted it to use Chinese simplified (since I’m learning that). Sadly changing this wasn’t as simple as a toggle in a menu, so here I write down what I did to fix it.&lt;/p&gt;

&lt;p&gt;For an illustration of the problem, see &lt;a href=&quot;https://en.wikipedia.org/wiki/Han_unification#Examples_of_language-dependent_glyphs&quot;&gt;Wikipedia: Examples of language-dependent glyphs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ubuntu’s font configuration is stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/fonts/conf.d&lt;/code&gt;. In this directory there’s a lot of files. Eventually I found that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;64-language-selector-prefer.conf&lt;/code&gt; contained the configuration needed to change the default rendering of CJK (Chinese, Japanese, Korean) characters. In this file, you can simply change the order:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/screenshot-font-language-selector.png&quot; alt=&quot;Picture of the content of the 64-language-selector-prefer file with SC put at the top of the list&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The default ordering seems to be Japanese first.&lt;/p&gt;

&lt;p&gt;To refresh the font config cache, you can run: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FC_DEBUG=1024 fc-cache&lt;/code&gt; (FC_DEBUG will make it so you can see which files are being read)&lt;/p&gt;

&lt;p&gt;This should fix the font rendering! Happy hacking.&lt;/p&gt;

&lt;p&gt;Note that Firefox ignores this configuration and instead uses its own font configuration under about:config key font.cjk_pref_fallback_order.&lt;/p&gt;
</description>
        <pubDate>Sat, 27 Jul 2024 12:37:43 +0200</pubDate>
        <link>http://thomasvanderberg.nl/blog/fix-cjk-font-order-linux/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/fix-cjk-font-order-linux/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>avoiding RSI and improving computer ergonomics with some scripting and a dmenu hack called kbmenu</title>
        <description>&lt;h2 id=&quot;rsi-issues&quot;&gt;RSI issues&lt;/h2&gt;
&lt;p&gt;A few months ago I got some beginning RSI symptoms: pain and tingling sensations throughout the lower arms and hands. The direct cause was an intense weekend writing a large pentest report, combined with programming scripts to ease the reporting in the future. At the same time I was configuring my new laptop and using a new windowing system which relied heavily on key combinations (win+this, alt+that, …). All in all I was hurting my hands heavily and they needed rest.&lt;/p&gt;

&lt;p&gt;I took the symptoms seriously and took a number of steps. I bought a new much more ergonomic desk and an ergonomic keyboard. I started taking frequent typing breaks and more and longer breaks in general. And I read online about methods to decrease strain on my hands while using my computer. After a few weeks, the symptoms subsided and currently I feel like I’m back to normal.&lt;/p&gt;

&lt;h2 id=&quot;single-key-shortcuts&quot;&gt;Single key shortcuts&lt;/h2&gt;

&lt;p&gt;While reading about computing ergonomics, I found a provocative article from Xah Lee called &lt;a href=&quot;http://xahlee.info/linux/why_tiling_window_manager_sucks.html&quot;&gt;Why Tiling Window Manager Sucks&lt;/a&gt;. I encourage you to read it even if you disagree with his conclusion, because he writes an interesting challenge to those who use tiling window managers in the article:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Try the following workflow for a week. I’d be interested to know if you still think tiling windows great.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;Remove tiling manager. Use a basic, normal, one, such as xfce.&lt;/li&gt;
    &lt;li&gt;Set workspace/virtual-screen to just 1. (and remove the tens of related keybindings)&lt;/li&gt;
    &lt;li&gt;Set up 3 function keys to switch to 3 of your most used app. For example, {F8, F9, F10} for {emacs, browser, terminal}. [see How to Set Key to Switch to Browser]&lt;/li&gt;
    &lt;li&gt;Set up 1 key to cycle windows within a app. F3. (trivial to do in xfce. Harder in lxde/openbox.)&lt;/li&gt;
    &lt;li&gt;Set up 1 key to switch to last window, such as F4. (this is normally Alt+Tab. In xfce, can be done easily. In lxde/openbox, the problem is that it requires pressing Enter to “exit” the switch, similar to releasing Alt.)&lt;/li&gt;
    &lt;li&gt;Set up 1 key to toggle max/restore window size. F1&lt;/li&gt;
    &lt;li&gt;Set up 1 key to close window. For example, F6 (must be 1 single key. Alt+F4 is not good.)&lt;/li&gt;
    &lt;li&gt;Set up 1 key to switch prev tab, and 1 key to switch next tab. (i use {F11, F12})&lt;/li&gt;
    &lt;li&gt;Set up 1 key to close tab. For example, the Pause/Break key. [see Print Screen, SysRq, ScrLk, Pause, Break Keys] (note: the prev/next tab key, and close tab key, should be next to each other. If you are using a full-sized IBM PC keyboard with numberpad, best to use / * - for {close, prev, next} tab, in that order. [see How to Program Number Keypad as Function Keys] )&lt;/li&gt;
    &lt;li&gt;Turn on mouse hover auto-raise window. (not just focus, but raise.) [see Linux: Mouse Hover to Raise Window]&lt;/li&gt;
    &lt;li&gt;Ban double-click. [see Linux: Set Mouse Single-Click to Open File]&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a heavy user of workspaces and having over time learned many keyboard shortcuts, I did feel like typing a lot of awkward combinations caused me a lot of awkward hand movements. I was intrigued by the idea of creating single key shortcuts using rarely used keys, an idea I had not thought of before.&lt;/p&gt;

&lt;p&gt;Since then I’ve setup my system to use a bunch of Xah Lee’s suggestions, and they’ve been working great. I’ve made my own changes though. Currently both my personal Linux system and my work Windows system have the following shortcuts configured:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;F2 - Copy&lt;/li&gt;
  &lt;li&gt;F3 - Paste&lt;/li&gt;
  &lt;li&gt;F4 - Switch to previous window (Alt+Tab)&lt;/li&gt;
  &lt;li&gt;F6 - Close window (Alt+F4)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, I’ve configured F8 to F10 for my most used apps on both systems. On Windows I reconfigured printscreen to be the same as ctrl+shift+s (select a region and make a screenshot) as I used it way more often. On Linux I set printscreen to the following script, which makes a screenshots and copies it to the clipboard:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/tmp/screenshot-&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;date&lt;/span&gt; +%s&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;.png
maim &lt;span class=&quot;nt&quot;&gt;--select&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
xclip &lt;span class=&quot;nt&quot;&gt;-selection&lt;/span&gt; clipboard &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; image/png &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m really happy with the new shortcuts as they save me from needing to make awkward hand combos for my most commonly used tasks. For Windows I used &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/powertoys/&quot;&gt;PowerToys&lt;/a&gt; to configured they keys. On Linux I used &lt;a href=&quot;https://github.com/autokey/autokey/&quot;&gt;Autokey&lt;/a&gt; as well as regular Xfce key bindings.&lt;/p&gt;

&lt;h2 id=&quot;key-sequences-to-key-menu&quot;&gt;Key sequences to key menu&lt;/h2&gt;

&lt;p&gt;Another interesting article I found from Xah Lee was &lt;a href=&quot;http://xahlee.info/kbd/banish_key_chords.html&quot;&gt;Ban Key Chords&lt;/a&gt; where he talks about key chords versus key sequences. Key chords require you to type multiple keys together, such as ctrl+shift+s, while key sequences let you type them like a text, for example alt, then e, then c to copy. I thought the idea of key sequences to be smart and I’m surprised they seem to be rarely used on Linux. In fact I couldn’t find a way to configure my own sequences in any way.&lt;/p&gt;

&lt;p&gt;At this time I thought it would be great to use a single rarely used key, such as F12, to show a menu where every key would lead to a specific action defined by me. I did some research, and couldn’t find any software that let me create such a menu easily. Eventually I decided I could take &lt;a href=&quot;https://wiki.archlinux.org/title/dmenu&quot;&gt;dmenu&lt;/a&gt; which comes close, and edit it so it would select an option as soon as it is no longer ambiguous. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmenu&lt;/code&gt; turned out to be easy to hack, and so I created my own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kbmenu&lt;/code&gt;, which can be used in scripts such as the following:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&amp;lt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Documents/keymenu.txt kbmenu &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; 20 &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; 2-&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
bash &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$run&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where keymenu.txt contains the following sequences:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;c tcopydb cwe.csv
r tradio*
s select-window-kb
m sleep 0.1s &amp;amp;&amp;amp; xdotool type ik@thomasvanderberg.nl
v tcopydb vuln-nl.csv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;* (See also &lt;a href=&quot;/blog/tradio/&quot;&gt;tradio&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The effect is that I can type F12, then any of the keys to run a command I’ve created. For example F12,m will write my full email address into any selected field. A number of other commands link to other scripts I’ve created, and it’s easy to add anything new to it.&lt;/p&gt;

&lt;p&gt;For ease of access I’ve put &lt;a href=&quot;https://github.com/tmsbrg/kbmenu&quot;&gt;kbmenu on Github&lt;/a&gt; though it is just a simple change. The only change was in the match function, which was replaced with the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matchend&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;textsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fstrncmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;appenditem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matchend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;curr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matchend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;curr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;calcoffsets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hope I gave you some interesting ideas for increasing your own ergonomics or computer efficiency. If you’re feeling pain in your arms and/or tingling, please take rest to let your hands recover and possibly check with a doctor if it takes longer than expected.&lt;/p&gt;
</description>
        <pubDate>Tue, 16 Aug 2022 19:48:46 +0200</pubDate>
        <link>http://thomasvanderberg.nl/blog/kbmenu-dmenu-hack-keyboard-menu/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/kbmenu-dmenu-hack-keyboard-menu/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Rejoice! You can use KDE filechooser in Firefox and other GTK apps</title>
        <description>&lt;p&gt;Today, I found out that it’s possible to use KDE filechooser in Firefox and other GTK applications thanks to the &lt;a href=&quot;https://github.com/flatpak/xdg-desktop-portal&quot;&gt;xdg-desktop-portal&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;To take advantage of this, make sure xdg-desktop-portal-kde is running (Starts automatically on Kubuntu. You should be able to run it manually if KDE is installed). Set the environment variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GTK_USE_PORTAL=1&lt;/code&gt;, for instance by appending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export GTK_USE_PORTAL=1&lt;/code&gt; to your ~/.profile. Since Firefox 98, you can also set Firefox to explicitly use xdg-desktop-portal through the configuration parameters under widget.use-xdg-desktop-portal.* (set them to 1 to always use the portal).&lt;/p&gt;

&lt;p&gt;Firefox portal configuration:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/firefox_use_portal.png&quot; alt=&quot;Firefox configuration parameters under widget.use-xdg-desktop-portal set to 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Old, GTK filechooser:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gtk-filechooser.png&quot; alt=&quot;GTK filechooser, the abomination&quot; /&gt;&lt;/p&gt;

&lt;p&gt;New, KDE filechooser, with image previews and other basic usability features:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/kde-filechooser.png&quot; alt=&quot;KDE filechooser, the our savior&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Life has been improved ✅&lt;/p&gt;
</description>
        <pubDate>Thu, 14 Apr 2022 22:27:03 +0200</pubDate>
        <link>http://thomasvanderberg.nl/blog/kde-filechooser-gtk-firefox/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/kde-filechooser-gtk-firefox/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Diving into userscripts</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Userscript&quot;&gt;Userscripts&lt;/a&gt; are something I never really investigated but always intrigued me. Last weekend I decided to finally check out how to make them.&lt;/p&gt;

&lt;p&gt;The trigger was the following page:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/youtube_sureyouwanttoleave.png&quot; alt=&quot;YouTube page containing the text &amp;quot;Are you sure you want to leave YouTube? This link is taking you to a site outside of YouTube (bit.ly)&amp;quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This nag page has been showing up lately whenever I click on a web link from a YouTube description or comment. Yes YouTube, of course I want to leave the website! It’s the world wide web and I clicked on a link!*&lt;/p&gt;

&lt;p&gt;It kind of annoyed me, so I wanted to see if I can get rid of it by writing a user script. Turns out it was pretty easy by checking what existing scripts did and turning it into my own thing. I published my script on &lt;a href=&quot;https://greasyfork.org/en&quot;&gt;Greasy Fork&lt;/a&gt;, a website for sharing userscripts. &lt;a href=&quot;https://greasyfork.org/en/scripts/439458-youtube-outgoing-links-fix&quot;&gt;Click here to view my script page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Installing a user script is as easy as installing the &lt;a href=&quot;https://www.tampermonkey.net/&quot;&gt;Tamper Monkey extension&lt;/a&gt; and then going to Greasy Fork and clicking “install” on a user script. Be sure to check the content of the script first though, as a malicious script could impersonate your session and do bad things on your behalf. Luckily most user scripts are very small and easy to audit manually (that’s rare in software!)&lt;/p&gt;

&lt;p&gt;Since it’s easy to include here as well, here’s the full content of the “YouTube outgoing links fix” script as I have it working now:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// ==UserScript==&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @name         YouTube outgoing links fix&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @version      1.0.2&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @description  Replaces outgoing links to avoid the YouTube &quot;are you sure you want to leave&quot; page&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @author       Thomas van der Berg&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @namespace    tmsbrg&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @match        https://www.youtube.com/*&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @grant        none&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @license      GPLv3+&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ==/UserScript==&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;use strict&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// from https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;replaceLinks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// bit of a hack: seems we need to wait for YouTube to do its stuff before we act&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;outgoing_links&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;a[href^=&quot;https://www.youtube.com/redirect&quot;]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;outgoing_links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;original_destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;outgoing_links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;decodeURIComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;original_destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;q=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;outgoing_links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;outgoing_links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// remove some YouTube specific stuff that tries to open youtube.com/redirect on click&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;yt-navigate-finish&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;replaceLinks&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The trickiest thing for me was figuring how to trigger my code whenever you open a new video, as YouTube doesn’t have a page reload when you click a video. I found in other peoples’ scripts that you can hook into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yt-navigate-finish&lt;/code&gt; event, so that’s what I did. Another tip: Since you’re just adding JavaScript to the page, you can test every step using the web console easily to see if it’s working as expected.&lt;/p&gt;

&lt;p&gt;The script just goes through every link where the target starts with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://www.youtube.com/redirect&lt;/code&gt;, and then replaces it with a direct link to where you want to go. I had some fun checking out some JavaScript programming to build it, as it’s been a while.&lt;/p&gt;

&lt;p&gt;I hope the script is useful for some others as well who are annoyed by the new YouTube redirect page. And I encourage you if you’re read up to here: The next time a website you’re using has an annoying feature or you’re missing something, see if you can write a simple userscript to make your life better and publish it. Let’s keep users in control of the web  ☺&lt;/p&gt;

&lt;p&gt;* Oddly enough, while testing out the page on Chromium for this blog, I couldn’t trigger it. It seems this nag page is only triggering for me on my Firefox. Maybe it’s my settings, but maybe it’s also another way for Google to annoy users to force Chrome on them.&lt;/p&gt;
</description>
        <pubDate>Tue, 01 Feb 2022 19:43:14 +0100</pubDate>
        <link>http://thomasvanderberg.nl/blog/diving-into-userscripts/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/diving-into-userscripts/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>makepty: A static executable to upgrade raw shells to PTYs</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://asciinema.org/a/7NHg67zFhsfZQnU17rY0J9Rtj&quot;&gt;&lt;img src=&quot;https://asciinema.org/a/7NHg67zFhsfZQnU17rY0J9Rtj.svg&quot; alt=&quot;asciicast&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve recently been spending time creating a static executable that can replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python3 -c &apos;import pty;pty.spawn(&quot;/bin/bash&quot;)&apos;&lt;/code&gt; for platforms which lack python, inspired by a FreeBSD box I was attacking on HackTheBox.&lt;/p&gt;

&lt;p&gt;The result: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;makepty&lt;/code&gt;, a little Rust program that simply creates a PTY and connects it with stdin and stdout. Click on the video above to see it in use.&lt;/p&gt;

&lt;p&gt;You can get more information on the &lt;a href=&quot;https://github.com/tmsbrg/makepty&quot;&gt;makepty Github&lt;/a&gt; and you can download it from the &lt;a href=&quot;https://github.com/tmsbrg/makepty/releases/tag/0.1.0&quot;&gt;static builds release&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ve tested it for Linux and FreeBSD and wrote extensive instructions on the Github page.&lt;/p&gt;
</description>
        <pubDate>Tue, 15 Jun 2021 12:46:31 +0200</pubDate>
        <link>http://thomasvanderberg.nl/blog/makepty-static-exe-upgrade-shell/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/makepty-static-exe-upgrade-shell/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>How Microsoft implemented and then removed a crucial Teams feature on Linux</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/teams-comparison-linux-windows.jpeg&quot; alt=&quot;Comparison of Teams for Linux and Windows in March 2021: Linux only allowing a 4 person view while Windows allows up to 49 participants to be viewed.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Teams is the most downloaded software of 2020. It is now used by offices, schools, courtrooms, governments, and pretty much every other type of organization. As the lockdown was active in april, I had to download Teams to contact my colleagues, as many others had to. At my current assignment, it is the main communication tool for the company.&lt;/p&gt;

&lt;p&gt;One feature Teams lacked at that time is to see more than four people on the same screen. A major shortcoming when compared to competition like zoom, especially in an environment where work events were now all online and could include tens even a hundred people.&lt;/p&gt;

&lt;h3 id=&quot;as-quickly-as-it-came-the-feature-was-removed-for-linux&quot;&gt;&lt;em&gt;“As quickly as it came, the feature was removed for Linux”&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;A few months later Teams users rejoiced: an update came that allowed everyone to view 9 people at the same time. I remember this feature being quickly available on both Linux and Windows. Then, about a week later, as quickly as it came, the feature was removed for Linux in another update. Though most of my Windows colleagues were able to see 9 participants in video calls, I was left with a view of only 4 people. For me and other Linux users, this was worse than before. Now we were left out. Though others could see something funny or nice a team mate is doing while muted, we saw nothing. Though others could see us, we couldn’t see them. At the time I thought there must have been a temporary bug. I patiently waited, as many others. See this &lt;a href=&quot;https://answers.microsoft.com/en-us/msteams/forum/msteams_tff-msteams_meeting-msteams_audio/teams-on-linux-more-than-4-people/13384d1f-a176-4111-8049-fcd7d257ff32&quot;&gt;Microsoft forum thread opened on september 2020&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now it is march 2021, at least half a year after this feature was briefly introduced and then removed for Linux, while remaining active on Windows. Since then, a new view was introduced that allowed windows users to see up to 49 users at the same time, which is great for large team events. However, on Linux we are still stuck with only being able to view four other people.&lt;/p&gt;

&lt;h3 id=&quot;stuck-on-a-backlog&quot;&gt;&lt;em&gt;Stuck on a backlog?&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;What happened? Microsoft employees in the forum thread I linked above say it’s being worked on and it’s on the backlog. However, one forum user noted that the backlog for Microsoft Teams and Linux is &lt;a href=&quot;https://filestore.community.support.microsoft.com/api/images/252f3bc6-b888-4e4e-a915-2d34b7e072e3?upload=true&quot;&gt;completely empty&lt;/a&gt;. Another forum user commented on how Teams is simply implemented as an Electron app, so it would be odd that some major Linux bug is keeping Microsoft from being able to re-implement this feature.&lt;/p&gt;

&lt;p&gt;So what’s taking Microsoft so long? Is it really being diligently planned but difficult to return? Is it stuck on a backlog? Or is this a case of the Microsoft’s Embrace, Extend, Extinguish, I’ve heard about a lot in the past?&lt;/p&gt;

&lt;h3 id=&quot;linux-users-are-still-here&quot;&gt;&lt;em&gt;Linux users are still here&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;I didn’t write this blog post to demonize Microsoft, but I really hope to be able to create some noise and make Microsoft realize Linux users are still here. We’re using Azure and other Microsoft products, and we just want to be able to interact with our colleagues as they are able to interact with us. So Microsoft, please re-enable large gallery view in Linux!&lt;/p&gt;
</description>
        <pubDate>Thu, 25 Mar 2021 10:34:08 +0100</pubDate>
        <link>http://thomasvanderberg.nl/blog/microsoft-removed-crucial-teams-feature-linux/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/microsoft-removed-crucial-teams-feature-linux/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Fastest fix for responsible disclosure I&apos;ve seen</title>
        <description>&lt;p&gt;Last week I was trying to buy something to fix a bicycle tire.&lt;/p&gt;

&lt;p&gt;I ended up on &lt;a href=&quot;https://www.bikebudget.nl&quot;&gt;BikeBudget&lt;/a&gt; and while looking around found a security vulnerability.&lt;/p&gt;

&lt;p&gt;After reporting it on friday their response was the fastest and nicest I’ve seen! Within an hour the vulnerability was fixed and they mailed me.&lt;/p&gt;

&lt;p&gt;In the end they offered to send me the tire fixing set for free, and they sent me a whole box of swag! Thanks! That’s really nice.&lt;/p&gt;

&lt;p&gt;Picture of the swag and thank you note:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/bikebudget-swag.jpg&quot; alt=&quot;bikebudget swag box with thank you note, tire fix set, and a bunch of small items&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 09 Mar 2021 10:41:11 +0100</pubDate>
        <link>http://thomasvanderberg.nl/blog/fastest-fix-responsible-disclosure/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/fastest-fix-responsible-disclosure/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>I created a webapp to help me learn simplified Chinese characters</title>
        <description>&lt;p&gt;Find common Chinese characters using pinyin.&lt;/p&gt;

&lt;p&gt;Click the image to try it now:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/cn/hanzi/&quot;&gt;&lt;img src=&quot;/images/hanzi_screenshot.png&quot; alt=&quot;Hanzi searchtool showing common Chinese characters pronounced &amp;quot;shi&amp;quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;what&quot;&gt;What&lt;/h2&gt;

&lt;p&gt;It’s a tool that allows you to enter pinyin and optionally a tone number and shows only the &lt;em&gt;commonly used&lt;/em&gt; Chinese characters with this pronunciation.&lt;/p&gt;

&lt;p&gt;It allows you to switch between the top 3500 character list (frequently used) or the top 6500 (relatively common),&lt;/p&gt;

&lt;p&gt;Some other features include showing or hiding all pinyin pronunciations for the characters, and showing or searching by the index of the character from the source &lt;a href=&quot;https://en.wikipedia.org/wiki/Table_of_General_Standard_Chinese_Characters&quot;&gt;Table of General Standard Chinese Characters&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It currently only deals with simplified characters, because that’s what the source deals with and what I’m trying to learn.&lt;/p&gt;

&lt;p&gt;Note that this is not a comprehensive Chinese learning tool. To learn Chinese you need to learn words, not just characters. Characters are just one layer in the Chinese language, and even full understanding of all Chinese characters would not mean you’ve learned the language.&lt;/p&gt;

&lt;h2 id=&quot;why-i-made-this&quot;&gt;Why I made this&lt;/h2&gt;

&lt;p&gt;While learning Chinese, I wanted to get an understanding of which Chinese characters are actually in common use. If you look in a dictionary for a list of Chinese characters, you will get a bewildering amount of characters. Dictionaries try to be comprehensive. Fortunately, most of these are only in historic use.&lt;/p&gt;

&lt;p&gt;I wanted to remove the forest of irrelevant (for my purposes) characters and find get a list of ones actually worth investing time into.&lt;/p&gt;

&lt;p&gt;I made this to get an overview and easily be able to answer questions like “how many common characters share this pronunciation?”.&lt;/p&gt;

&lt;p&gt;I also wanted it to work without having to wait for a web page to load for each query. I made it work using a fully offline search (you download the data when loading the page itself).&lt;/p&gt;

&lt;h2 id=&quot;sources-and-data&quot;&gt;Sources and data&lt;/h2&gt;

&lt;p&gt;During my search I found this official list of &lt;a href=&quot;https://en.wikipedia.org/wiki/Table_of_General_Standard_Chinese_Characters&quot;&gt;Table of General Standard Chinese Characters&lt;/a&gt; made by the Chinese government.&lt;/p&gt;

&lt;p&gt;Sadly, this list is a rasterized PDF which does not even contain the pronunciation of these characters.&lt;/p&gt;

&lt;p&gt;Still, it seemed like a good authoritative reference of commonly used characters. I started searching around and found a text version of it on &lt;a href=&quot;http://xh.5156edu.com/page/z6211m4474j19255.html&quot;&gt;this Chinese webpage&lt;/a&gt;. While checking the data I found it had some mistakes around characters 3649 to 3668, which I had to fix manually.&lt;/p&gt;

&lt;p&gt;To combine this with pronunciation data I found the &lt;a href=&quot;ftp://ftp.cuhk.hk/pub/chinese/ifcss/software/data/Uni2Pinyin.gz&quot;&gt;Unicode Pinyin Table&lt;/a&gt;. I’ve added numerouos pronunciations manually, when I found them missing from that source. I’ve logged my manual edits in &lt;a href=&quot;/files/edits-to-hanzi-pinyin.txt&quot;&gt;edits-to-hanzi-pinyin.txt&lt;/a&gt;. Note that since I’m only a basic Chinese speaker myself, I can’t exclude that there’s likely more mistakes. I’m open to using a more reliable source for pronunciation data if one is available.&lt;/p&gt;

&lt;p&gt;Using this data I created the &lt;a href=&quot;/files/hanzi-pinyin.6500.csv&quot;&gt;hanzi-pinyin.6500.csv&lt;/a&gt; and &lt;a href=&quot;/files/hanzi-pinyin.3500.csv&quot;&gt;hanzi-pinyin.3500.csv&lt;/a&gt; files which are the source of the Hanzi search tool.&lt;/p&gt;

&lt;h2 id=&quot;how-did-i-make-this&quot;&gt;How did I make this&lt;/h2&gt;

&lt;p&gt;Originally I just used &lt;a href=&quot;https://en.wikipedia.org/wiki/Grep&quot;&gt;grep&lt;/a&gt; to search the hanzi-pinyin CSV files, but found it to become cumbersome due to the need to write regular expressions when I just wanted to think about pinyin.&lt;/p&gt;

&lt;p&gt;I created the &lt;a href=&quot;/files/cnhz.py&quot;&gt;cnhz&lt;/a&gt; python script for myself, originally as a simple wrapper to build the grep regexes for me so I could just write pinyin. I then added more features around it.&lt;/p&gt;

&lt;p&gt;As it got more useful I thought about how I could make it more accessible for other Chinese learners too. Most of them do not use Linux or have Python installed. I thought of rewriting it in Go to make it a single executable - but found the command line format would be awkward for most people. Also Windows cmd.exe does not support Chinese characters.&lt;/p&gt;

&lt;p&gt;I eventually decided to turn it into a webpage. the CSV files were sufficiently small that the entire database could be loaded into the browser’s memory so you could do a completely client side search - making the experience much smoother than loading an online dictionary entry.&lt;/p&gt;

&lt;p&gt;Also, because I can easily host it on my own web page, which I pay for anyway, I don’t have any need to add advertisements or anything to make the experience worse.&lt;/p&gt;

&lt;p&gt;Furthermore, the page can easily be downloaded and used offline by any learner in case my site goes down or for when you don’t have internet.&lt;/p&gt;

&lt;p&gt;I tried to support offline working more by making the site into a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps&quot;&gt;progressive web app&lt;/a&gt;. However, while adding a manifest was easy, I found that to add a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API&quot;&gt;service worker&lt;/a&gt; (which allows offline caching) - I would have to move all assets including a copy of my main CSS file to /cn/hanzi/. Not having time to figure this out at the moment, I decided to not add service workers for now.&lt;/p&gt;

&lt;p&gt;By the way, the &lt;a href=&quot;/js/hanzi_list.js&quot;&gt;hanzi_list.js&lt;/a&gt; file was generated from the CSV sources using an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt; script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt; ../files/hanzi-pinyin-full.csv \
    awk \
    &apos;NR==1 { printf &quot;const hanzi_3500 = \&quot;&quot; }
     NR==3501 { printf &quot;\&quot;; const hanzi_6500 = hanzi_3500 + \&quot;&quot; }
     { print NR&quot;,&quot;$0&quot;\\n\\&quot; }
     END { print &quot;\&quot;;\nconst hanzi_6500_split = hanzi_6500.split(\&quot;\\n\&quot;);&quot; }&apos; \
 &amp;gt; ../js/hanzi_list.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I hope you find my &lt;a href=&quot;/cn/hanzi&quot;&gt;Chinese hanzi tool&lt;/a&gt; useful. If you have any questions or want to contact me, see my details below.&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Oct 2020 14:56:10 +0200</pubDate>
        <link>http://thomasvanderberg.nl/blog/cn-hanzi/</link>
        <guid isPermaLink="true">http://thomasvanderberg.nl/blog/cn-hanzi/</guid>
        
        
        <category>blog</category>
        
      </item>
    
  </channel>
</rss>
