Skip to content

Commit 6a7f150

Browse files
committed
An implementation of the SASLprep stringprep profile.
1 parent 7ad43f2 commit 6a7f150

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

sasl/stringprep.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""SASL stringprep profile
2+
3+
<http://www.ietf.org/rfc/rfc4013.txt>
4+
<http://www.ietf.org/rfc/rfc3454.txt>
5+
6+
Copyright (C) 2012, Wim Lewis <wiml@hhhh.org>.
7+
"""
8+
9+
from __future__ import absolute_import
10+
from stringprep import *
11+
import unicodedata
12+
13+
__all__ = ( 'prepare', )
14+
15+
def prepare(s):
16+
"""Prepare a Unicode string according to the SASLprep stringprep profile.
17+
Returns the prepared string, or raises a UnicodeError on failue."""
18+
19+
# Step 1 - Map
20+
buf = u''
21+
for ch in s:
22+
if in_table_c12(ch):
23+
buf += u' '
24+
elif not in_table_b1(ch):
25+
buf += ch
26+
27+
# Step 2 - Normalize
28+
buf = unicodedata.normalize('NFKC', buf)
29+
30+
# Step 3 - Prohibited characters
31+
for ch in buf:
32+
if ( in_table_c21(ch) or
33+
in_table_c22(ch) or
34+
in_table_c3(ch) or
35+
in_table_c4(ch) or
36+
in_table_c5(ch) or
37+
in_table_c6(ch) or
38+
in_table_c7(ch) or
39+
in_table_c8(ch) or
40+
in_table_c9(ch) ):
41+
raise UnicodeError("Invalid character %r" % (ch,))
42+
43+
# Step 4 - bidi mark checking
44+
# If there are any characters in categort D1 (randAL), then do extra checks.
45+
if any(map(in_table_d1, buf)):
46+
# If there are any R+AL characters, the first and last
47+
# characters must be R+AL.
48+
if not in_table_d1(buf[0]) or not in_table_d1(buf[-1]):
49+
raise UnicodeError("bidi rejected by stringprep (6.3)")
50+
# And there must not be any L (table d2).
51+
if any(map(in_table_d2, buf)):
52+
raise UnicodeError("bidi rejected by stringprep (6.2)")
53+
54+
return buf
55+

0 commit comments

Comments
 (0)