F#中字符串的编译时约束,类似于度量单位-可能吗? [英] Compile-time constraints for strings in F#, similar to Units of Measure - is it possible?
问题描述
我正在使用F#开发Web应用程序.考虑保护用户输入字符串免受SQL,XSS和其他漏洞的侵害.
I'm developing a Web application using F#. Thinking of protecting user input strings from SQL, XSS, and other vulnerabilities.
用两个词,我需要一些编译时约束,使我能够将普通字符串与表示SQL,URL,XSS,XHTML等的字符串区别开来.
In two words, I need some compile-time constraints that would allow me discriminate plain strings from those representing SQL, URL, XSS, XHTML, etc.
许多语言都有它,例如Ruby的本机字符串内插功能#{...}
.
对于F#,似乎度量单位效果很好,但是它们仅适用于数字类型.
有几种采用运行时 UoM的解决方案(链接),但是我认为这是我实现目标的开销.
Many languages have it, e.g. Ruby’s native string-interpolation feature #{...}
.
With F#, it seems that Units of Measure do very well, but they are only available for numeric types.
There are several solutions employing runtime UoM (link), however I think it's an overhead for my goal.
我研究了FSharpPowerPack,似乎很可能为字符串提出类似的东西:
I've looked into FSharpPowerPack, and it seems quite possible to come up with something similar for strings:
[<MeasureAnnotatedAbbreviation>] type string<[<Measure>] 'u> = string
// Similarly to Core.LanguagePrimitives.IntrinsicFunctions.retype
[<NoDynamicInvocation>]
let inline retype (x:'T) : 'U = (# "" x : 'U #)
let StringWithMeasure (s: string) : string<'u> = retype s
[<Measure>] type plain
let fromPlain (s: string<plain>) : string =
// of course, this one should be implemented properly
// by invalidating special characters and then assigning a proper UoM
retype s
// Supposedly populated from user input
let userName:string<plain> = StringWithMeasure "John'); DROP TABLE Users; --"
// the following line does not compile
let sql1 = sprintf "SELECT * FROM Users WHERE name='%s';" userName
// the following line compiles fine
let sql2 = sprintf "SELECT * FROM Users WHERE name='%s';" (fromPlain userName)
注意:这只是一个示例;不建议使用SqlParameter
. :-)
Note: It's just a sample; don't suggest using SqlParameter
. :-)
我的问题是:是否有一个像样的图书馆?有可能添加语法糖吗?
谢谢.
My questions are: Is there a decent library that does it? Is there any possibility to add syntax sugar?
Thanks.
更新1 :感谢Daniel,我需要编译时约束.
Update 1: I need compile-time constraints, thanks Daniel.
更新2 :我正在尝试避免任何运行时开销(元组,结构,有区别的联合等).
Update 2: I'm trying to avoid any runtime overhead (tuples, structures, discriminated unions, etc).
推荐答案
有点晚了(我确定有一种时间格式,在2月23日至11月30日之间只有一点不同),我相信这些单线与您的目标兼容:
A bit late (I'm sure there's a time format where there is only one bit different between February 23rd and November 30th), I believe these one-liners are compatible for your goal:
type string<[<Measure>] 'm> = string * int<'m>
type string<[<Measure>] 'm> = { Value : string }
type string<[<Measure>] 'm>(Value : string) = struct end
这篇关于F#中字符串的编译时约束,类似于度量单位-可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!