From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Authentication-Results: plum.tunbury.org; dkim=pass (1024-bit key; unprotected) header.d=inria.fr header.i=@inria.fr header.a=rsa-sha256 header.s=dc header.b=VHmXNNJT; dkim-atps=neutral Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.134.164.83; helo=mail2-relais-roc.national.inria.fr; envelope-from=caml-list-owner@inria.fr; receiver=tunbury.org Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by plum.tunbury.org (Postfix) with ESMTP id 816B940094 for ; Tue, 27 Oct 2026 10:29:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:date:message-id:mime-version:subject:reply-to: sender:list-id:list-help:list-subscribe:list-unsubscribe: list-post:list-owner:list-archive; bh=2M2+AZnYN8oOY+qQ+dI7et0wr4HN4lMXwcCdpY4tbTY=; b=VHmXNNJTpUJRuvYH9nijWuKCSUc74si7mvJyRwt1QzsOrEgc9aWpRPxL h457ejlJNRQEK47pmOOeM4eGRr9NHryRnS/XyIDCsjs/2OSsdNQ+39hs6 L6yV2RHUO03Z7G8MVcRUAA1KDC0CtiF2cgBnnnapxizoVu/yV3zINqUHF o=; X-CSE-ConnectionGUID: vlgp3COwS7e4jSR9oSJ8Xg== X-CSE-MsgGUID: tVJqNo4YRf6qo0pgYGWllA== Authentication-Results: mail2-relais-roc.national.inria.fr; dkim=none (message not signed) header.i=none; spf=Pass smtp.mailfrom=caml-list-owner@inria.fr; spf=None smtp.helo=postmaster@prod-sympa-app.inria.fr Received-SPF: Pass (mail2-relais-roc.national.inria.fr: domain of caml-list-owner@inria.fr designates 128.93.162.27 as permitted sender) identity=mailfrom; client-ip=128.93.162.27; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="caml-list-owner@inria.fr"; x-conformance=spf_only; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:128.93.142.0/24 ip4:192.134.164.0/24 ip4:128.93.162.160 ip4:128.93.162.3 ip4:128.93.162.88 ip4:128.93.162.27 mx ~all" Received-SPF: None (mail2-relais-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@prod-sympa-app.inria.fr) identity=helo; client-ip=128.93.162.27; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="postmaster@prod-sympa-app.inria.fr"; x-conformance=spf_only X-IronPort-AV: E=Sophos;i="6.27,181,1787004000"; d="asc'?scan'208";a="302493235" Received: from prod-sympa-app.inria.fr ([128.93.162.27]) by mail2-relais-roc.national.inria.fr with ESMTP; 27 Oct 2026 11:29:28 +0100 Received: by prod-sympa-app.inria.fr (Postfix, from userid 990) id 70A4881F49; Tue, 27 Oct 2026 11:29:27 +0100 (CET) Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by prod-sympa-app.inria.fr (Postfix) with ESMTP id E317981F06 for ; Tue, 27 Oct 2026 11:29:21 +0100 (CET) X-CSE-ConnectionGUID: CwOnlDlgSmiN/i9cm1u1Lw== X-CSE-MsgGUID: QaSaNfqkQ3Kp4G98UxErvw== IronPort-SDR: 6ae07cff_dLqqLXhjziAcgE1zKFW4SF3oXu4fpQ+okzctFphRM+gS6Mw IPobQRsmb9lVTx0mC0VR43Q6cABIffMr7S0hBoQ== X-URL-LookUp-ScanningError: 1 X-ThreatScanner-Verdict: Negative X-IPAS-Result: =?us-ascii?q?A0GnBgDSe+BqjyIeaIFSAgYWgkWCFikbAW9hMwcISQNhg?= =?us-ascii?q?zg8g0+LRYJggRaQN4sKgVyBDh0WIQIOBwEDAQgFLgYaAQIEAQEBAgECAYILk?= =?us-ascii?q?Q0CHwYBBDQTAQIEAwIDAQEBAQEBAQEBAQELAQEBBAEBAQIBAQIEAwEBAQECE?= =?us-ascii?q?AEBAQEBATkFSYYVAQU0DUkBiUgBgWpRUx5eAgQDBgcBAQEBAQEBAQEBAQEBA?= =?us-ascii?q?SIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA?= =?us-ascii?q?gQEBAGBAg4OAQgEGQEBLAIBAwYYIwMNAgwDAhEBNQMBJhQGAYIPWAGCIgJQA?= =?us-ascii?q?wUMBpopmlIbN3p/M4EBggwBAQaBCT4FDQMPL9obgWIJCYFNgViEGoJRDw0Bd?= =?us-ascii?q?GqEX4MagR0CJw+BVUSBFTWBdEoHb4FQLkwXAQEBARiBCAQTBQEBBgICBmkHA?= =?us-ascii?q?oJ5gmqCERV6EoE8NgYFWwUJhWeOA4JCLAFVExcLBwVggQgDgQZuMh2BIz4XL?= =?us-ascii?q?1gbBgWBHYEedSprgQddgSspYSGBCIF2AoJRggACAUlBDgdFUwklQxJHJCIIE?= =?us-ascii?q?gkBExouC4EaNTwJJkEVDGQLGgViCAINDHs5EDUgJG09NxUZkCgQIQ2CGBmCP?= =?us-ascii?q?goEEg0ZBgEBDQgXBDARAgcHAgUFAQgCBgMQBgEBIAIsAgQEBRcHFQEHAwIDC?= =?us-ascii?q?xoIBAMGBAIIAwEBFgEJAQUGBgkEBgUGAgkCBBgCDwOEYIgthUoJBxQBAwUBH?= =?us-ascii?q?gIFAgOPWINWikOTWR1tNAeEIYFgBgyJCoEmjjSHU4QEgVeLPYcDklQilgOCY?= =?us-ascii?q?4JZhiiBAF1JCYFva4h6hxuFDxApAwQTGARohD6BfyM8DWIeDAczGjBDgjMBA?= =?us-ascii?q?QExCUccD4xwWmECAQURgRQBAYJKEIEugSaBOzkXJDwegRfHN0M1AgEBBwMxB?= =?us-ascii?q?wIHAQELAQOFawEBRyKCSYhVASYHBWsEXQEB?= IronPort-PHdr: A9a23:tnlPzRK7/c97pmrsJdmcuMFoWUAX0o4c3iYr45Yqw4hDbr6kt8y7e hCEu7M11hSQANqBsLptsKn/jePJYSQ4+5GPsXQPItRndiQuroE7uTJlK+O+TXPBEfjxciYhF 95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRoLerpBIHSk9631+ev8JHPfglEnjWwbL1zI RmssQndqMYajZZiJ6sz1BfErGZDdvhLy29vOV+ckBHw69uq8pV+6SpQofUh98BBUaX+Yas1S KFTASolPW4o+sDlrAHPQwSX6HQTS2kbjBVGDRXd4B71Qpn+vC36tvFg2CaBJs35Uao0WTW54 Kh1ThLjlToKOCQ48GHTjcxwkb5brRe8rBFx34LYfIeYP+d5ca3AYNMaXnJBUdhNWCxdDI28a I4PAPAAPeZesoLxo1QDoB+7CQSqGejhyCJHhmXu0KM6zeovDA/I0g8vEN0Sq3nUo8n5Ob0IX Oyp0KXFzzPOZO5W1zfn74jIdwgsrO2IXb1qd8ra1FQhGB/FjlWVqIzlIy+V3fkKvmeB6+pvT +Svh3Q8qw5tojivw8YsipXVho8O0lDE8iF5wYYpJdKmVEF7YdikEJpJtyGHKYR6WMQiQ3tnu CsjzLANpJG0cjQQxps92x7fd+KIc5KO4h/7UOucIjN1iW5ldry/mRq8/1WsxvD8WMe00FtHs jRIn9jRu30P2RHe6sqKR/h580qh1ziB1wHe5+VKL0wplKfWL5gsyaM+mJoUtETMBC72mEPug a+Rakor4O2o6+D9brXhvJ+cOJd4ihz4MqQvmcywH/44PhIIX2if4ei827zj/VH5QLVXlfI6i LXWsJffJcgDqa65AhNV0oY+6xmkFTum0dMYkWEILFJCfxKHgIzpNE/ULP/kCve/hkygkC1sx //dI73hGI/BIWTEkLfmZbZx81RcyA0owtBC/ZJYEK0OIPX0Wk/prtDYDxk5PxSzw+b8Etp9y 5kSWXiRDaOBMaPSt1GI5uYyI+iDeYAaoir9JOI/6/Hyin85nEcRfaaz3ZQNZnC3BPJmLF+Db XXwhdcBFH8Gvg8kQ+zrjF2CUDhTZ3m2X64m/TE7FJqqAp3DRoC3nrOB0jy7EodKaWBBD1CAC WvoeJ+eW/cNdS2dPNRhniYYWrimTo8tzRauuxPgxLpiKurU4jcYtZX52Ndp4O3TkAk+9TtoA MuH1mGNS3h4nngGRzMs26B/u0N9xk+e0ah+gvxYFsJc5+lPUggkMZ7Q1el6C9TqVgLOeNeJV UyqQtK8ATE+Vt4xwtkOY1x8G9q4lBzD0TCqD6cSl7OQBpw77L7T32TrK8ZhzHbKzLMhgEc6T ctIL22pm7Rz+BXJCI7ViUqVj6GqergH3C7M+2eM02yOsFtfUA5qXqXJRWwQZkvMotT/6UPNU aSuBa4iMgRc0cKCLa1Kasf3glVAWfjsJs7eb3itlGe3ABaE3quMbI7wdGQd0yXdEk8Ekx0V/ XmbLwQxHDuhrmTDBzJtDVLie17g/fd6pX+hU0M40w6HY1dv2rap4BIYi/ORR+sO0r8KpSsts St4EVay0t7MFdaMuhBtcLtTbN455lpMyHjXuBZnPpO6KqBvnl4efBpzv0Ppzxh3D4pBndUwo HMyywpyLaKZ0E9feDyE3ZDwPLzXKnDv/B+xcaLW3Uve0NmO9qcO7vQ3tUnjsRm0GkY893hry cRZ32eT65nQAgceTYj9X0g4+hRiorHVeCg954fa1X12Nqm0tyfP1c81CuU41hqtZ9hQML6EF Q/9C8AUBNSgJfQym1iuahIFPPxS+7AoMMOmcfuG2berPPt+kz68imRH+o9931qW+Cp4UOHI2 YwJw+qE0QuHUjf8jUuhstzslI9fYjESA2y/xjT6C45KfKFyeIkGCGi0L82w3NV+iIbhW2RE+ 167G1MGxMipdAKOYFPn2A1Q0V0boXimmSuj0zx5iCopr6qa3CzW2evubhsHOmhRRGljl1jgO 4a0j8oCUEiudAcmjAGl6lrix6hHuKR/KHHeTVpQcyj5MW5iVai+uKCabsBP9J0kqT9XX/qiY V6ZULDwux4a0iz+E2dE3DA7cDWqu5XlnxNklG2dLHBzrHvAecFt2xjT/tvcReRe3jYeWSZ4i jjXBl2kMtex8tubmYnNvPyiWmynTpFcbCzrwpmatCSn/WBkGQSxkei8lNH/Cgg6ySH72sFwW yjUsRjyf5Hn17+iMeJpZkZoBEHz6859GoxmiIU9mIwe12VJzqmSqHEOlGO2NdRAxYr/amAMT HgF2Y37+g/gjWRnJ3TB/In5U3SB3oM1bt2zZCUN0SI47txWIL+T6K1YkCB1pFuhsA+XZuJyy GROgcAy4WIX1rla8DEmyT+QV+xDdaE5FSnllhDTqsu7sL0Sf2G3N765yEt5m9mlSrCEuABVH njjKd85BSElyMJ5PRrX1WHrrJn+cYzZadsV8AafkxLBk/R9MJU1h+YHjiphOHvgsDsi0eFox Qd208SCtZOcY35o4Lr/BxdZMjPvYMZGwQvW1fNgg9eZiqGVS41mHiQXUZDoS/OxDT9Usu7oY g+KGTt6sXybHLvDASeV71pgpH/UVZX3JzeQPnZKhc56SkylLVdEyBsRQC18npM9EVWyw9f9d U5i+j0Lzlvo811UzeZ5KxT0UmHevRqlLDAuR/BzNTJw6QdPrwfQOM2atadoGj1Au4amtEqLI 3CaYAJBCScIXFaFDhbtJOvm496I6OWeCuekSpmGKbyTtexTUeuJzpOzw8Nn+TiLLMCGInhlC bUyxENCWXlzH8mRlS8ITmQbkCfEbsjToxnZmGU/p8S29rLwUwLq5JeTI6NVNcRz9hu2h6aaK uPWgzx2aH5Z2p4K2X7U2e0HxldB7kMmPzKpELkGqWvMVPeJwP4RVkZHLXgrcpAUvMdelkFXN MXWi834zOt9h/8xUBJeUED539qufYoMKn28M1XOAACKMq6HLHvF2ZKSA+v0RLtOgeFTrxD1t yycFhqpBQ64z2zXSgGgZMB22TmcOA1CtYq9dBd0FGWlS8jpPxS/OdkxljY2xLwomlvAMnMaO jVnNUYRvvuX9ywS0ZAdUyRRq2FoK+WJgXPT5u3RLNANuvtuAzhov/pd5GUmxrBV6iBdWfEzn zHd5I0LwRnugqyEzTxpVwBLozBAideQvElsDq7e84FJRXfO+B9lAXy4Mx0RvJMlD9Tuv/sV0 d3TjOfoLy8E9dvI/MwaDsySKcSdMXNnPwC7UDLTCQIES3asOwS9zwRmqsrKo0OIv5dvi6K5g J0KW6NWX1wzF+oHBwJiBtNXKZN+WHU/mr6ejdIUzXC5sR/aSd4cu8zXEPWIDpCNYH6VgKJFa B0B3b7jZd1JZ8uigxAkMQE8x9iCElGYRd1Xpyx9cgI46F5A9nRzVCxWuQqtaw+g5mMSCe/hm xc3jgVkZuF+vDzo4loxOh/LvH5pyhh3wI25x2vJNmWtf8LSFclMBiH5tlY8KMb+SgdxNkipm FB8cSzDX/RXhqdhcmZijEndv4FOELhSV/4hAldYyPeJavEvyVkZpD+gwBoN3tH+Uc5ciRolJ L+W+mpH3xN/YdU1I63JOacPyUJf06uKtynuzesxxQ4CO24H936UcyMT/klUJv8hPSXirYkOo USS3iBOfmQBTa9gmchRrhYDJvWPmgPahqZELlGtOuefKaKApmWGktSHF1o030VOjEJF+Llqz e8pdFeSXE00ir7NB1IOL8WIemQ3J4JCsXPUeyiJq+DEx5l4ap68Gu7fRuiLrK8Ig0igEVVhD 8EW488GBJXpzFDAIJKtMuse0Rt0rleORh3NHLFTdRmMijtCv8yv0Mo9w9xGPj9ESSZ8KXnlv +yG4FZy3LzYBJFtPj9ZX5NYZCtsCYvjw3If5CwGV2TSsKpRiwmas22t/2KJVmC6MYAlPa/LL VBtEI/ko21nqvrq0FKPoJyMeGj3aIYw5NOQubFB/PPlQ7sXTKEj4R2Ew9AKGyWmCzyWQ4/pK 5WiOdZ3M9CmVSrlChT6gjYxBa8dJf6VJ7OTyUHtTIdQ68yA2Sw7cNS6DncYEgtxoOcK4OR9Y xcCatw1e0yguwM7Pq25aACWt7fmC36qMidTRuJDwP+SYqwOiTIrav6mxXAgSJAj0uTx9lQCD J0HlRDRw/+/apIWCHKiXCUFJ0OU/WxiyyBoLYNQiq8nzQnNsEUAPjzDb+FvZGFe/pk9CV6UP XRqGz84Slub3sLI5g+h2axX/jMIxowFl7Qd7D6l5tmEPGHJOuTjs5jevis+YMJzpqRwNdemO c6arNbFmSSZSpDMswqDWSr8FvxAm9EWLjgLJZsA0WwjJ8ECvpJMrEQrUcJrbYd1M/F5mK27Z m9FN3sKyisIS46L3DoDm/qxnbzAmUKZdJ0kdgcPsJBDnsc1WSlrZCgTv+mmC5WQkHWLADtuQ k9b/UFX6QQMm5UlNPji+5bNRYRQxiR+puItFDPMEoh0+lD7TGCPnFW+T++u2b/Mv0oa3Lfn1 d8VXwR6AE5WyrNNl0cmH7pwLrEZoo/AtjLbPVO/pm/mz/GqYUVA0cCBPUOtF5LL7CCvN09Us W1RX4JEz2vTUIgfgxYsIrh+v01CecivMgP34zhur2yIN7yoDIazwFI0sXsNRyGrCsdMTeZ8v wCOMNWAS4isrIT5Np5SRG5J5ZDbrE1Wwh0F28GRw51BLcpA+XgJACgJpi+S7oLadQ== IronPort-Data: A9a23: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 IronPort-HdrOrdr: A9a23:NPmZKqnSZnl17a772rO5fx+eCQjpDfIT3DAbv31ZSRFFG/Fw9v re/sjzsCWf5Qr5N0tApTntAsW9qBDnhP1ICOsqXYtKNTOO0ACVxepZg7cKrQeOJwTOssZjkY 1gf6J9BNCYNykese/KpC+iHZIFyNmDmZrY4ts2Ik0dKT1XVw== X-Talos-CUID: 9a23:PPUBVGFY+cCaicB3qmJM62kSHuwhfUbYzVGXIh6zDD90EZmKHAo= X-Talos-MUID: 9a23:Sv1oHwsWqZzN/cB7ls2nvThZPeFm+qeXU2MVzbpX6/SUGDZuJGLI X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.27,181,1787004000"; d="asc'?scan'208";a="160967180" X-URL-ContentFilter: X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown X-MGA-submission: =?us-ascii?q?MDGku8MtNjuIlB7xmiYlsZjgeM5Bk3GQq9eKxv?= =?us-ascii?q?hdPJ7bgB9CBPVhfYcIiZtTqVK44ECXy814lKPcN066MW4O5rx3vGKaGV?= =?us-ascii?q?RPxesTUfiOOyxw3CpFdkl0tL67GMmrzOuUiKcFqRV/PXVVk+fuHnOVFu?= =?us-ascii?q?MEyMOPNycJeu3BCfrTfU8SDA=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2026 11:29:19 +0100 Received: from mac-03220211.irisa.fr (mac-03220211.irisa.fr [131.254.21.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ssl.polytechnique.org (Postfix) with ESMTPSA id E033E1A4D8 for ; Tue, 27 Oct 2026 11:29:18 +0100 (CET) From: Alan Schmitt To: caml-list@inria.fr Date: Tue, 27 Oct 2026 11:29:17 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Oct 27 11:29:19 2026 +0100 (CET)) X-Spam-Flag: Unsure, tests=bogofilter, spamicity=0.477042, queueID=10D841A4DC X-Org-Mail: alan.schmitt.1995@polytechnique.org Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News Reply-To: Alan Schmitt X-Loop: caml-list@inria.fr X-Sequence: 19599 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Here is the latest OCaml Weekly News, for the week of October 20 to 27, 2026. (Due to its large size, this week's CWN is only sent in text format.) Table of Contents =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 uniker.nl - Unikernels in OCaml Announcing segmap, a fast data structure for renamings hexen.0.1 intel_hex.1.0 Js_of_ocaml / Wasm_of_ocaml 6.5 TIFF Inspector: an ocaml-tiff based inspector, with an in-browser OCaml pla= yground OCaml 5.5.2 released bytream.0.4 First release of spvec ocaml-emcc: compile OCaml programs with their C stubs to WebAssembly New release of snkv-ocaml 0.3.0 =E2=80=94 OCaml bindings for SNKV with HNSW= vector search Building TIFF Inspector: Exploring OCaml, TIFF Internals, and an In-Browser= Playground stele 0.1.0: syntax-error messages for Menhir grammars OSEC-2026-21: Str partial-match stale capture registers underflow OSEC-2026-22: Integer overflow in Unix.map_file OSEC-2026-23: Multiple issues in Marshal OSEC-2026-24: Multiple issues in command quoting on Windows OSEC-2026-25: Heap buffer overflow in the OCaml `runtime_events' consumer w= hen parsing an oversized custom user event OSEC-2026-26: runtime_events user event name-based type confusion Old CWN uniker.nl - Unikernels in OCaml =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Calascibetta Romain announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80 We are delighted to announce the launch of our new website: [uniker.nl]. This website embodies our new approach to developing unikernels with OCaml 5. It offers a new way of developing unikernels and now places just as much emphasis on the deployment and use of unikernels. The website features a comprehensive [tutorial] and resources to help you get to grips with our new ecosystem, providing a _first entry point_ for anyone interested in unikernels in OCaml. The content of this site is available [here], is powered by the excellent [YOCaml] project, and is deployed using our [immuable] unikernel. [uniker.nl] [tutorial] [here] [YOCaml] [immuable] Our new ecosystem =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C We were able to present our new workflow at the [OCaml Workshop 2026] ([slides]) and our approach can be summarised in two main points: =E2=80=A2 the development of unikernels =E2=80=A2 the deployment of unikernels and their uses [OCaml Workshop 2026] [slides] =E2=97=8A To develop unikernels Our co-operative has been developing unikernels for quite a few years now. [Our blog] showcases some of the ones we use for our infrastructure. Based on our experience, we are well aware of the constraints and limitations of what we can achieve when it comes to developing an application in the form of a unikernel. The best-known constraint we have accepted is not to require the POSIX interface (nor to attempt to replicate it) in terms of protocols and formats. One of the rules still adhered to today is, amongst other things, [not to depend on I/O or a scheduler][1] when providing implementations. Building on this experience, we have been able to develop protocols and formats that are currently being used by others in contexts other than unikernels. However, we have also seen the limits of what we can achieve, particularly with what MirageOS currently offers. With this in mind, and upon further reflection on the constraints we face when developing unikernels (particularly regarding cross-compilation), we have decided to structure the development of unikernels using two tools: [~unic~](how to infer dependencies and _vendor_ them) and [~mfetch~](how to vendor dependencies). [Our blog] [not to depend on I/O or a scheduler] [1] =E2=97=8A [`unic']: how to infer dependencies and _vendor_ them One constraint we face with unikernels is the need to recompile C files with specific options so that they do not depend on what already exists on the host system. The approach taken by MirageOS 3 was to distribute the result of this specific compilation within libraries that contain C stubs (such as [`digestif'] or [`mirage-crypto']). The problem is that we were forcing users of these libraries to install [`ocaml-solo5'] in order to obtain a compilation environment for C files specific to [Solo5], our core component for producing unikernels. MirageOS 4 then arrived with `dune' and its contexts, allowing us to achieve a consistent compilation environment for C files. However, this approach introduced new a constraint: all dependencies of our unikernels had to use `dune', which is *legitimately* not the case in the OCaml ecosystem. It is for this reason that we decided to refine the need to recompile some of our libraries a little further and, finally, to be able to capitalise on a key advantage of [`ocaml-solo5'], namely that compiling OCaml files with this compiler produces exactly the same result as if you were using your host OCaml compiler: in other words, and as has been the case from the beginning, we strictly only need to cross-compile the C files. It is therefore at the intersection of these two features (only needing to cross-compile the C files and being able to reuse libraries written in pure OCaml and compiled with the host compiler) that we can offer users the ability to write this sort of code without involving any maintenance work on libraries that do not use `dune' and without necessarily having to recompile everything: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ opam install unic =E2=94=82 $ cat >main.ml< open Digestif =E2=94=82=20 =E2=94=82 > let () =3D Mkernel.run [] @@ fun () -> =E2=94=82 > Fmt.pr "%a\n%!" SHA1.pp (SHA1.digest_string "Hello World!") =E2=94=82 > EOF =E2=94=82 $ unic infer -r . =E2=94=82 Module Digestif is provided by several ocamlfind packages: =E2=94=82 [0] digestif.c =E2=94=82 [1] digestif.ocaml =E2=94=82 Pick one [0-1]: 0 =E2=94=82 digestif =E2=94=82 mkernel =E2=94=82 $ opam source digestif =E2=94=82 $ opam source mkernel =E2=94=82 $ dune build =E2=94=82 $ solo5-hvt -- _build/solo5/main.exe --solo5:quiet =E2=94=82 2ef7bde608ce5404e97d5f042f95f89f1c232871Solo5 =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 `unic' is therefore a tool capable of inferring the dependencies of an OCaml project without using a specific build system, and of calculating what needs to be cross-compiled (in this case `digestif' and `mkernel' but not `fmt') to produce a unikernel. The project serves our purpose first and foremost, but it is worth noting that it can also be useful when compiling statically linked executables. This tool offers a whole range of sub-tools for analysing META files, viewing an artefact from different perspectives (its module name, its `ocamlfind' package name and its OPAM package name) or analysing OCaml artefacts (such as `*.cmxa' files). We would particularly like to thank @Octachron for his [`codept'] project (on which `unic' is based) and for working with us to improve it. [`unic'] [`digestif'] [`mirage-crypto'] [`ocaml-solo5'] [Solo5] [`codept'] =E2=97=8A [`mfetch']: how to vendor dependencies Having identified more precisely which dependencies need to be cross-compiled, we now need to download these dependencies. Although `opam source' does the job very well, we wanted a tool that could download the source code from various types of source, such as: =E2=80=A2 from a _tarball_, as is usually the case =E2=80=A2 but also from a Git repository =E2=80=A2 or even from a specific location on your file system That is why we developed `mfetch', which allows you to download software sources based on information provided by OPAM or the user, and to create a `vendors' folder containing all these sources. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ unic infer -r . -o _mfetch =E2=94=82 $ mfetch --with-dune-file =E2=94=82 digestif =E2=94=82=E2=96=88=E2=96=88=E2=96=88= =E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2= =96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82 3.= 1 MiB / 3.1 MiB 5.9 MiB/s=20 =E2=94=82 mkernel =E2=94=82=E2=96=88=E2=96=88=E2=96=88= =E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2= =96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82 37.= 3 KiB / 37.3 KiB 3.4 MiB/s=20 =E2=94=82=20 =E2=94=82 digestif ok =E2=94=82 mkernel ok =E2=94=82 $ dune build =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 `mfetch' also allows you to check whether you have modified any of the source files (for a bug fix) or to generate a `*.locked' file so that you can then verify the reproducibility of your unikernel using our other tool [`orb']. The tool itself is not revolutionary, but it helps to streamline the workflow. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ mfetch status =E2=94=82 digestif ok =E2=94=82 mkernel ok =E2=94=82 $ mfetch lock =E2=94=82 2 sources locked into _mfetch.locked =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 [`mfetch'] [`orb'] =E2=97=8A Libraries for OCaml 5 Our new workflow now uses OCaml 5. As well as updating the basic building blocks required to produce unikernels with OCaml 5, we have also developed a series of libraries that primarily enable us to take advantage of effects. Furthermore, over the past several years we have developed: =E2=80=A2 [Miou], our scheduler for OCaml 5 =E2=80=A2 [`mkernel'], a derivative of our Miou scheduler designed to han= dle the I/O provided by Solo5 =E2=80=A2 [`mnet'], a reimplementation of the TCP/IP stack (using [`utcp'= ]) in OCaml with effects =E2=80=A2 and plenty of other libraries such as [`mhttp'], [`msendmail'], [`mfat'], [`vifu'], etc. These libraries, currently used by some of our deployed unikernels, allow us to offer developers a _direct-style_ approach to implementing their unikernels. But what is key to take away from this emerging ecosystem is the retrospective analysis of past projects to ensure we do not repeat the same mistakes. We very quickly realised that it could be very difficult to migrate existing libraries using [`lwt'] (the MirageOS scheduler) to Miou (or any other scheduler using effects). We therefore took the opportunity not only to propose a _direct-style_ approach using Miou, but also to rethink the implementation of our libraries in light of what we've learnt from deploying unikernels with MirageOS. We have paid particular attention to memory usage, to avoiding known CVEs from our previous implementations (as we are also part of the OCaml security team), and also to offering an alternative API that does not systematically rely on functors. The approach is still experimental, as we need to consolidate this new ecosystem across several layers, but we are firmly convinced (based on what we've observed in our deployed unikernels) that these new implementations are significantly better than what we used in the past. [Miou] [`mkernel'] [`mnet'] [`utcp'] [`mhttp'] [`msendmail'] [`mfat'] [`vifu'] [`lwt'] =E2=97=8A To deploy unikernels The other side of unikernels is deployment. Indeed, it is not just a matter of developing unikernels (and making their development easier) but also of deploying and using them. Our main objective remains to replace existing services with unikernels (name servers, websites, time servers, etc.), and the way to compete with existing infrastructure is to actively deploy and use our unikernels. That is why we have developed two projects: =E2=80=A2 [Albatross], an OCaml service for launching unikernels =E2=80=A2 [Aussi], an OCI runtime for Solo5 We mainly use Albatross in conjunction with our infrastructure for verifying the reproducibility of our unikernels: [builds.robur.coop]. In this way, we can trace the dependencies of the unikernels - particularly their CVEs - and ensure supply-chain security. Next comes deployment, and we are therefore seeking to integrate our unikernels into existing infrastructure and provide ways of monitoring them, in particular using [InfluxDB], [Telegraf] and [Grafana]. This is how we are able to offer services such as (note that some haven't yet been ported to `mkernel~/~mnet', but will be soon): =E2=80=A2 simple websites such as our (using [`unipi'] or [`immuable']) =E2=80=A2 domain name management for domains such as `robur.coop', `reyn.= ir' or `din.osau.re' (via our [primary] DNS server and [secondary] server) =E2=80=A2 a VPN service, whether using [MirageVPN] or [Zostera] =E2=80=A2 a time server (using [Chaos]): =E2=80=A2 a [CalDAV] calendar system =E2=80=A2 [a mailing list] using the [`ptt'] project =E2=80=A2 a TLS termination proxy such as [`tlstunnel'] or [`contruno'] (= used by sherlocode.com) =E2=80=A2 and many more! It is therefore through actual use that we improve our unikernels and the libraries that depend on them. That is why part of our tutorial also focuses on deploying unikernels, so that you can use them and help us with your feedback. Finally, we are also proposing a project called [Mollymawk], designed to simplify the deployment of unikernels via a web interface, so that, in future, we can offer access to our infrastructure to anyone who wishes to use it (and we would like to thank @kit-ty-kate for their various attempts). [Albatross] [Aussi] [builds.robur.coop] [InfluxDB] [Telegraf] [Grafana] [`unipi'] [`immuable'] [primary] [secondary] [MirageVPN] [Zostera] [Chaos] [CalDAV] [a mailing list] [`ptt'] [`tlstunnel'] [`contruno'] [Mollymawk] About us =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Finally, none of this would be possible without our co-operative and the way we organise our work. You can view the details of our finances [here]. We accept donations and have recently secured funding from NLnet. Private companies such as [Ahrefs] and [Tarides] also sponsor our work. We also have partnerships with [OCamlPro] and the [OCaml Foundation]. And we contribute to the OCaml ecosystem on a daily basis by working with individuals and companies. You can find more details on [our website]. We would like to emphasise that it is thanks to our structure (that of an association) that we are able to carry out this work, and we would like to thank our sponsors. [here] [Ahrefs] [Tarides] [OCamlPro] [OCaml Foundation] [our website] Unikernels and MirageOS =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Enthusiasts may wonder what the advantage of our approach is compared to MirageOS, a unikernel project that remains active thanks to our maintenance work. Our approach is characterised by five points that we have identified as glass ceilings to the adoption of unikernels: =E2=80=A2 the first concerns the use of [`ocaml-cstruct']. The fundamental issue remains the use of `bigarray' as _buffer_ instead of `bytes~/~string'. Our experience whilst developing [MirageVPN] has shown us that using `cstruct' as a systematic library for the _buffer_ concept across our entire ecosystem was our biggest *penalty* in terms of throughput for our unikernel. This is why we decided not only to develop [`bstr'] and [`slice'], but also to rewrite the majority of our libraries by replacing `cstruct' with `bytes~/~string' (this was the case for [`ocaml-tls'], [`mirage-crypto'], [`ocaml-dns'] and, more recently, [`awa-ssh'] and [`utcp']). The conclusion is quite simple: it is not a question of stopping using bigarray, but rather of not making their use systematic in our APIs. =E2=80=A2 the second point concerns the use of functors to express the de= vices required by the unikernel. The approach of reusing interfaces to inject specific implementations that concretize these devices via functors may seem appealing, but the maintenance cost of such an ecosystem=E2=80=94constrained by interfaces that are no longer really u= p to date with new concepts=E2=80=94has led us into [absurd situations] when= ever we've needed to develop more specific unikernels tailored to our requirements. Once again, the rule is not to stop using functors, but not to make their use systematic. =E2=80=A2 the third point concerns the compilation of unikernels. MirageOS relies on a workaround that, even today, integrates very poorly with `dune'; this can be defined as: _multi-stage compilation_, where a code-generation phase is required depending on the desired _target_. This way of structuring the workflow with a set of dependencies dictated by the tool explicitly restricts the developer in what they wish to do and how they wish to do it. Although there are constraints on compiling a unikernel (such as not using the `Unix' module), our cooperative has decided to provide *informative* (and not prescriptive) tools that assist (but do not force) the user in designing their unikernel (furthermore, we are also delighted to introduce [`unic'] and [`mfetch']). The key point of our new approach is to ensure that it is the user who has the final say, rather than the tool (in this case, `mirage'), in the development of unikernels. It is very intricate on what the `mirage' tool does, including generation of functor applications and some initialization stubs, as well as opam version constraints (since the functors and initialization functions may change in new opam packages). The `mirage' tool has a closed world assumption, and it is hard to use a package not known by `mirage' - it is as well very hard to use `js_of_ocaml' in a `mirage' unikernel. =E2=80=A2 the fourth point concerns the maintenance of this ecosystem, and specifically the maintenance of the tools and libraries on which MirageOS relies. Furthermore, we have experienced some disappointments with `opam-monorepo', and we are finding, day by day, that it is becoming increasingly difficult to update `mirage-tcpip' in line with OCaml 5. Our involvement in the OCaml security team has also led us to wish to deprecate certain libraries due to a lack of maintenance. We are therefore refocusing our ecosystem on what our co-operative produces and maintains. =E2=80=A2 Finally, the last point concerns our work with the community, w= hich remains unchanged despite the emergence of AI. We have observed a certain abusive use of AI to solve non-existent problems relating to unikernels, which, in our view, undermines our credibility regarding the security, maintenance and quality of our software. In this regard, we are trying to distance ourselves from those who prefer _vibe-coding_ rather than deployment. This approach is reflected in our use of the [AGPL] as our licence (whilst offering the option of dual licensing) and a [POLICY] regarding the use of AI. All of this has led us to propose MirageOS 5, which represents a fundamental departure from the factors that characterised the failure of MirageOS 4 (for which I was the release manager). It is therefore, having acknowledged this defeat (and analysed it), that we are proposing a new approach to creating and deploying unikernels: [uniker.nl]. As regards the projects associated with the MirageOS project, we will, of course, continue to maintain some of them, whilst at the same time offering more up-to-date solutions to those who use some of our libraries. We would also be delighted to help anyone wishing to migrate to our new libraries and tools; we are (as we always have been) available to assist. [`ocaml-cstruct'] [MirageVPN] [`bstr'] [`slice'] [`ocaml-tls'] [`mirage-crypto'] [`ocaml-dns'] [`awa-ssh'] [`utcp'] [absurd situations] [`unic'] [`mfetch'] [AGPL] [POLICY] [uniker.nl] Announcing segmap, a fast data structure for renamings =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Fran=C3=A7ois Pottier announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80 Hello! I am happy to announce `segmap'. This OCaml library implements *segment maps*, a purely functional data structure that represents an increasing function of the natural numbers into the natural numbers. This data structure offers efficient support for many operations, including lookup, reverse lookup, horizontal and vertical displacements, insertion at the front end, composition, meet, and join. This data structure may be useful in proof assistants, compilers, and symbolic computation systems where variables are encoded as de Bruijn indices or co-de Bruijn indices. The data structure is described in [this paper], and [the documentation of the library] is available online. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam update =E2=94=82 opam install segmap =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Happy hacking, FP. [this paper] [the documentation of the library] hexen.0.1 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90 Archive: Mikhail announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Yo! I needed to decode the hexadecimal substring, so I wrote [Hexen], yet another library for encoding and decoding hexadecimal byte sequences. The main goal of this library is to provide a flexible API for encoding and decoding substrings into any destination (bytes or buffers). [Hexen] Usage =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Hexen provides high-level functions like `encode' and `decode' for quick encoding and decoding of strings or substrings. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Hexen.encode "Hello World";; =E2=94=82 (* - : string =3D "48656c6c6f20576f726c64" *) =E2=94=82=20 =E2=94=82 Hexen.decode "48656c6c6f20576f726c64";; =E2=94=82 (* - : string =3D "Hello World" *) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Hexen.encode_substring "Hello World" 0 5;; =E2=94=82 (* - : string =3D "48656c6c6f" *) =E2=94=82=20 =E2=94=82 Hexen.decode_substring "48656c6c6f20576f726c64" 0 10;; =E2=94=82 (* - : string =3D "Hello" *) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Also, Hexen provides functions to encode and decode strings or substrings directly into existing buffers or bytes. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let buffer =3D Buffer.create 16 in =E2=94=82=20 =E2=94=82 Hexen.encode_to_buffer "Hello" buffer; =E2=94=82 Hexen.encode_substring_to_buffer "Hello World" 5 6 buffer; =E2=94=82=20 =E2=94=82 let bytes =3D Bytes.create 12 in=20 =E2=94=82 Hexen.decode_into (Buffer.contents buffer) 0 bytes 0 22; =E2=94=82 Bytes.set bytes 11 '!'; =E2=94=82=20 =E2=94=82 bytes =E2=94=82 (* - : bytes =3D Bytes.of_string "Hello World!" *) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 intel_hex.1.0 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Mikhail announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Yo! I am happy to announce the first major release of the [Intel HEX manipulation library]. Intel HEX format is commonly used to represent compiled program code and data that is loaded into a microcontroller, flash memory, or ROM in embedded systems programming. And now you can work with it in pure OCaml! [Intel HEX manipulation library] Changes =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 Redesign API; =E2=80=A2 Added `Memory' module to process memory images of your firmware= s; =E2=80=A2 Instead of using the `ohex' package, we start use [hexen] for encoding and decoding hexadecimals; [hexen] In use =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C The library provides a simple API for parsing and creating Intel HEX files. To create an Intel HEX file, you can use the following code: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Intel_hex.Record. =E2=94=82 [ =E2=94=82 Extended_linear_address 0x0F; =E2=94=82 Data (0x0000, "Hello "); =E2=94=82 Data (0x0007, "World!"); =E2=94=82 End_of_file; =E2=94=82 ] =E2=94=82 |> Intel_hex.Object.to_string =E2=94=82 |> print_endline =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 :02000004000FEB =E2=94=82 :0600000048656C6C6F20E6 =E2=94=82 :06000700576F726C6421CA =E2=94=82 :00000001FF =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 And to parse a string containing an Intel HEX file: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 ":0600000048656C6C6F20E6\n:06000700576F726C6421CA" =E2=94=82 |> Intel_hex.Object.of_string =E2=94=82 (* - : Intel_hex.Object.t =3D =E2=94=82 [ Intel_hex.Record.Data (0, "Hello ");=20 =E2=94=82 Intel_hex.Record.Data (7, "World!") ] *) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 However, the library also provides a module for working with memory images built from Intel HEX files or other sources. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Intel_hex.Memory.of_string ~block_size:6 "Hello World!" =E2=94=82 (* - : Intel_hex.Memory.t =3D =E2=94=82 [ Intel_hex.Memory.Segment(0x0000, "Hello "); =E2=94=82 Intel_hex.Memory.Segment(0x0006, "World!") ] *) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 For more details, see the [API reference]. [API reference] Js_of_ocaml / Wasm_of_ocaml 6.5 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Hhugo announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm pleased to announce the joint release of js_of_ocaml and wasm_of_ocaml 6.5.0, compilers from OCaml bytecode to JavaScript and WebAssembly. This release brings together more than 130 pull requests (about 400 commits) from 7 contributors since 6.4.0. Highlights: =E2=80=A2 *OCaml 5.6* support. =E2=80=A2 *OxCaml*: improved support. =E2=80=A2 *Introcaml*: experimental support for [Introcaml] (OCaml values shown in OCaml syntax in Chrome DevTools). =E2=80=A2 *Faster compilation*: about 25=E2=80=9330% faster on large prog= rams. =E2=80=A2 *Smaller output*: binary constants are emitted as base64 and the generated JavaScript is tighter (the toplevel example goes from 13.6 MB to 9.0 MB). =E2=80=A2 *wasm_of_ocaml*: BLAKE2 and zstd (`Digest.BLAKE2*', compressed marshaled values) no longer require multi-memory support, so they work in Safari; plus faster runtime primitives and better sourcemaps. =E2=80=A2 *Effects*: better code with `--effects=3Dcps' and `--effects=3Ddouble-translation' =E2=80=A2 *New web API bindings*: WebGL2, Web Crypto, Service Workers, Clipboard, Notification, FontFace, and more. The toplevel can run in a Web Worker. =E2=80=A2 Many bug fixes =E2=80=A6 Breaking changes: `js_of_ocaml-lwt.logger' is removed (`lwt_log' is deprecated), the `Typed_array.float{32,64}Array_fromArray' signatures changed. Contributors to this release: Vincent Balat, Fr=C3=A9d=C3=A9ric Bour, Shon Feder, habakan, Hugo Heuzard, Robin Ricard and J=C3=A9r=C3=B4me Vouillon.= Thank you all! See the [documentation] and the [full changelog]. Please report any issue on [GitHub]. It should soon be avaible on opam () [Introcaml] [documentation] [full changelog] [GitHub] TIFF Inspector: an ocaml-tiff based inspector, with an in-browser OCaml pla= yground =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Ridwan Adebosin announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hi everyone, I've been building *TIFF Inspector*, a tool for looking inside TIFF files (directories, tags, storage layout, samples and planes), built on [geocaml/ocaml-tiff]. =E2=80=A2 Live: =E2=80=A2 Code: (MIT) It comes as a CLI, an HTTP API and a web UI. Every reported value says where it came from: read from the file, a spec default, or absent. Nothing is guessed. [geocaml/ocaml-tiff] What might interest OCaml folks =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C *ocaml-tiff fixes.* Testing on unusual files turned up a few issues, which I fixed in a vendored copy: =E2=80=A2 BigTIFF entries with several small values stored inline (for ex= ample BitsPerSample=3D[8,8,8], as GDAL writes them) were unreadable. =E2=80=A2 Classic TIFF offsets of 2 GiB and above were sign-extended. =E2=80=A2 SampleFormat stored at an offset rather than inline was not rea= d. =E2=80=A2 Entry introspection, so tools can see field types and counts. *Independent test fixtures.* There are 21 small TIFFs generated by a separate Python writer that shares no code with the parser, plus golden outputs. They might be useful to ocaml-tiff as a conformance set, if the maintainers want them. *An in-browser playground.* At `/playground' you can write OCaml and run it against ocaml-tiff and the inspector core on sample files, with no install. It's the toplevel compiled with js_of_ocaml (about 1.3 MB gzipped), running in a web worker. `;;' is optional, and compile errors are underlined in the editor. To get there I wrote JavaScript implementations of the C primitives used by `bstr' and `checkseum'. I'd be glad to offer them upstream if that's useful. *The server.* It uses OCaml 5 with Eio and cohttp-eio. Each upload is inspected in a separate process with time and memory limits, with rate limiting and graceful shutdown. It runs in Docker on a free Render instance. Feedback welcome =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 Does the JSON report shape work for other geospatial tooling? =E2=80=A2 geocaml maintainers: would you prefer the fixes as one PR or se= veral small ones? =E2=80=A2 Any TIFFs that inspect wrongly. Issues with a sample file are g= old. Thanks for reading! OCaml 5.5.2 released =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90 Archive: octachron announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80 We have the pleasure of celebrating the anniversary of the first powered flight in Europe by announcing the release of OCaml 5.5.2. OCaml 5.5.2 fixes various minor security issues, two rare miscompilations, a configuration issue with future versions of macOS, and one runtime events library issue. Overall, if you were already using any versions of OCaml 5.5, we are advising you to switch to OCaml 5.5.2 . The full list of bug fixes is available below for more details. Happy hacking, =E2=80=93 Florian Angeletti, for the OCaml team. Installation Instructions =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C The base compiler can be installed as an opam switch with the following commands: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam update =E2=94=82 opam switch create 5.5.2 =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 The source code for the release is also directly available on: =E2=80=A2 GitHub: =E2=80=A2 Inria archive: Bug Fixes =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C =E2=80=A2 [#15045]: Atomic loads whose results are unused should not be removed during dead-code elimination. (Xavier Clerc, review by Steven Dolan and KC Sivaramakrishnan) =E2=80=A2 [#15067], [#15071]: Fix detection of functions available in the future on macOS. (Antonin D=C3=A9cimo, review by Nicol=C3=A1s Ojeda B= =C3=A4r and Damien Doligez) =E2=80=A2 [#15112], OSEC-2026-22: `Unix.map_file': protect against overfl= ow when computing the data size. (Xavier Leroy and Nicol=C3=A1s Ojeda B= =C3=A4r, review by Nicol=C3=A1s Ojeda B=C3=A4r and Edwin T=C3=B6r=C3=B6k) =E2=80=A2 [#15113], OSEC-2026-21: `Str.string_partial_match': make sure captured groups are valid. (Xavier Leroy, review by Nicol=C3=A1s Ojeda B=C3=A4r and Edwin T=C3=B6r=C3=B6k) =E2=80=A2 [#15115], OSEC-2026-23: Fix multiple issues in demarshaling (`Marshal.from_{channel,string,bytes}') (Xavier Leroy, review by Nicol=C3=A1s Ojeda B=C3=A4r) =E2=80=A2 [#15133], OSEC 2026-24: Multiple issues in command quoting on Windows (Xavier Leroy and Nicol=C3=A1s Ojeda B=C3=A4r, review by Nicol= =C3=A1s Ojeda B=C3=A4r) =E2=80=A2 [#15119], OSEC-2026-25: Harden decoding of runtime events messa= ges from ring buffers. (Sadiq Jaffer, report by Hannes Mehnert, review by Olivier Nicole and Edwin T=C3=B6r=C3=B6k) =E2=80=A2 [#15177], OSEC-2026-26: Maintain custom events cache integrity. (Sadiq Jaffer, report by Hannes Mehnert, review by Edwin T=C3=B6r=C3=B6= k) =E2=80=A2 [#15043], [#15076]: runtime events library, fix an infinite loop when a user event is larger than half the ring buffer. (Tim McGilchrist, review by Sadiq Jaffer) =E2=80=A2 [#15185], [#15187]: fix a pattern-matching miscompilation on ce= rtain combinations of immediate ranges and redundant patterns (Gabriel Scherer, report by Alperer Kele=C5=9F, review by Vincent Laviron and Florian Angeletti) [#15045] [#15067] [#15071] [#15112] [#15113] [#15115] [#15133] [#15119] [#15177] [#15043] [#15076] [#15185] [#15187] bytream.0.4 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: Mikhail announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Yo! I am happy to announce the next version of the [Bytream] library, which allows streaming bytes and processing them with low memory allocation. This release includes many important updates. [Bytream] Changes =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 Now, `Bytream' for slices uses the [Slice] library from the [Bs= tr] project instead of its own `~buffer, ~offset, ~length' labeled tuples, which require OCaml version 5.2 or higher; =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let of_channel ?(io_buffer_size =3D 4096) ic =3D =E2=94=82 let buffer =3D Bstr.create io_buffer_size in =E2=94=82=20 =E2=94=82 let reader () =3D =E2=94=82 match In_channel.input_bigarray ic buffer 0 io_buffer_siz= e with =E2=94=82 | 0 -> raise End_of_file =E2=94=82 | len -> Slice_bstr.make ~len buffer =E2=94=82 in =E2=94=82=20 =E2=94=82 make reader =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=80=A2 Added `bytream.ozstd' for Zstandard compression and decompressi= on via the [ozstd] library; =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let output_compressed_string out_stream =3D=20 =E2=94=82 let out_stream =3D Bytream_ozstd.Out.make ~compression_leve= l:3 out_stream in=20 =E2=94=82 Bytream.Out.output_string out_stream "Cras pulvinar sollici= tudin nulla quis tempor."; =E2=94=82 Bytream.Out.flush out_stream =E2=94=82=20 =E2=94=82 let input_decompressed_line in_stream =3D=20 =E2=94=82 let in_stream =3D Bytream_ozstd.In.make in_stream in=20 =E2=94=82 Bytream.In.input_line in_stream =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=80=A2 Added `bytream.bin' for declarative encoding and decoding bytes= via the [Bin] library; =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 type point =3D { x : int; y : int } =E2=94=82=20 =E2=94=82 let point =3D=20 =E2=94=82 let open Bin in=20 =E2=94=82 record (fun x y -> { x; y }) =E2=94=82 |+ field neint16 (fun t -> t.x) =E2=94=82 |+ field neint16 (fun t -> t.y) =E2=94=82 |> sealr =E2=94=82=20 =E2=94=82 let _ =3D=20 =E2=94=82 (* ... *) =E2=94=82 let p =3D Bytream_bin.In.input in_stream point in=20 =E2=94=82 Bytream_bin.Out.output out_stream point { p with y =3D p.y = * 2 } =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 [Slice] [Bstr] [ozstd] [Bin] Credits =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C I would like to express my special gratitude to [Robur Coop] for their libraries ([Bstr], [Slice], [Bin], etc.), which are very closely integrated into my projects such as [Bytream], [ozstd] and other. Thanks! [Robur Coop] [Bstr] [Slice] [Bin] [Bytream] [ozstd] First release of spvec =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Fran=C3=A7ois Pottier announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80 I am pleased to announce the first release of `spvec'. This small OCaml library implements /semi-persistent vectors/. In other words, it offers vectors that support just two operations, namely `push' and `get', and that appear to be persistent (immutable), but must be used according to a restricted discipline. Thanks to this restriction, an efficient implementation, based on a mutable vector, is possible. One might say that this library offers mutable vectors disguised as persistent vectors, with a simple and safe API. Two submodules are offered, `Spvec.Safe' and `Spvec.Unsafe'. The /safe/ variant detects misuses of the library at runtime. The /unsafe/ variant is faster, but does not detect misuses; it should be used only if and when the user's code is believed to be correct. For more details, see the [documentation]. =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam update =E2=94=82 opam install spvec =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Happy hacking, FP. [documentation] ocaml-emcc: compile OCaml programs with their C stubs to WebAssembly =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90 Archive: rboud announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hi everyone, I've been working on a tool called ocaml-emcc, and it's now in a state where other people could try it: The idea is pretty simple. Instead of compiling OCaml to JS or wasm, I compile `ocamlrun' with emscripten, compile all the C stubs of the program and its dependencies with emcc, and link the whole thing into one module. Nothing has to be rewritten in JavaScript. zarith, sqlite3, camlzip, cryptokit, mirage-crypto, ctypes bindings and so on "just" work, and so does your own C. The obvious downside is that it's bytecode running in an interpreter, so it's a lot slower than js_of_ocaml or wasm_of_ocaml. If your code is pure OCaml or its C stubs already have JavaScript implementations, use those instead. This is for the cases where the FFI part is the problem. Give it a shot! =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam pin add ocaml-emcc git+https://github.com/rboudrouss/ocaml= -emcc.git =E2=94=82 source /path/to/emsdk/emsdk_env.sh # emcc in PATH (you need to= install emscripten) =E2=94=82 ocaml-emcc build main.js # in your dune project =E2=94=82 node main.js # or load main.js in a web page =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 The extension of the output decides what you get (see the README and emscripten's documentation for more flags): =E2=80=A2 `main.js': node and browsers =E2=80=A2 `main.html': the same, plus a minimal page =E2=80=A2 `main.wasm': a standalone module, which still imports a few emscripten functions =E2=80=A2 `main.wasm --wasi': imports only WASI functions, so it runs on wasmtime or node's WASI It's still a prototype, so there are rough edges, if you try it on something and it breaks, I'd really like to hear about it. Packages that don't build are exactly what I'm looking for right now. Feel free to propose/ask for new recipes too. This started as an attempt to compile [MOPSA], a static analyzer written in OCaml, to wasm. It turned out to be really hard because of how much FFI it relies on (apron, gmp, clang's frontend=E2=80=A6). I eventually got it [working] by patching both OCaml and MOPSA's sources, and gave a talk about it at the [OCaml Workshop 2026]. Since then I've been turning that work into a general tool, and it turns out to generalize quite well, so here it is. I'm curious to hear what people would use it for, especially if you have an OCaml project that never made it to the browser because of its C dependencies. [MOPSA] [working] [OCaml Workshop 2026] New release of snkv-ocaml 0.3.0 =E2=80=94 OCaml bindings for SNKV with HNSW= vector search =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Tomasz Bara=C5=84ski announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hi, everyone! I=E2=80=99m happy to announce snkv-ocaml 0.3.0, OCaml bindings for SNKV, a persistent, ACID key-value store built on SQLite=E2=80=99s B-tree engine.= SNKV provides key-value storage, column families, TTL, authenticated encryption, transactions, iterators, and runtime statistics. snkv-ocaml 0.3.0 is available in opam. This release corresponds to upstream SNKV v0.8.2, and supports HNSW-based vector search over vectors stored in the same database. Links: =E2=80=A2 Repository: =E2=80=A2 OPAM: =E2=80=A2 Changelog: =E2=80=A2 Upstream SNKV: Building TIFF Inspector: Exploring OCaml, TIFF Internals, and an In-Browser= Playground =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: RidwanAdebsoin announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hi everyone! I've been building *TIFF Inspector*, a tool for looking inside TIFF files (directories, tags, storage layout, samples and planes), built on [geocaml/ocaml-tiff]. =E2=80=A2 *Live:* [TIFF Inspector] =E2=80=A2 *Code:* [GitHub repository] (MIT) It comes as a CLI, an HTTP API and a web UI. Every reported value says where it came from: read from the file, a spec default, or absent. Nothing is guessed. [geocaml/ocaml-tiff] [TIFF Inspector] [GitHub repository] What might interest OCaml folks =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C *ocaml-tiff fixes.* Testing on unusual files turned up a few issues, which I fixed in a vendored copy: =E2=80=A2 BigTIFF entries with several small values stored inline (for example, `BitsPerSample=3D[8,8,8]', as GDAL writes them) were unreadable. =E2=80=A2 Classic TIFF offsets of 2 GiB and above were sign-extended. =E2=80=A2 `SampleFormat' stored at an offset rather than inline was not r= ead. =E2=80=A2 Entry introspection, so tools can see field types and counts. *Independent test fixtures.* There are 21 small TIFFs generated by a separate Python writer that shares no code with the parser, plus golden outputs. They might be useful to `ocaml-tiff' as a conformance set, if the maintainers want them. *An in-browser playground.* At `/playground', you can write OCaml and run it against `ocaml-tiff' and the inspector core on sample files, with no install. It's the toplevel compiled with `js_of_ocaml' (about 1.3 MB gzipped), running in a web worker. `;;' is optional, and compile errors are underlined in the editor. To get there, I wrote JavaScript implementations of the C primitives used by `bstr' and `checkseum'. I'd be glad to offer them upstream if that's useful. *The server.* It uses OCaml 5 with Eio and cohttp-eio. Each upload is inspected in a separate process with time and memory limits, with rate limiting and graceful shutdown. It runs in Docker on a free Render instance. Feedback welcome =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 Does the JSON report shape work for other geospatial tooling? =E2=80=A2 `geocaml' maintainers: would you prefer the fixes as one PR or several small ones? =E2=80=A2 Any TIFFs that inspect incorrectly? Issues with a sample file a= re gold. Thanks for reading! stele 0.1.0: syntax-error messages for Menhir grammars =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: J=C3=A9r=C3=B4me Vouillon announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm happy to announce the first release of [stele], a tool that writes the syntax-error messages of a Menhir grammar for you. A Menhir parser that meets bad input raises `Error', which says where the parse failed but not why. Menhir can show a real message instead, but only if you write one for every error state (every point where the parse can get stuck). A realistic grammar has hundreds of them, and they go stale as the grammar changes. stele generates them at build time, from `menhir --list-errors' and the grammar's `.cmly'. With a few aliases and one `%on_error_reduce' annotation, the calculator from the tutorial reports: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Error: Assuming that the statements are complete, expecting '}'. =E2=94=82 --> stray.calc:1:6 =E2=94=82 1 | { 1; ) } =E2=94=82 =C2=B7 ^ =E2=94=82 =C2=B7 ^^ these statements =E2=94=82 =C2=B7 ^ This '{' opens the enclosing construct. =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 What you get: =E2=80=A2 *A message for every error state*, saying what could come next.= Each list is checked against the parser's tables, so a message never offers a token the parser would reject in that state. =E2=80=A2 *Location hints*: the opening delimiter the input is still insi= de, and the construct the parser assumed complete. A small runtime library, `stele.runtime', turns these into source spans when the parser fails. It depends only on `menhirLib', so it works under js_of_ocaml and wasm_of_ocaml. stele leaves the rendering to you; [Grace] works well. =E2=80=A2 *Better wording when you want it*: a small config file gives readable names and groups tokens ("an operator"), and an overrides file holds hand-written messages for the few states that need one. Stale entries in either fail the build. stele builds on Fran=C3=A7ois Pottier's [/Reachability and Error Diagnosis in LR(1) Parsers/] (CC 2016), the paper behind `--list-errors'. It automates the work the paper did by hand for CompCert's parser. It started inside the [Wax] toolchain, where it produces the error messages of both its grammars. To try it: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam install stele =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 It needs OCaml =E2=89=A5 4.14 and menhir =E2=89=A5 20260122. The [tutoria= l] takes a small calculator grammar from "Syntax error" to the full setup in ten stages. Its final state is a runnable example to copy. [stele] [Grace] [/Reachability and Error Diagnosis in LR(1) Parsers/] [Wax] [tutorial] OSEC-2026-21: Str partial-match stale capture registers underflow =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-21 =E2=94=82 modified: "2026-10-26T15:15:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity:=20 =E2=94=82 "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:= N/E:P/AU:Y/R:U" =E2=94=82 severity_score: "5.5 (Medium)" =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "824dadcbde77aea27d84b8d70a72442b8fcb344a"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "feccd4744ebe25b90208e569d03efd514b964dce"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Nicol=C3=A1s Ojeda B=C3=A4r"] =E2=94=82 [remediation_reviewer "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_developer "Xavier Leroy"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-122 ] =E2=94=82 affected_bindings: ["Str.string_partial_match" "Str.replace_mat= ched"=20 =E2=94=82 "Str.global_replace" "Str.replace_first" ] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Str partial-match stale capture registers underflow* ANT-2026-KKC4QS4S Str partial-match stale capture registers underflow `Str.string_partial_match' records the beginning and end of a captured group. There was an implicit assumption that `beginning <=3D end'. However if it reached the end of the matched string but not the end of the regexp, it was possible for the beginning of the group to be matched at iteration N of the star operator, and the end of the group to be matched at iteration N-1, resulting in `beginning > end'. `Str.matched_group' is safe, it fails with an `Invalid_argument' on groups with `beginning > end', but `Str.replace_matched' can crash, trying to memcpy `end - beginning' bytes. The example in the ANT is `ab' partially matched against `\(\(a\)b\)+'. Group 2 has `beginning =3D 2' and `end =3D 1'. Fix =E2=95=8C=E2=95=8C=E2=95=8C The fix is to record groups with `beginning > end' as not matched. Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C All of the following conditions are necessary: =E2=80=A3 you need to use `Str.string_partial_match' =E2=80=A3 if you don't use this function you are not affected =E2=80=A3 you need to use one of `Str.{replace_matched,global_replace,replace_first}' on the same regexp after a call to `Str.string_partial_match'. =E2=80=A3 If you use `Str.group_beginning' and `Str.group_end' and do y= our own string manipulation that is safe, because the String module would raise on out of bounds accesses. Similarly `Str.matched_group' is safe (uses `String' functions in its OCaml implementation) =E2=80=A3 the match replacement must reference a group > 0 =E2=80=A3 if the replacement string argument is fixed, and doesn't refe= rence any groups, or references only group 0, then you are not affected =E2=80=A3 the referenced replacement group must be under a repetition ope= rator in the original regexp =E2=80=A3 if there is no repetition operator in the regexp, or there ar= e no groups under the repetition operator then you are not affected For example `{|\(\(a\)b\)+|}' as the regular expression in a call to `Str.string_partial_match', followed by a reference to `\2' in the argument of `Str.replace_matched' could be affected. Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2026-09-29: fix merged to trunk OSEC-2026-22: Integer overflow in Unix.map_file =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-22 =E2=94=82 modified: "2026-10-23T22:30:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity:=20 =E2=94=82 "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:H/SC:N/SI:N/SA:= N/E:P" =E2=94=82 severity_score: "5.5 (Medium)" =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "de57bb4f59c3302260aaeaaa4dfee12695597d25"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "ff978d2139ba638886c2565f2d86c0ee265840a5"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Nicol=C3=A1s Ojeda B=C3=A4r"] =E2=94=82 [remediation_reviewer "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_developer "Xavier Leroy"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-190 ] =E2=94=82 affected_bindings: ["Unix.map_file"] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Integer overflow in Unix.map_file* ANT-2026-6W9NPC2Q mmap dimension product integer overflow Fix =E2=95=8C=E2=95=8C=E2=95=8C Use `caml_umul_overflow' instead of `*' when multiplying bigarray dimensions, which detects integer overflows and raise `Failure'. Negative positions are also rejected by raising `Invalid_argument'. Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If either the dimensions or the file size in a call to `Unix.map_file' from your code is user controllable then you are potentially affected. Score notes =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C The vulnerability is in a library, and the CVSS score is calculated [under worst case assumptions]. For an actual application the score will depend on how much an attacker can control the input to this function (if at all). [under worst case assumptions] Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2026-09-29: fix merged to trunk OSEC-2026-23: Multiple issues in Marshal =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-23 =E2=94=82 modified: "2026-10-23T22:30:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity: "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N" =E2=94=82 severity_score: "6.8" =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 aliases: [ CVE-2026-28364 ] =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "7da997d28b1ac57dd3a7108a865b327493fd4239"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "709b0ab93e53d54297b42d897d74dced1e9c75a5"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Nicol=C3=A1s Ojeda B=C3=A4r"] =E2=94=82 [remediation_developer "Xavier Leroy"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-126 CWE-502 CWE-754] =E2=94=82 affected_bindings: ["Marshal.from_channel" "Marshal.from_bytes"= =20 =E2=94=82 "Marshal.from_string" "input_value" ] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Multiple issues in Marshal* Several issues have been discovered in the Marshal module: ANT-2026-K7NTK0FT Stale obj_counter across unmarshal calls enables null/freed intern_obj_table indexing ANT-2026-2NJYQWEX Custom block size wraparound in CODE_CUSTOM_LEN allocation ANT-2026-PJC00M7X Unmarshaler accepts forged Closure_tag metadata without validation This is a followup for [OSEC-2026-01] Corrupted or malicious marshaled data that causes undefined behaviour in the runtime system when unmarshaled. input_value should either fail cleanly or produce a well-formed OCaml object, without corrupting the runtime system. Consequently, this excludes well-formed marshaled data that produces an OCaml object that is not of the type expected by the OCaml code and causes the Ocaml code to crash or misbehave. [OSEC-2026-01] Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If you use one of the affected bindings `Marshal.from_channel', `Marshal.from_bytes', `Marshal.from_string', `Stdlib.input_value' (or a wrapper in a library, such as `Lwt_io.read_value'). Please note that Marshal is not type safe, and you have to be careful if you use the deserialization on untrusted input (due to type confusion, and remote code execution by design - you can use Marshal for code). It is recommended to use Marshal only for communication between trusted processes. Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2026-09-29: fix merged to trunk OSEC-2026-24: Multiple issues in command quoting on Windows =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-24 =E2=94=82 modified: "2026-10-23T22:30:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity:=20 =E2=94=82 "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:= N/E:P" =E2=94=82 severity_score: "7.3 (High)" =E2=94=82 aliases : [ CVE-2026-41083 ] =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "70a3a75c0bfb23d67ad5fe3e9c1ba9800d61feae"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "0bbf8e5af985feb03a11a5ffe57d068373d09fd0"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Nicol=C3=A1s Ojeda B=C3=A4r"] =E2=94=82 [remediation_developer "Xavier Leroy"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-78 ] =E2=94=82 affected_bindings: ["Filename.quote_command" "Unix.create_proc= ess"=20 =E2=94=82 "Unix.create_process_env" "Unix.open_process_args_in"=20 =E2=94=82 "Unix.open_process_args_out" "Unix.open_process_args_full"] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Multiple issues in command quoting on Windows* ANT-2026-R7FKP7RG Win32 quote_cmd_filename misses pipe/redirect metacharacters ANT-2026-SRZZ62SD Windows batch-file argument injection via maybe_quote/make_cmdline ANT-2026-JPEWMPAB Win32 argument quoting leaves embedded CR/LF unescaped Also includes the fix for [OSEC-2026-05] `Filename.quote_command' returns a quoted command line, suitable for use as an argument to `Sys.command', `Unix.system', and the `Unix.open_process' functions. However on Windows certain characters weren't properly escaped. `Unix.create_process' can invoke `.bat' or `.cmd' programs on Windows, and certain characters were accepted that cannot be quoted safely. [OSEC-2026-05] Fix =E2=95=8C=E2=95=8C=E2=95=8C `Filename.quote_command' has been updated to correctly quote arguments. `Unix.create_process*' has been updated to reject arguments that cannot be safely quoted by raising `Failure': if the program [prog] is a [.bat] or [.cmd] script and either [prog] or [args] contain characters that cannot be securely passed to a script, such as [" | & , ; < =3D > ^ % "]. If you really need to pass these characters to a script, consider using {!Unix.system} instead. Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If you use `Filename.quote_command' on Windows with user supplied arguments. If you use `Unix.create_process*' or `Unix.open_process*' on Windows with `.bat' or `.cmd' programs, and user supplied arguments. Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2029-09-05: fix merged to trunk OSEC-2026-25: Heap buffer overflow in the OCaml `runtime_events' consumer w= hen parsing an oversized custom user event =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-25 =E2=94=82 modified: "2026-10-23T22:30:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity:=20 =E2=94=82 "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:= N/E:P" =E2=94=82 severity_score: "4.5 (Medium)" =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "2247294d06464df0273479f41b0418655918da27"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "9dcf0c86201cf5e8ece56c6bb5f61fc4d92fb74a"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Olivier Nicole"] =E2=94=82 [remediation_reviewer "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_developer "Sadiq Jaffer"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-20 CWE-122 ] =E2=94=82 affected_bindings: ["Runtime_events.read_poll" ] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Heap buffer overflow in the OCaml `runtime_events' consumer when parsing an oversized custom user event* ANT-2026-0JXJVEVY Custom events maintains a cache of user events, it is possible to have a corrupt stream that has a valid message with one message type (which can be custom/unit/span/int) and then has the same event with a different message type. This would never be encountered in a real program but can lead to a crash. Fix =E2=95=8C=E2=95=8C=E2=95=8C Check message lengths for all runtime event types, report a corrupt stream on mismatch. Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If the runtime events producer and consumer run in separate processes, and the producer can be tricked into producing malformed data. Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2027-09-05: fix merged to trunk OSEC-2026-26: runtime_events user event name-based type confusion =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Hannes Mehnert announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear everyone, a new advisory was published for the OCaml runtime. Below is the advisory, you can as well find it at and Best, Hannes =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 id: OSEC-2026-26 =E2=94=82 modified: "2026-10-23T22:30:00+01:00" =E2=94=82 published: "2026-10-23T22:30:00+01:00" =E2=94=82 severity:=20 =E2=94=82 "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:= N/E:P" =E2=94=82 severity_score: "4.5 (Medium)" =E2=94=82 affected: "ocaml" {< "5.5.2"} =E2=94=82 events: [ =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "ac2fae847a9c2c35ae3bba90a19adbe5d0cc6f59"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 [ =E2=94=82 git "https://github.com/ocaml/ocaml" [ =E2=94=82 [fixed "de10a6b03a471821cb0b868223e5331b919f48c0"] =E2=94=82 ] =E2=94=82 ] =E2=94=82 ] =E2=94=82 credits: [ =E2=94=82 [reporter "Anthropic"] =E2=94=82 [coordinator "Hannes Mehnert"] =E2=94=82 [coordinator "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_reviewer "Edwin T=C3=B6r=C3=B6k"] =E2=94=82 [remediation_developer "Sadiq Jaffer"] =E2=94=82 ] =E2=94=82 cwe: [ CWE-20 CWE-122 ] =E2=94=82 affected_bindings: ["Runtime_events.read_poll"] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *runtime_events user event name-based type confusion* ANT-2026-DTBY2HWS Custom events maintains a cache of user events, it is possible to have a corrupt stream that has a valid message with one message type (which can be custom/unit/span/int) and then has the same event with a different message type. This would never be encountered in a real program but can lead to a crash. Fix =E2=95=8C=E2=95=8C=E2=95=8C Validate event type against expected type, report a corrupt stream on mismatch. Am I affected? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If the runtime events producer and consumer run in separate processes, and the producer can be tricked into producing malformed data. Timeline =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 2026-08-24: vulnerability was found =E2=80=A2 2026-08-27: forwarded report to security@ocaml.org =E2=80=A2 2027-10-20: fix merged to trunk Old CWN =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 If you happen to miss a CWN, you can [send me a message] and I'll mail it to you, or go take a look at [the archive] or the [RSS feed of the archives]. If you also wish to receive it every week by mail, you may subscribe to the [caml-list]. [Alan Schmitt] [send me a message] [the archive] [RSS feed of the archives] [caml-list] [Alan Schmitt] --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQFvBAEBCABZFiEE6lXof/BsSVW56ZmGBA0KO07S5ccFAmrgfP0bFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMCwzHxxhbGFuLnNjaG1pdHRAcG9seXRlY2huaXF1ZS5v cmcACgkQBA0KO07S5cfzxQgAxkGkNuJGyBtceosEjOkda3YDJz7hNgc+Xz9uk1AP SMr8Oi4TQSoKxLEcHBwlTNcWsCaX5pPIoTLGmOCHa2gqR6rlZ7tTh2orLdF0HgWx 5CMnRaaNyRlQUxT8CdaObPEDh0xGdmArWdQ6+FuGuruzxtpKR5LCv3laqEmQ/mM3 bDw1DrJCEzNy4q9M8kr18GmecYKjccnH8B5pHOGbTWmt5x48stosIgR0LpMOmfxz cSLZmOafCCu7m0F7HpKIfifTnPv08ll2zVH4Ld+HR7639v1in+AxHPK8eJLhP7ku KGIBmSJjbOyt9gc8eKcGZ6CA8cG8ck11clto5M6q2ZDnmA== =vtTT -----END PGP SIGNATURE----- --=-=-=--