shithub: mc

Download patch

ref: 0b7b8cf380ced404a763a81e86db439ee4915393
parent: a61a1f51567f27ec605986354a28f8360abb1bda
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Sep 8 19:08:12 EDT 2016

Add url escaping.

--- a/lib/escfmt/bld.sub
+++ b/lib/escfmt/bld.sub
@@ -1,7 +1,8 @@
 lib escfmt =
 	escsh.myr
 	eschtml.myr
+	escurl.myr
 
 	lib ../std:std
-	lib ../sys:sys
+        lib ../sys:sys
 ;;
--- /dev/null
+++ b/lib/escfmt/escurl.myr
@@ -1,0 +1,52 @@
+use std
+
+pkg escfmt =
+	type escurl = byte[:]
+
+	const url	: (s : byte[:] -> escurl) 
+;;
+
+const __init__ = {
+	var s = ("" : escurl)
+	std.fmtinstall(std.typeof(s), urlfmt, [][:])
+}
+
+const url = {s
+	-> (s : escurl)
+}
+
+const urlfmt = {sb, ap, args
+	var s : byte[:]
+
+	s = std.vanext(ap)
+	for b in s
+		match (b : char)
+		| ':':	std.sbfmt(sb, "%{x}", b)
+		| '/':	std.sbfmt(sb, "%{x}", b)
+		| '?':	std.sbfmt(sb, "%{x}", b)
+		| '#':	std.sbfmt(sb, "%{x}", b)
+		| '[':	std.sbfmt(sb, "%{x}", b)
+		| ']':	std.sbfmt(sb, "%{x}", b)
+		| '@':	std.sbfmt(sb, "%{x}", b)
+		| '!':	std.sbfmt(sb, "%{x}", b)
+		| '$':	std.sbfmt(sb, "%{x}", b)
+		| '&':	std.sbfmt(sb, "%{x}", b)
+		| '\'':	std.sbfmt(sb, "%{x}", b)
+		| '(':	std.sbfmt(sb, "%{x}", b)
+		| ')':	std.sbfmt(sb, "%{x}", b)
+		| '*':	std.sbfmt(sb, "%{x}", b)
+		| '+':	std.sbfmt(sb, "%{x}", b)
+		| ',':	std.sbfmt(sb, "%{x}", b)
+		| ';':	std.sbfmt(sb, "%{x}", b)
+		| '=':	std.sbfmt(sb, "%{x}", b)
+		| '%':	std.sbfmt(sb, "%{x}", b)
+		| c:
+			if b >= 0x80
+				std.sbfmt(sb, "%{x}", b)
+			else
+				std.sbfmt(sb, "{}", c)
+			;;
+
+		;;
+	;;
+}
--- /dev/null
+++ b/lib/escfmt/test/escurl.myr
@@ -1,0 +1,28 @@
+use std
+use escfmt
+use testr
+
+const main = {
+	testr.run([\
+		[.name="unchanged", .fn={ctx
+			var s = std.fmt("{}", escfmt.url("word"))
+			testr.check(ctx, std.sleq("word", s), std.fmt("mismatched escape {}", s))
+			std.slfree(s)
+		}],
+		[.name="allspecials", .fn={ctx
+			var s = std.fmt("{}", escfmt.url(":/?#[]@!$&'()*+,;=%"))
+			testr.check(ctx, \
+				std.sleq("%3a%2f%3f%23%5b%5d%40%21%24%26%27%28%29%2a%2b%2c%3b%3d%25", s), \
+				std.fmt("mismatched escape {}", s))
+			std.slfree(s)
+		}],
+		[.name="unicodes", .fn={ctx
+			var s = std.fmt("{}", escfmt.url("᚛᚛ᚉᚑᚅᚔᚉᚉᚔ"))
+			testr.check(ctx, \
+				std.sleq("%e1%9a%9b%e1%9a%9b%e1%9a%89%e1%9a%91%e1%9a%85%e1%9a%94%e1%9a%89%e1%9a%89%e1%9a%94", s), \
+					std.fmt("mismatched escape {}", s))
+			std.slfree(s)
+		}],
+	][:])
+}
+