File Coverage

blib/lib/JS/JJ.pm
Criterion Covered Total %
statement 102 102 100.0
branch 28 38 73.6
condition 33 44 75.0
subroutine 9 9 100.0
pod 2 2 100.0
total 174 195 89.2


line stmt bran cond sub pod time code
1             package JS::JJ;
2              
3 1     1   684 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         1  
  1         69  
5 1         72 use Encode qw/
6             encode_utf8
7             decode_utf8
8 1     1   587 /;
  1         9922  
9              
10 1     1   7 use base qw/Exporter/;
  1         2  
  1         1595  
11              
12             our @EXPORT_OK = qw/
13             jj_encode
14             jj_decode
15             /;
16              
17             our $VERSION = '0.01';
18              
19             our $jj_array = ['___', '__$', '_$_', '_$$', '$__', '$_$', '$$_', '$$$', '$___', '$__$', '$_$_', '$_$$', '$$__', '$$_$', '$$$_', '$$$$'];
20              
21             sub jj_encode {
22 1     1 1 3 my ($value, $key) = @_;
23            
24 1   50     3 $key ||= '$';
25            
26 1         2 my $encode = '';
27 1         1 my $temp = '';
28            
29 1         6 my @chars = split //, decode_utf8($value);
30            
31 1         46 for (my $i=0; $i
32 25         36 my $hex = ord $chars[$i];
33            
34 25 100 66     306 if ($hex == 0x22 || $hex == 0x5c) {
    100 100        
    100 100        
    100 100        
      66        
      66        
      66        
      33        
      66        
      100        
      33        
      100        
      100        
      66        
35 2         4 $temp .= '\\\\\\' . $chars[$i];
36             } elsif ((0x21 <= $hex && $hex <= 0x2f) || (0x3a <= $hex && $hex <= 0x40) || (0x5b <= $hex && $hex <= 0x60) || (0x7b <= $hex && $hex <= 0x7f)) {
37 3         7 $temp .= $chars[$i];
38             } elsif ((0x30 <= $hex && $hex <= 0x39) || (0x61 <= $hex && $hex <= 0x66)) {
39 7 50       13 $encode .= '"' . $temp . '"+' if $temp;
40 7 50       28 $encode .= $key . '.' . $jj_array->[$hex < 0x40 ? $hex - 0x30 : $hex - 0x57] . '+';
41            
42 7         18 $temp = '';
43             } elsif ($hex == 0x6c || $hex == 0x6f || $hex == 0x74 || $hex == 0x75) {
44 5 50       11 $encode .= '"' . $temp . '"+' if $temp;
45 5 100       10 $encode .= '(![]+"")[' . $key . '._$_]+' if $hex == 0x6c;
46 5 100       12 $encode .= $key . '._$+' if $hex == 0x6f;
47 5 100       9 $encode .= $key . '.__+' if $hex == 0x74;
48 5 50       14 $encode .= $key . '._+' if $hex == 0x75;
49            
50 5         11 $temp = '';
51             } else {
52 8         11 $encode .= '"';
53 8 100       16 $encode .= $temp if $temp;
54            
55 8 100       10 if ($hex < 128) {
56 7         26 my @oct = split //, sprintf "%o", $hex;
57            
58 7         15 for (keys @oct) {
59 19 50       73 $oct[$_] = $key . '.' . $jj_array->[$oct[$_]] . '+' if $oct[$_] =~ /[0-7]/;
60             }
61            
62 7         23 $encode .= '\\\\' . '"+' . join '', @oct;
63             } else {
64 1         9 my @hex = map { chr } unpack 'U*', sprintf "%04x", $hex;
  4         17  
65            
66 1         4 for (keys @hex) {
67 4 50       20 $hex[$_] = $key . '.' . $jj_array->[hex($hex[$_])] . '+' if $hex[$_] =~ /[0-9a-f]/;
68             }
69            
70 1         6 $encode .= '\\\\' . '"+' . $key . '._+' . join '', @hex;
71            
72             }
73            
74 8         19 $temp = '';
75             }
76             }
77            
78 1         3 return &_join_encode($encode, $key, $temp);
79             }
80              
81             sub jj_decode {
82 1     1 1 563 my $value = shift;
83            
84 1         14 my ($key) = $value =~ /(.*)=~\[\];/;
85 1         4 $key =~ s/^\s+|\s+$//;
86 1         3 $key =~ s/(\$)/\\\$/g;
87            
88 1 50       5 if ($key) {
89 1         2 my $jj = &_clean($value);
90            
91 1         2 my $regex = $key . '.';
92 1         5 $regex .= join '|' . $key . '.', @$jj_array;
93              
94             # hex
95 1         3 my $hex_n = 4 * length($key) + 24;
96            
97 1         78 my (@hex) = $jj =~ /(\"?\\\"\+${key}\._\+[${regex}\+]{${hex_n}})/g;
98            
99 1         5 for (@hex) {
100 1         6 my (@n) = $_ =~ /(\+)/g;
101 1 50       8 $_ =~ s/\+[^\+]+$/\+/ if scalar(@n) > 4;
102            
103 1         3 my $l = &_replace_hex($key, $_);
104 1         3 $l =~ s/^.+\+//g;
105 1         6 $l = encode_utf8(chr(hex($l)));
106            
107 1         25 $jj =~ s/\Q${_}\E\"?/${l}/;
108             }
109            
110 1         3 $jj = &_replace_hex($key, $jj);
111            
112             # oct
113 1         9 my (@oct) = $jj =~ /(\\\"\+\d{2,3})/g;
114            
115 1         3 for (@oct) {
116 7         25 my ($oct) = $_ =~ /(\d+)$/;
117 7 50       19 $oct =~ s/\d{1}$// if $oct > 177;
118            
119 7         13 my $l = chr(oct($oct));
120 7         91 $jj =~ s/\\\"\+${oct}\"?/${l}/;
121             }
122            
123             # lotu
124 1         12 $jj =~ s/\(!\[\]\+""\)\[${key}\._\$_\]\+\"?/l/gs;
125 1         19 $jj =~ s/${key}\._\$\+\"?/o/gs;
126 1         10 $jj =~ s/${key}\.__\+\"?/t/gs;
127 1         8 $jj =~ s/${key}\._\+\"?/u/gs;
128            
129             # remove \\
130 1         2 $jj =~ s/(\"\"\+)/\"/g;
131 1         3 $jj =~ s/\Q\\\E//g;
132            
133 1         10 return $jj;
134             }
135             }
136              
137             sub _clean {
138 1     1   2 my $jj = shift;
139            
140 1         10 my ($new) = $jj =~ /.\$\$\+"\\""\+(.*?)\"\+"\\"/;
141 1         45 $new =~ s/^\s+|\s+$//;
142            
143 1         3 return $new;
144             }
145              
146             sub _replace_hex {
147 2     2   4 my ($key, $value) = @_;
148            
149 2         14 $value =~ s/${key}\.\$\$\$\$\+\"?/f/g;
150 2         16 $value =~ s/${key}\.\$\$\$_\+\"?/e/g;
151 2         22 $value =~ s/${key}\.\$\$_\$\+\"?/d/g;
152 2         12 $value =~ s/${key}\.\$\$__\+\"?/c/g;
153 2         11 $value =~ s/${key}\.\$_\$\$\+\"?/b/g;
154 2         13 $value =~ s/${key}\.\$_\$_\+\"?/a/g;
155 2         10 $value =~ s/${key}\.\$__\$\+\"?/9/g;
156 2         10 $value =~ s/${key}\.\$___\+\"?/8/g;
157 2         12 $value =~ s/${key}\.\$\$\$\+\"?/7/g;
158 2         13 $value =~ s/${key}\.\$\$_\+\"?/6/g;
159 2         20 $value =~ s/${key}\.\$_\$\+\"?/5/g;
160 2         33 $value =~ s/${key}\.\$__\+\"?/4/g;
161 2         16 $value =~ s/${key}\._\$\$\+\"?/3/g;
162 2         12 $value =~ s/${key}\._\$_\+\"?/2/g;
163 2         14 $value =~ s/${key}\.__\$\+\"?/1/g;
164 2         16 $value =~ s/${key}\.___\+\"?/0/g;
165              
166 2         8 return $value;
167             }
168              
169             sub _join_encode {
170 1     1   3 my ($encode, $key, $temp) = @_;
171            
172 1 50       4 $encode .= '"' . $temp . '"+' if $temp;
173 1         24 $encode = $key . '=~[];' .
174             $key . '={___:++' .
175             $key . ',$$$$:(![]+"")[' .
176             $key . '],__$:++' .
177             $key . ',$_$_:(![]+"")[' .
178             $key . '],_$_:++' .
179             $key . ',$_$$:({}+"")[' .
180             $key . '],$$_$:(' .
181             $key . '[' .
182             $key . ']+"")[' .
183             $key . '],_$$:++' .
184             $key . ',$$$_:(!""+"")[' .
185             $key . '],$__:++' .
186             $key . ',$_$:++' .
187             $key . ',$$__:({}+"")[' .
188             $key . '],$$_:++' .
189             $key . ',$$$:++' .
190             $key . ',$___:++' .
191             $key . ',$__$:++' .
192             $key . '};' .
193             $key . '.$_=' . '(' .
194             $key . '.$_=' .
195             $key . '+"")[' .
196             $key . '.$_$]+' . '(' .
197             $key . '._$=' .
198             $key . '.$_[' .
199             $key . '.__$])+' . '(' .
200             $key . '.$$=(' .
201             $key . '.$+"")[' .
202             $key . '.__$])+' . '((!' .
203             $key . ')+"")[' .
204             $key . '._$$]+' . '(' .
205             $key . '.__=' .
206             $key . '.$_[' .
207             $key . '.$$_])+' . '(' .
208             $key . '.$=(!""+"")[' .
209             $key . '.__$])+' . '(' .
210             $key . '._=(!""+"")[' .
211             $key . '._$_])+' .
212             $key . '.$_[' .
213             $key . '.$_$]+' .
214             $key . '.__+' .
215             $key . '._$+' .
216             $key . '.$;' .
217             $key . '.$$=' .
218             $key . '.$+' . '(!""+"")[' .
219             $key . '._$$]+' .
220             $key . '.__+' .
221             $key . '._+' .
222             $key . '.$+' .
223             $key . '.$$;' .
224             $key . '.$=(' .
225             $key . '.___)[' .
226             $key . '.$_][' .
227             $key . '.$_];' .
228             $key . '.$(' .
229             $key . '.$(' .
230             $key . '.$$+"\\""+' . $encode . '"\\"")())();';
231            
232 1         10 return $encode;
233             }
234              
235             1;
236              
237             =encoding utf8
238              
239             =head1 NAME
240              
241             JS::JJ - Encode and Decode JJ
242              
243             =head1 SYNOPSIS
244              
245             use JS::JJ qw/
246             jj_encode
247             jj_decode
248             /;
249            
250             my $jj = jj_encode($js);
251            
252             my $js = jj_decode($jj);
253            
254             =head1 DESCRIPTION
255            
256             This module provides methods for encode and decode JJ.
257              
258             =head1 METHODS
259              
260             =head2 jj_encode
261              
262             my $jj = jj_encode($js);
263            
264             Returns the jj.
265              
266             =head2 jj_decode
267              
268             my $js = jj_decode($jj);
269            
270             Returns the javascript.
271              
272             =head1 SEE ALSO
273              
274             L
275              
276             =head1 AUTHOR
277            
278             Lucas Tiago de Moraes C
279            
280             =head1 COPYRIGHT AND LICENSE
281            
282             This software is copyright (c) 2020 by Lucas Tiago de Moraes.
283            
284             This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
285            
286             =cut