diff --git a/app/lib/vk.rb b/app/lib/vk.rb index fea7dae..4857f17 100644 --- a/app/lib/vk.rb +++ b/app/lib/vk.rb @@ -72,9 +72,64 @@ def self.retry_handle_429(response, desired_uri) end def self.parse_salt(s) - if data = /'(.*)'/.match(s) + if data = /^'(.*)'$/.match(s) return data.captures[0] end + + return unless s.starts_with?('(function() {') && s.ends_with?(';})();') + s = s.delete_prefix('(function() {') + s = s.delete_suffix(';})();') + + codes = s.delete_prefix('var codes = [[').split(']];').first.split('],[') + codes = codes.map do |carr| + carr + .split(/\(function\(e?\) ?{/) + .reject(&:blank?) + .map { |s| s.delete_suffix(',').delete_suffix(';})') } + .reverse + end + + + nums = codes.map do |cod| + cod + .reduce(0) { |code, f| js_func(f, code) } + .chr + end + + nums.join + end + + def self.js_func(s, arg = nil) + if s.start_with?('return') + s = s.delete_prefix('return ') + if s.match?(/^-?\d+$/) + return s.to_i + end + matches = /.* (.) (.*)/.match(s) + r = matches[2].to_i + op = matches[1] + if op == '-' + return arg.to_i - r + elsif op == '+' + return arg.to_i + r + elsif op == '^' + if arg + return arg.to_i ^ r + else + r + end + end + elsif s.start_with?('var map = {') + s = s.delete_prefix('var map = {') + m = s.split('};return').first.split(',') + m.each do |s| + k, v = s.split(':') + if k == "\"#{arg}\"" + return v.to_i + end + end + return nil + end end def self.response_requires_429?(response) diff --git a/spec/vk_spec.rb b/spec/vk_spec.rb index fe770d2..bf54124 100644 --- a/spec/vk_spec.rb +++ b/spec/vk_spec.rb @@ -44,4 +44,30 @@ }) end end + + describe 'js' do + describe '.js_func' do + it 'handles simple returns' do + expect(described_class.js_func('return -13')).to eq(-13) + end + + it 'handles subtraction' do + expect(described_class.js_func('return e - 1', 10)).to eq(9) + end + + it 'handles xor' do + expect(described_class.js_func('return e ^ 2', 10)).to eq(8) + end + + it 'handles nil xor' do + expect(described_class.js_func('return e ^ 3', nil)).to eq(3) + end + + it 'handles map access' do + expect( + described_class.js_func('var map = {"-1":1,"-2":2};return map[e]', -2)) + .to eq(2) + end + end + end end