summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/stdlib/src/binary.erl141
-rw-r--r--lib/stdlib/src/erl_stdlib_errors.erl11
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl33
3 files changed, 84 insertions, 101 deletions
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index 4c27b1d3e6..e587cfe98d 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -365,13 +365,14 @@ get_opts_replace(_,_) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Hex encoding functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--define(HEX(X, Off), (hex(X, OffSet)):16).
-compile({inline, [hex/2]}).
-spec encode_hex(Bin) -> Bin2 when
Bin :: binary(),
Bin2 :: <<_:_*16>>.
+encode_hex(Bin) when is_binary(Bin) ->
+ encode_hex(Bin, uppercase);
encode_hex(Bin) ->
- encode_hex(Bin, uppercase).
+ error_with_info(badarg, [Bin]).
-spec encode_hex(Bin, Case) -> Bin2 when
Bin :: binary(),
@@ -384,23 +385,17 @@ encode_hex(Bin, lowercase) when is_binary(Bin) ->
encode_hex(Bin, Case) ->
error_with_info(badarg, [Bin, Case]).
--spec encode_hex1(binary(), 1 | 257) -> <<_:_*16>>.
-encode_hex1(Data, OffSet) when byte_size(Data) rem 8 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet),?HEX(D, OffSet),?HEX(E, OffSet),?HEX(F, OffSet),?HEX(G, OffSet),?HEX(H, OffSet)>> || <<A,B,C,D,E,F,G,H>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 7 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet),?HEX(D, OffSet),?HEX(E, OffSet),?HEX(F, OffSet),?HEX(G, OffSet)>> || <<A,B,C,D,E,F,G>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 6 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet),?HEX(D, OffSet),?HEX(E, OffSet),?HEX(F, OffSet)>> || <<A,B,C,D,E,F>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 5 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet),?HEX(D, OffSet),?HEX(E, OffSet)>> || <<A,B,C,D,E>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 4 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet),?HEX(D, OffSet)>> || <<A,B,C,D>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 3 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet),?HEX(C, OffSet)>> || <<A,B,C>> <= Data >>;
-encode_hex1(Data, OffSet) when byte_size(Data) rem 2 =:= 0 ->
- << <<?HEX(A, OffSet),?HEX(B, OffSet)>> || <<A,B>> <= Data >>;
-encode_hex1(Data, OffSet) when is_binary(Data) ->
- << <<?HEX(N, OffSet)>> || <<N>> <= Data >>.
+encode_hex1(Data, Offset) ->
+ <<First:(bit_size(Data) div 64)/binary-unit:64, Rest/binary>> = Data,
+ Hex = << <<(hex(A, Offset)):16, (hex(B, Offset)):16, (hex(C, Offset)):16, (hex(D, Offset)):16,
+ (hex(E, Offset)):16, (hex(F, Offset)):16, (hex(G, Offset)):16, (hex(H, Offset)):16>> ||
+ <<A,B,C,D,E,F,G,H>> <= First >>,
+ encode_hex2(Rest, Offset, Hex).
+
+encode_hex2(<<A,Data/binary>>, Offset, Acc) ->
+ encode_hex2(Data, Offset, <<Acc/binary, (hex(A, Offset)):16>>);
+encode_hex2(<<>>, _Offset, Acc) ->
+ Acc.
hex(X, Offset) ->
element(
@@ -440,84 +435,42 @@ hex(X, Offset) ->
16#6530, 16#6531, 16#6532, 16#6533, 16#6534, 16#6535, 16#6536, 16#6537, 16#6538, 16#6539, 16#6561, 16#6562, 16#6563, 16#6564, 16#6565, 16#6566,
16#6630, 16#6631, 16#6632, 16#6633, 16#6634, 16#6635, 16#6636, 16#6637, 16#6638, 16#6639, 16#6661, 16#6662, 16#6663, 16#6664, 16#6665, 16#6666}).
+-compile({inline, [unhex/1]}).
-spec decode_hex(Bin) -> Bin2 when
Bin :: <<_:_*16>>,
Bin2 :: binary().
-decode_hex(Bin) when byte_size(Bin) rem 2 =:= 0 ->
- << <<(unhex(Int))>> || <<Int:16>> <= Bin >>;
-decode_hex(Bin) ->
- badarg_with_info([Bin]).
-
-%% This function pattern-matches on the hexadecimal representation of a pair of characters
-%% for example, 16#3030 is matching on the integers <<48, 48>>, which is ascii for <<"00">>
-unhex(16#3030) -> 0; unhex(16#3031) -> 1; unhex(16#3032) -> 2; unhex(16#3033) -> 3; unhex(16#3034) -> 4; unhex(16#3035) -> 5; unhex(16#3036) -> 6; unhex(16#3037) -> 7; unhex(16#3038) -> 8; unhex(16#3039) -> 9;
-unhex(16#3041) -> 10; unhex(16#3042) -> 11; unhex(16#3043) -> 12; unhex(16#3044) -> 13; unhex(16#3045) -> 14; unhex(16#3046) -> 15;
-unhex(16#3061) -> 10; unhex(16#3062) -> 11; unhex(16#3063) -> 12; unhex(16#3064) -> 13; unhex(16#3065) -> 14; unhex(16#3066) -> 15;
-unhex(16#3130) -> 16; unhex(16#3131) -> 17; unhex(16#3132) -> 18; unhex(16#3133) -> 19; unhex(16#3134) -> 20; unhex(16#3135) -> 21; unhex(16#3136) -> 22; unhex(16#3137) -> 23; unhex(16#3138) -> 24; unhex(16#3139) -> 25;
-unhex(16#3141) -> 26; unhex(16#3142) -> 27; unhex(16#3143) -> 28; unhex(16#3144) -> 29; unhex(16#3145) -> 30; unhex(16#3146) -> 31;
-unhex(16#3161) -> 26; unhex(16#3162) -> 27; unhex(16#3163) -> 28; unhex(16#3164) -> 29; unhex(16#3165) -> 30; unhex(16#3166) -> 31;
-unhex(16#3230) -> 32; unhex(16#3231) -> 33; unhex(16#3232) -> 34; unhex(16#3233) -> 35; unhex(16#3234) -> 36; unhex(16#3235) -> 37; unhex(16#3236) -> 38; unhex(16#3237) -> 39; unhex(16#3238) -> 40; unhex(16#3239) -> 41;
-unhex(16#3241) -> 42; unhex(16#3242) -> 43; unhex(16#3243) -> 44; unhex(16#3244) -> 45; unhex(16#3245) -> 46; unhex(16#3246) -> 47;
-unhex(16#3261) -> 42; unhex(16#3262) -> 43; unhex(16#3263) -> 44; unhex(16#3264) -> 45; unhex(16#3265) -> 46; unhex(16#3266) -> 47;
-unhex(16#3330) -> 48; unhex(16#3331) -> 49; unhex(16#3332) -> 50; unhex(16#3333) -> 51; unhex(16#3334) -> 52; unhex(16#3335) -> 53; unhex(16#3336) -> 54; unhex(16#3337) -> 55; unhex(16#3338) -> 56; unhex(16#3339) -> 57;
-unhex(16#3341) -> 58; unhex(16#3342) -> 59; unhex(16#3343) -> 60; unhex(16#3344) -> 61; unhex(16#3345) -> 62; unhex(16#3346) -> 63;
-unhex(16#3361) -> 58; unhex(16#3362) -> 59; unhex(16#3363) -> 60; unhex(16#3364) -> 61; unhex(16#3365) -> 62; unhex(16#3366) -> 63;
-unhex(16#3430) -> 64; unhex(16#3431) -> 65; unhex(16#3432) -> 66; unhex(16#3433) -> 67; unhex(16#3434) -> 68; unhex(16#3435) -> 69; unhex(16#3436) -> 70; unhex(16#3437) -> 71; unhex(16#3438) -> 72; unhex(16#3439) -> 73;
-unhex(16#3441) -> 74; unhex(16#3442) -> 75; unhex(16#3443) -> 76; unhex(16#3444) -> 77; unhex(16#3445) -> 78; unhex(16#3446) -> 79;
-unhex(16#3461) -> 74; unhex(16#3462) -> 75; unhex(16#3463) -> 76; unhex(16#3464) -> 77; unhex(16#3465) -> 78; unhex(16#3466) -> 79;
-unhex(16#3530) -> 80; unhex(16#3531) -> 81; unhex(16#3532) -> 82; unhex(16#3533) -> 83; unhex(16#3534) -> 84; unhex(16#3535) -> 85; unhex(16#3536) -> 86; unhex(16#3537) -> 87; unhex(16#3538) -> 88; unhex(16#3539) -> 89;
-unhex(16#3541) -> 90; unhex(16#3542) -> 91; unhex(16#3543) -> 92; unhex(16#3544) -> 93; unhex(16#3545) -> 94; unhex(16#3546) -> 95;
-unhex(16#3561) -> 90; unhex(16#3562) -> 91; unhex(16#3563) -> 92; unhex(16#3564) -> 93; unhex(16#3565) -> 94; unhex(16#3566) -> 95;
-unhex(16#3630) -> 96; unhex(16#3631) -> 97; unhex(16#3632) -> 98; unhex(16#3633) -> 99; unhex(16#3634) -> 100; unhex(16#3635) -> 101; unhex(16#3636) -> 102; unhex(16#3637) -> 103; unhex(16#3638) -> 104; unhex(16#3639) -> 105;
-unhex(16#3641) -> 106; unhex(16#3642) -> 107; unhex(16#3643) -> 108; unhex(16#3644) -> 109; unhex(16#3645) -> 110; unhex(16#3646) -> 111;
-unhex(16#3661) -> 106; unhex(16#3662) -> 107; unhex(16#3663) -> 108; unhex(16#3664) -> 109; unhex(16#3665) -> 110; unhex(16#3666) -> 111;
-unhex(16#3730) -> 112; unhex(16#3731) -> 113; unhex(16#3732) -> 114; unhex(16#3733) -> 115; unhex(16#3734) -> 116; unhex(16#3735) -> 117; unhex(16#3736) -> 118; unhex(16#3737) -> 119; unhex(16#3738) -> 120; unhex(16#3739) -> 121;
-unhex(16#3741) -> 122; unhex(16#3742) -> 123; unhex(16#3743) -> 124; unhex(16#3744) -> 125; unhex(16#3745) -> 126; unhex(16#3746) -> 127;
-unhex(16#3761) -> 122; unhex(16#3762) -> 123; unhex(16#3763) -> 124; unhex(16#3764) -> 125; unhex(16#3765) -> 126; unhex(16#3766) -> 127;
-unhex(16#3830) -> 128; unhex(16#3831) -> 129; unhex(16#3832) -> 130; unhex(16#3833) -> 131; unhex(16#3834) -> 132; unhex(16#3835) -> 133; unhex(16#3836) -> 134; unhex(16#3837) -> 135; unhex(16#3838) -> 136; unhex(16#3839) -> 137;
-unhex(16#3841) -> 138; unhex(16#3842) -> 139; unhex(16#3843) -> 140; unhex(16#3844) -> 141; unhex(16#3845) -> 142; unhex(16#3846) -> 143;
-unhex(16#3861) -> 138; unhex(16#3862) -> 139; unhex(16#3863) -> 140; unhex(16#3864) -> 141; unhex(16#3865) -> 142; unhex(16#3866) -> 143;
-unhex(16#3930) -> 144; unhex(16#3931) -> 145; unhex(16#3932) -> 146; unhex(16#3933) -> 147; unhex(16#3934) -> 148; unhex(16#3935) -> 149; unhex(16#3936) -> 150; unhex(16#3937) -> 151; unhex(16#3938) -> 152; unhex(16#3939) -> 153;
-unhex(16#3941) -> 154; unhex(16#3942) -> 155; unhex(16#3943) -> 156; unhex(16#3944) -> 157; unhex(16#3945) -> 158; unhex(16#3946) -> 159;
-unhex(16#3961) -> 154; unhex(16#3962) -> 155; unhex(16#3963) -> 156; unhex(16#3964) -> 157; unhex(16#3965) -> 158; unhex(16#3966) -> 159;
-unhex(16#4130) -> 160; unhex(16#4131) -> 161; unhex(16#4132) -> 162; unhex(16#4133) -> 163; unhex(16#4134) -> 164; unhex(16#4135) -> 165; unhex(16#4136) -> 166; unhex(16#4137) -> 167; unhex(16#4138) -> 168; unhex(16#4139) -> 169;
-unhex(16#4141) -> 170; unhex(16#4142) -> 171; unhex(16#4143) -> 172; unhex(16#4144) -> 173; unhex(16#4145) -> 174; unhex(16#4146) -> 175;
-unhex(16#4161) -> 170; unhex(16#4162) -> 171; unhex(16#4163) -> 172; unhex(16#4164) -> 173; unhex(16#4165) -> 174; unhex(16#4166) -> 175;
-unhex(16#4230) -> 176; unhex(16#4231) -> 177; unhex(16#4232) -> 178; unhex(16#4233) -> 179; unhex(16#4234) -> 180; unhex(16#4235) -> 181; unhex(16#4236) -> 182; unhex(16#4237) -> 183; unhex(16#4238) -> 184; unhex(16#4239) -> 185;
-unhex(16#4241) -> 186; unhex(16#4242) -> 187; unhex(16#4243) -> 188; unhex(16#4244) -> 189; unhex(16#4245) -> 190; unhex(16#4246) -> 191;
-unhex(16#4261) -> 186; unhex(16#4262) -> 187; unhex(16#4263) -> 188; unhex(16#4264) -> 189; unhex(16#4265) -> 190; unhex(16#4266) -> 191;
-unhex(16#4330) -> 192; unhex(16#4331) -> 193; unhex(16#4332) -> 194; unhex(16#4333) -> 195; unhex(16#4334) -> 196; unhex(16#4335) -> 197; unhex(16#4336) -> 198; unhex(16#4337) -> 199; unhex(16#4338) -> 200; unhex(16#4339) -> 201;
-unhex(16#4341) -> 202; unhex(16#4342) -> 203; unhex(16#4343) -> 204; unhex(16#4344) -> 205; unhex(16#4345) -> 206; unhex(16#4346) -> 207;
-unhex(16#4361) -> 202; unhex(16#4362) -> 203; unhex(16#4363) -> 204; unhex(16#4364) -> 205; unhex(16#4365) -> 206; unhex(16#4366) -> 207;
-unhex(16#4430) -> 208; unhex(16#4431) -> 209; unhex(16#4432) -> 210; unhex(16#4433) -> 211; unhex(16#4434) -> 212; unhex(16#4435) -> 213; unhex(16#4436) -> 214; unhex(16#4437) -> 215; unhex(16#4438) -> 216; unhex(16#4439) -> 217;
-unhex(16#4441) -> 218; unhex(16#4442) -> 219; unhex(16#4443) -> 220; unhex(16#4444) -> 221; unhex(16#4445) -> 222; unhex(16#4446) -> 223;
-unhex(16#4461) -> 218; unhex(16#4462) -> 219; unhex(16#4463) -> 220; unhex(16#4464) -> 221; unhex(16#4465) -> 222; unhex(16#4466) -> 223;
-unhex(16#4530) -> 224; unhex(16#4531) -> 225; unhex(16#4532) -> 226; unhex(16#4533) -> 227; unhex(16#4534) -> 228; unhex(16#4535) -> 229; unhex(16#4536) -> 230; unhex(16#4537) -> 231; unhex(16#4538) -> 232; unhex(16#4539) -> 233;
-unhex(16#4541) -> 234; unhex(16#4542) -> 235; unhex(16#4543) -> 236; unhex(16#4544) -> 237; unhex(16#4545) -> 238; unhex(16#4546) -> 239;
-unhex(16#4561) -> 234; unhex(16#4562) -> 235; unhex(16#4563) -> 236; unhex(16#4564) -> 237; unhex(16#4565) -> 238; unhex(16#4566) -> 239;
-unhex(16#4630) -> 240; unhex(16#4631) -> 241; unhex(16#4632) -> 242; unhex(16#4633) -> 243; unhex(16#4634) -> 244; unhex(16#4635) -> 245; unhex(16#4636) -> 246; unhex(16#4637) -> 247; unhex(16#4638) -> 248; unhex(16#4639) -> 249;
-unhex(16#4641) -> 250; unhex(16#4642) -> 251; unhex(16#4643) -> 252; unhex(16#4644) -> 253; unhex(16#4645) -> 254; unhex(16#4646) -> 255;
-unhex(16#4661) -> 250; unhex(16#4662) -> 251; unhex(16#4663) -> 252; unhex(16#4664) -> 253; unhex(16#4665) -> 254; unhex(16#4666) -> 255;
-unhex(16#6130) -> 160; unhex(16#6131) -> 161; unhex(16#6132) -> 162; unhex(16#6133) -> 163; unhex(16#6134) -> 164; unhex(16#6135) -> 165; unhex(16#6136) -> 166; unhex(16#6137) -> 167; unhex(16#6138) -> 168; unhex(16#6139) -> 169;
-unhex(16#6141) -> 170; unhex(16#6142) -> 171; unhex(16#6143) -> 172; unhex(16#6144) -> 173; unhex(16#6145) -> 174; unhex(16#6146) -> 175;
-unhex(16#6161) -> 170; unhex(16#6162) -> 171; unhex(16#6163) -> 172; unhex(16#6164) -> 173; unhex(16#6165) -> 174; unhex(16#6166) -> 175;
-unhex(16#6230) -> 176; unhex(16#6231) -> 177; unhex(16#6232) -> 178; unhex(16#6233) -> 179; unhex(16#6234) -> 180; unhex(16#6235) -> 181; unhex(16#6236) -> 182; unhex(16#6237) -> 183; unhex(16#6238) -> 184; unhex(16#6239) -> 185;
-unhex(16#6241) -> 186; unhex(16#6242) -> 187; unhex(16#6243) -> 188; unhex(16#6244) -> 189; unhex(16#6245) -> 190; unhex(16#6246) -> 191;
-unhex(16#6261) -> 186; unhex(16#6262) -> 187; unhex(16#6263) -> 188; unhex(16#6264) -> 189; unhex(16#6265) -> 190; unhex(16#6266) -> 191;
-unhex(16#6330) -> 192; unhex(16#6331) -> 193; unhex(16#6332) -> 194; unhex(16#6333) -> 195; unhex(16#6334) -> 196; unhex(16#6335) -> 197; unhex(16#6336) -> 198; unhex(16#6337) -> 199; unhex(16#6338) -> 200; unhex(16#6339) -> 201;
-unhex(16#6341) -> 202; unhex(16#6342) -> 203; unhex(16#6343) -> 204; unhex(16#6344) -> 205; unhex(16#6345) -> 206; unhex(16#6346) -> 207;
-unhex(16#6361) -> 202; unhex(16#6362) -> 203; unhex(16#6363) -> 204; unhex(16#6364) -> 205; unhex(16#6365) -> 206; unhex(16#6366) -> 207;
-unhex(16#6430) -> 208; unhex(16#6431) -> 209; unhex(16#6432) -> 210; unhex(16#6433) -> 211; unhex(16#6434) -> 212; unhex(16#6435) -> 213; unhex(16#6436) -> 214; unhex(16#6437) -> 215; unhex(16#6438) -> 216; unhex(16#6439) -> 217;
-unhex(16#6441) -> 218; unhex(16#6442) -> 219; unhex(16#6443) -> 220; unhex(16#6444) -> 221; unhex(16#6445) -> 222; unhex(16#6446) -> 223;
-unhex(16#6461) -> 218; unhex(16#6462) -> 219; unhex(16#6463) -> 220; unhex(16#6464) -> 221; unhex(16#6465) -> 222; unhex(16#6466) -> 223;
-unhex(16#6530) -> 224; unhex(16#6531) -> 225; unhex(16#6532) -> 226; unhex(16#6533) -> 227; unhex(16#6534) -> 228; unhex(16#6535) -> 229; unhex(16#6536) -> 230; unhex(16#6537) -> 231; unhex(16#6538) -> 232; unhex(16#6539) -> 233;
-unhex(16#6541) -> 234; unhex(16#6542) -> 235; unhex(16#6543) -> 236; unhex(16#6544) -> 237; unhex(16#6545) -> 238; unhex(16#6546) -> 239;
-unhex(16#6561) -> 234; unhex(16#6562) -> 235; unhex(16#6563) -> 236; unhex(16#6564) -> 237; unhex(16#6565) -> 238; unhex(16#6566) -> 239;
-unhex(16#6630) -> 240; unhex(16#6631) -> 241; unhex(16#6632) -> 242; unhex(16#6633) -> 243; unhex(16#6634) -> 244; unhex(16#6635) -> 245; unhex(16#6636) -> 246; unhex(16#6637) -> 247; unhex(16#6638) -> 248; unhex(16#6639) -> 249;
-unhex(16#6641) -> 250; unhex(16#6642) -> 251; unhex(16#6643) -> 252; unhex(16#6644) -> 253; unhex(16#6645) -> 254; unhex(16#6646) -> 255;
-unhex(16#6661) -> 250; unhex(16#6662) -> 251; unhex(16#6663) -> 252; unhex(16#6664) -> 253; unhex(16#6665) -> 254; unhex(16#6666) -> 255;
-unhex(Char) ->
- badarg_with_info([<<Char:16>>]).
+decode_hex(Data) when byte_size(Data) rem 2 =:= 0 ->
+ try
+ decode_hex1(Data)
+ catch
+ error:badarg ->
+ badarg_with_info([Data])
+ end;
+decode_hex(Data) ->
+ badarg_with_info([Data]).
+
+decode_hex1(Data) ->
+ <<First:(byte_size(Data) div 8)/binary-unit:64, Rest/binary>> = Data,
+ Bin = << <<(unhex(A)):4, (unhex(B)):4, (unhex(C)):4, (unhex(D)):4,
+ (unhex(E)):4, (unhex(F)):4, (unhex(G)):4, (unhex(H)):4>> ||
+ <<A,B,C,D,E,F,G,H>> <= First >>,
+ decode_hex2(Rest, Bin).
+
+decode_hex2(<<A,Data/binary>>, Acc) ->
+ decode_hex2(Data, <<Acc/binary-unit:4, (unhex(A)):4>>);
+decode_hex2(<<>>, Acc) ->
+ Acc.
+
+unhex(X) ->
+ element(X,
+ {nonono, no, no, no, no, no, no, no, no, no, no, no, no, no, no, %1
+ no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, %16
+ no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, %32
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, no, no, no, no, no, no, %48
+ no, 10, 11, 12, 13, 14, 15, no, no, no, no, no, no, no, no, no, %64
+ no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, %80
+ no, 10, 11, 12, 13, 14, 15, no, no, no, no, no, no, no, no, no %96
+ }).
badarg_with_cause(Args, Cause) ->
erlang:error(badarg, Args, [{error_info, #{module => erl_stdlib_errors,
diff --git a/lib/stdlib/src/erl_stdlib_errors.erl b/lib/stdlib/src/erl_stdlib_errors.erl
index 540c195a2a..a90d6477a7 100644
--- a/lib/stdlib/src/erl_stdlib_errors.erl
+++ b/lib/stdlib/src/erl_stdlib_errors.erl
@@ -77,8 +77,13 @@ format_binary_error(encode_hex, [Subject, Case], _) ->
[must_be_binary(Subject), must_be_hex_case(Case)];
format_binary_error(decode_hex, [Subject], _) ->
if
- is_binary(Subject), byte_size(Subject) rem 2 == 1 ->
- ["must contain an even number of bytes"];
+ is_binary(Subject) ->
+ if
+ byte_size(Subject) rem 2 =:= 1 ->
+ [<<"must contain an even number of bytes">>];
+ true ->
+ [<<"must only contain hex digits 0-9, A-F, and a-f">>]
+ end;
true ->
[must_be_binary(Subject)]
end;
@@ -1088,7 +1093,7 @@ expand_error(not_atom) ->
expand_error(not_binary) ->
<<"not a binary">>;
expand_error(bad_hex_case) ->
- <<"not uppercase or lowercase">>;
+ <<"not 'uppercase' or 'lowercase'">>;
expand_error(not_compiled_regexp) ->
<<"not a compiled regular expression">>;
expand_error(not_iodata) ->
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
index 5ed05bfc55..954efae9b7 100644
--- a/lib/stdlib/test/binary_module_SUITE.erl
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -1462,11 +1462,15 @@ error_info(_Config) ->
{split, [<<1,2,3>>, {bm,make_ref()}, []]},
{split, [<<1,2,3>>, <<"2">>, [bad_option]]},
- {encode_hex, [{no,a,binary}], [allow_rename]},
+ {encode_hex, [{no,binary}]},
+ {encode_hex, [{no,binary}, lowercase]},
{encode_hex, [<<"foobar">>, othercase]},
- {decode_hex, [{no,a,binary}]},
- {decode_hex, [<<"000">>],[allow_rename]},
- {decode_hex, [<<"GG">>],[allow_rename]}
+ {encode_hex, [no_binary, othercase], [{1,".*"}, {2,".*"}]},
+
+ {decode_hex, [{no,binary}]},
+ {decode_hex, [<<"000">>]},
+ {decode_hex, [<<"GG">>]},
+ {decode_hex, [<<255>>]}
],
error_info_lib:test_error_info(binary, L).
@@ -1512,8 +1516,29 @@ hex_encoding(Config) when is_list(Config) ->
<<"foobar">> = binary:decode_hex(<<"666f6f626172">>),
<<"foobar">> = binary:decode_hex(<<"666f6F626172">>),
+
+ rand:seed(default),
+ io:format("*** SEED: ~p ***\n", [rand:export_seed()]),
+ Bytes = iolist_to_binary([rand:bytes(256), lists:seq(0, 255)]),
+ do_hex_roundtrip(Bytes),
+
ok.
+do_hex_roundtrip(Bytes) ->
+ UpperHex = binary:encode_hex(Bytes),
+ UpperHex = binary:encode_hex(Bytes, uppercase),
+ LowerHex = binary:encode_hex(Bytes, lowercase),
+
+ Bytes = binary:decode_hex(UpperHex),
+ Bytes = binary:decode_hex(LowerHex),
+
+ case Bytes of
+ <<_, Rest/binary>> ->
+ do_hex_roundtrip(Rest);
+ <<>> ->
+ ok
+ end.
+
%%%
%%% Utilities.
%%%