Some work yo.

This commit is contained in:
Julien Palard 2017-11-18 18:28:22 +01:00
parent 01d3b4306e
commit 801d3776a6
6 changed files with 339 additions and 5 deletions

View File

@ -40,9 +40,6 @@ endif
html:
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
rsync:
rsync --delete -vah ../ mdk.fr:/var/www/
help:
@echo 'Makefile for a pelican Web site '
@echo ' '

View File

@ -0,0 +1,141 @@
Title: Compose Key vs Dead Key
Date: 2017-07-12
L'AFNOR à lancé autour de juin 2017 un appel à commentaires à propos
de [la normalisation du clavier
français](http://www.afnor.org/presse_juin2017/clavier-francais-afnor-ouvre-projet-de-norme-aux-commentaires/),
réunissant 3725 retours.
Parmis ces retours certains mentionnent la compose key :
> […] il est possible de composer une quantitée de symboles bien plus
grande qu'avec une dead key
> […] et éventuellement une touche de composition pour permettre
d'obtenir des caractères exotiques ou non-latins (ex: compose + oc
= © / compose + or = ® / compose + tm = ™
> Un clavier permettant de composer simplement les emojis les plus
courants semble donc répondre à un réel besoin.
> Une alternative que je trouve intéressante serait de proposer une
touche "Composer" (en référence à la touche utilisée sur les
anciens claviers Sun) qui permettrait de composer des ligatures.
> Il sagit dune touche morte qui permet de composer «visuellement»
les caractères non présents sur le clavier. Par exemple :
[COMPOSE]+[O]+[/] = Ø
> La touche morte traditonnellement appelée «composition» (ou
«compose», aussi en français par anglicisme) devrait être appelée
«touche morte neutre», surtout depuis que selon Unicode, des
lettres sont composées à partir de caractères indépendants et de
diacritiques combinants. On a des caractères précomposés qui
peuvent être décomposés. Dans cet espace conceptuel, une touche
morte de composition semble ne plus avoir de place.
Lors de la première réunion de dépuillement des commentaires, l'AFNOR
a rejeté l'idée de la compose key, la trouvant je cite "trop
compliquée".
# Les dead keys
Les [dead keys](https://en.wikipedia.org/wiki/Dead_key) sont des
touches permettant d'attacher un signe à la frappe suivante,
typiquement un caractère.
Il faut donc une touche morte par diacritique.
Ainsi, si la touche `[']` est une touche morte, suivie d'un `[e]`, elle
donne `é`.
# La compose key
La [compose key](https://en.wikipedia.org/wiki/Compose_key) est comme
un commentaire le mentionne une "touche morte neutre", elle permet
comme son nom l'indique de "composer" les touches suivantes, c'est à
dire de les "assembler".
Il n'y a donc qu'une seule touche "compose" sur un clavier.
Ainsi, `[COMPOSE] [e] [']` donne `é`.
# Compatibilité
Il n'existe aucune incompatibilité à proposer des dead keys et une
compose keys sur une même disposition physique: les touches mortes
étant des diacritiques et la compose key une autre touche.
# Avantages et inconvénients
## Avantage de la dead-key
Les touches mortes permettent accès rapide aux saisies courantes: `[']
[e]` suffit pour obtenir un `é`, alors qu'il faut taper `[compose] [']
[e]` avec une compose key.
## Inconvénient de la dead-key
Il est plus lent d'obtenir une diacritique seule, comme l'apostrophe,
pour lequel il faut taper `['] [ ]`, ce qui n'est pas
intuitif. L'intuition ammene aussi certaines personnes à taper
`[']['][backspace]` pour obtenir une apostrophe.
Cet inconvénient n'a pas le même impact pour toutes les dead keys, ni
dans tous les environnements, typiquement les guillemets, souvent
utilisé par paires, peut profiter de la séquence `["] ["]` générant
deux guillets, l'utilisateur peut ainsi se décaler entre les deux
guillemets pour y saisir son texte.
## Avantage de la compose key
La compose key permet de composer des caractères au delà des
diacritiques, sans alterer le comportement des touches diacritiques,
et ce de manière intuitive puisque c'est souvent une simple
superposition visuelle de caractères. Aussi la pluspart des compositions
peuvent se composer dans les deux sens : `[compose] [e] [']` et
`[compose] ['] [e]` sont identiques.
Voici quelques exemples typiques tirés d'un fichier de configuration
de la
[libX11](https://github.com/mirror/libX11/blob/master/nls/en_US.UTF-8/Compose.pre)
:
- `[compose] [o] [c]` donne `©`
- `[compose] [o] [r]` donne `®`
- `[compose] [+] [-]` donne `±`
- `[compose] [?] [?]` donne `¿`
- `[compose] [ ] [ ]` donne un espace insécable
- `[compose] [s] [s]` donne `ß`
- `[compose] [S] [S]` donne `ẞ`
- `[compose] [o] [e]` donne `œ`
- `[compose] [O] [E]` donne `Œ`
- `[compose] [o] [o]` donne `°`
- `[compose] [<] [<]` donne `«`
- `[compose] [>] [>]` donne `»`
- `[compose] [%] [o]` donne `‰`
- `[compose] [=] [e]` donne `€`
- `[compose] [c] [|]` donne `¢`
- `[compose] [L] [-]` donne `£`
- `[compose] [y] [=]` donne `¥`
- `[compose] [.] [.]` donne `…`
- `[compose] [N] [o]` donne `№`
- `[compose] [<] [3]` donne `♥`
- `[compose] [:] [)]` donne `☺`
- `[compose] [:] [(]` donne `☹`
- `[compose] [p] [o] [o]` donne `💩` (U+1F4A9 "PILE OF POO")
Ce fichier contient 4042 compositions au total, dont une partie non
négligable n'est évidemment pas atteignable avec une dead-key, comme
ẞ, qui nécessiterai que le `[s]` soit une touche morte.
Parmis ces exemples, certains sont intéressants à utiliser au
quotidien dans certains métiers, comme №, √, →, ✓, ✗, ±, …, ≠, ≤, ≥,

BIN
content/images/cat.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

BIN
content/images/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

View File

@ -13,12 +13,18 @@ Senior software architect at [meltygroup](https://www.meltygroup.com).
[docs.python.org/fr/](https://docs.python.org/fr/),
[git repository](https://github.com/python/python-docs-fr),
[progression](https://mdk.fr/blog/python-documentation-translation.html)).
- [Code en Seine](https://codeenseine.fr/): An bi-monthly free Python workshop at the CRI Paris.
- [Hackinscience](https://hackinscience.org/): A yearly Python intensive week at the CRI Paris.
- [logtop](http://julienpalard.github.io/logtop/) a realtime log line analzer, Debian packaged.
- Many others on [my github account](https://github.com/julienpalard).
- [pipe](https://pypi.python.org/pypi/pipe/) A Python module enablig a sh like infix syntax (using pipes).
- [vt100-emulator](https://github.com/JulienPalard/vt100-emulator) A headless terminal emulator in C89.
- [turtl-backup](https://github.com/JulienPalard/turtl-backup) A tool to backup a turtl / framanotes account.
- Many others on [my github account](https://github.com/JulienPalard).
- Join me on IRC, I'm `mdk` on [freenode](https://webchat.freenode.net)
- [My CV](https://mdk.fr/Julien-Palard.pdf)
- [My ssh key](https://mdk.fr/id_ed25519.pub)
- [My gpg key](https://mdk.fr/gpg.pub)
- I'm `mdk` on [freenode](https://webchat.freenode.net)
> "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook - The Wizardry Compiled (1989) -

View File

@ -0,0 +1,190 @@
status: hidden
title: Cybersécurité — Code Review
slug: di3oK1oochatha-codereview
robots: noindex
# Code Review
Le nom du projet est: `codereview`, en minuscule (c'est important pour
le [rendu](https://mdk.fr/pages/obiree2uaza2sh-rendu.html)).
Contexte : Vous faites de la relecture de code pour un projet open
source que vous utilisez depuis fort fort longtemps (mais après les
cours de sécu, vous vous êtes décidés à aller relire ça) donc tout ce
que vous écrivez est public, sera lu par des inconnus, et le core dev
qui fait ça sur son temps libre et pour le plaisir, et ne parle pas
forcément français. Ah et c'est sur github donc vous rédigez en
Markdown. Vous pouvez rendre une faille par fichier markdown (comme
si vous ouvriez une issue par faille, une issue = un fichier).
Le code est fourni, vous devez donc le relire, lister les failles que
vous voyez, pour chaque faille l'expliquer suffisamment clairement
pour prouver qu'elle est exploitable, voir fournir un expemple
d'exploitation, et vous devez proposer une correction. N'oubliez pas
que vous vous adressez à un développeur, qui n'a pas forcément votre
niveau, mais qui est peut être meilleur dans d'autres domaines.
<?php
$db = new PDO('sqlite:'.dirname(__FILE__).'/db.sqlite');
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->query(
"CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
login TEXT UNIQUE,
password TEXT,
is_admin INTEGER
)");
$db->query(
"CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created DATETIME,
user_id INTEGER
)");
$db->query(
"CREATE TABLE IF NOT EXISTS articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
body TEXT
)");
$db->query('INSERT OR IGNORE INTO users (login, password, is_admin) VALUES ("admin", "admin123", 1)');
if (!empty($_COOKIE['session_id'])) {
$session_id = $_COOKIE['session_id'];
}
else {
if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
list($login, $password) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], strlen("Basic "))));
$user = $db->query(sprintf('SELECT id, is_admin FROM users WHERE login = "%s" AND password = "%s"', $login, $password))->fetch();
}
$db->query(sprintf("INSERT INTO sessions (created, user_id) VALUES ('%s', '%s')",
date("Y-m-d H:i:s"),
$user['id']));
$session_id = $db->lastInsertId();
}
$session = $db->query(sprintf(
"SELECT * from sessions LEFT JOIN users ON users.id = sessions.user_id WHERE sessions.id = %s",
$session_id))->fetch();
if ($_GET['page'] == 'users')
{
if ($_SERVER['REQUEST_METHOD'] == 'PUT' ||
$_SERVER['REQUEST_METHOD'] == 'POST' ||
$_SERVER['REQUEST_METHOD'] == 'GET')
{
if (!$session['is_admin'])
{
header('HTTP/1.0 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Admin Zone');
die();
}
}
if ($_SERVER['REQUEST_METHOD'] == 'PUT')
{
$db->query(sprintf('UPDATE users SET password = "%s" WHERE id = "%s"',
$_GET['new_password'], $_GET['user_id']));
}
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$db->query(sprintf('INSERT INTO users (login, password, is_admin) VALUES ("%s", "%s", 0)',
$_GET['login'], $_GET['password']));
}
// Que ce soit un GET, PUT, ou POST on affiche la liste:
// TODO: tpl, en attendant, var_dump ça suffit, c'est une page d'admin.
var_dump($db->query('SELECT * FROM users')->fetchAll());
}
if ($_GET['page'] == 'sessions') {
if (!$session['is_admin'])
{
header('HTTP/1.0 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Admin Zone"');
die();
}
var_dump($db->query('SELECT * FROM sessions')->fetchall());
}
if ($_GET['page'] == 'redirect') {
/**
* Do not allow open redirects, only signed redirects. Open redirects
* allow easy phishing (presenting pretty URLs with legit domain,
* redirecting to phising site.
*/
$target = $_GET['target'];
$given_checksum = $_GET['checksum'];
if (sha1($target) != $given_checksum)
{
header('HTTP/1.0 400 Bad request');
die();
}
header("Location: " . $_GET['target'], TRUE, 301);
die();
}
if ($_GET['page'] == 'static') {
/**
* Allow static assets to be included. Only from ./static/. We're using
* PHP even for static assets so we can later minify CSS and JS on the fly
* \o/
*/
include "./static/" . $_GET['asset'];
}
if ($_GET['page'] == 'upload') {
if (!isset($_FILES['file'])) {
echo '<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="upload">
</form>';
die();
}
$uploaddir = './uploads';
@mkdir("./uploads", 0700);
$uploadfile = $uploaddir . '/' . basename($_FILES['file']['name']);
assert('!in_array("' . $_FILES["file"]["type"] . '", ["image/jpeg", "image/png"])');
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
echo "Uploaded successfully: <a href='$uploadfile'>$uploadfile</a>\n";
die();
}
}
if ($_GET['page'] == 'new_article') {
/**
* We hired a remote dev to do the client. Note for later: Don't fscking
* do that ever again. He did everything in Python (Like PHP was not the
* obvious choice? (spoiler: he won't get paid)) And he insisted on
* transmiting everything as base64 encoded "pickled" values, telling
* that's better than json and easier than protobuf, srly? Fsck this.
* Plus I hate Python documentation, there's never A SINGLE FSCKING
* EXAMPLE in this FSCKING DOC. Hopefully I found an example on
* stackoverflow, thanks Google for ranking SO before python, but sorry
* for the code. TODO: Rewrite the client in PHP.
*
* Test data:
* gAN9cQAoWAQAAABib2R5cQFYFgAAAERvbG9yLCBtdWNoIG11Y2ggZG9sb3JxAlgFAAAAdGl0bGVxA1gLAAAATG9yZW0gSXBzdW1xBHUu
*/
$base64_encode_picke = $_GET['article'];
exec(sprintf('python3 -c "import json; import pickle; import base64; print(json.dumps(pickle.loads(base64.b64decode(%s))))"',
"'" + $base64_encode_picke + "'"), $output);
$json = json_decode($output[0], TRUE);
$db->query(sprintf('INSERT INTO articles (title, body) VALUES ("%s", "%s")',
$json['title'], $json['body']));
}
if ($_GET['page'] == 'articles') {
// TODO: Template.
var_dump($db->query('SELECT * FROM articles')->fetchall());
}
setcookie('session_id', $session_id);