4 ms·
Theoretically in a strongly and statically typed language like Haskell shouldn't it be possible to fix the safe/unsafe string problem by having separate a strin
by kisielk 15y ago
Theoretically in a strongly and statically typed language like Haskell shouldn't it be possible to fix the safe/unsafe string problem by having separate a string type for unsanitized input?
Not that I've tried this approach myself, but I'd be curious to hear from anyone who has.
- raganwald 15y agoYes I have implemented something like this and I still do this from time to time. For example, I don’t always use plain strings for things like SSNs/SINs and phone numbers, sometimes I create a brand new class. You can do this in any language today by boxing strings. In an “untyped” language like Ruby, you’ll get runtime errors if you try to use an UnsafeString where you expect a String, and in a statically typed language you’ll get a compiler error. Some languages make this easier than others, but the main problem is not whether you can use types or boxes to solve the problem. The main problem is that if you are using libraries/frameworks that doesn’t support your types or boxes, you still have to be careful to place boxing and unboxing code where your code interacts with the library. Taking a web framework as an example, if its template system expects PUS (plain unsafe strings) and it provides post parameters as PUS, it’s up to you to box things up so that your code never passes PUS straight through the system. I agree that once you box up a PUS it won’t get inserted into a template, but the pain point is that library authors don’t implement anything like this so you are going to have to deal with the rather broad interface between your code and almost every library that does something with a string. Which is not to say that types are or are not better than coding conventions, but rather to say that in theory types are an airtight solution in any language, but in practice there is still broad scope for human error thanks to libraries.
- eru 15y agoYes, that's possible in Haskell. And it's actually one of the canonical examples. And even in C you could wrap your (char*)s up in different structs. The typing overhead would be higher than in Haskell, though. (There's even a language extension to allow you to overload string literals. But you probably don't want that, because s = TaintedString "My string literal" is easier to read than: s :: TaintedString s = "My string literal" The overloading makes more sense for implementation details like using a different String implementation like ByteStrings instead of a linked list of Characters. You actually want to be able to see the semantic differences.)
- masklinn 15y agoRe. second one, wouldn't it also be possible to write s = "My string literal" :: TaintedString ? It's not shorter than the constructed version but it should work, you sometimes need it to get the "right" kind of number out of a literal when the type inference gets confused (or more commonly in the REPL)
- eru 15y agoYes, that's possible with the right compiler extensions. For this example it's essentially the same thing as giving the type on its own line, so I chose the more common syntax.
- JadeNB 15y ago> Not that I've tried this approach myself, but I'd be curious to hear from anyone who has. Tom Moertel (http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem http://blog.moertel.com/articles/2006/10/18/a-type-based-sol...) has.