This thread contains a patchset. You're looking at the original emails,
but you may wish to use the patch review UI.
Review patch
2
2
[PATCH 0/1] Sort bencode dicts before send
According to https://en.wikipedia.org/wiki/Bencode , dictionaries must
appear in lexicographic order. Altough it's not an issue in most
lisp-based languages, some implementations of bencode decoding will
fail (unable to decode) if they are not in lexicographic order.
This commit seems the easiest way to implement this. Maybe the
overhead could be avoidable using a defvared variable in the
condition, as an opt-out option.
Nicolas Graves (1):
Sort bencode dicts before send
arei-nrepl.el | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
--
2.45.2
[PATCH 1/1] Sort bencode dicts before send
---
arei-nrepl.el | 11 ++++++++++ -
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arei-nrepl.el b/arei-nrepl.el
index d7e37fe..6fedcda 100644
--- a/arei-nrepl.el
+++ b/arei-nrepl.el
@@ -352,13 +352,22 @@ decoded message or nil if the strings were completely decoded."
(erase-buffer)
(cons string-q response-q))))
+ (defun sort-plist-by-keys (plist)
+ "Return a new PLIST sorted by keys, keeping key-value pairs together."
+ (cl-loop with pairs = '()
+ for (key value) on plist by #'cddr
+ do (push (cons key value) pairs)
+ finally return
+ (cl-loop for (key . value) in (cl-sort pairs #'string< :key #'car)
+ append (list key value))))
+
(defun arei-nrepl-bencode (object)
"Encode OBJECT with bencode.
Integers, lists and arei-nrepl-dicts are treated according to bencode
specification. Everything else is encoded as string."
(cond
((integerp object) (format "i%de" object))
- ((arei-nrepl-dict-p object) (format "d%se" (mapconcat #'arei-nrepl-bencode (cdr object) "")))
+ ((arei-nrepl-dict-p object) (format "d%se" (mapconcat #'arei-nrepl-bencode (sort-plist-by-keys (cdr object)) "")))
((listp object) (format "l%se" (mapconcat #'arei-nrepl-bencode object "")))
(t (format "%s:%s" (string-bytes object) object))))
--
2.45.2
Re: [PATCH 1/1] Sort bencode dicts before send
On 2024-08-29 16:48, Nicolas Graves wrote:
> ---
> arei-nrepl.el | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/arei-nrepl.el b/arei-nrepl.el
> index d7e37fe..6fedcda 100644
> --- a/arei-nrepl.el
> +++ b/arei-nrepl.el
> @@ -352,13 +352,22 @@ decoded message or nil if the strings were completely decoded."
> (erase-buffer)
> (cons string-q response-q))))
>
> +(defun sort-plist-by-keys (plist)
> + "Return a new PLIST sorted by keys, keeping key-value pairs together."
> + (cl-loop with pairs = '()
> + for (key value) on plist by #'cddr
> + do (push (cons key value) pairs)
> + finally return
> + (cl-loop for (key . value) in (cl-sort pairs #'string< :key #'car)
> + append (list key value))))
> +
> (defun arei-nrepl-bencode (object)
> "Encode OBJECT with bencode.
> Integers, lists and arei-nrepl-dicts are treated according to bencode
> specification. Everything else is encoded as string."
> (cond
> ((integerp object) (format "i%de" object))
> - ((arei-nrepl-dict-p object) (format "d%se" (mapconcat #'arei-nrepl-bencode (cdr object) "")))
> + ((arei-nrepl-dict-p object) (format "d%se" (mapconcat #'arei-nrepl-bencode (sort-plist-by-keys (cdr object)) "")))
> ((listp object) (format "l%se" (mapconcat #'arei-nrepl-bencode object "")))
> (t (format "%s:%s" (string-bytes object) object))))
Hi Nicolas!
Applied, thank you!
Probably we need a similiar thing for guile's bencode implementation :)
--
Best regards,
Andrew Tropin