2

I'm currently trying to translate a python script to ruby. Now I'm stuck on a part that uses a raw string for a regex.

This is the original python code:

pat = re.compile(r'.{4}\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.{1}\x78\x9C')
match = pat.search(string)
(start_match, end_match) = match.span()

This is my attempt to translate it to ruby:

pat = Regexp.compile('.{4}\\xAA\\xEE\\xAA\\x76\\x1B\\xEC\\xBB\\x20\\xF1\\xE6\\x51.{1}\\x78\\x9C')
start_match, end_match = string.enum_for(:scan, pat).map { Regexp.last_match.begin(0) }

Unfortunately I must be doing it wrong because I get this error:

invalid multibyte escape: /.{4}\\xAA\\xEE\\xAA\\x76\\x1B\\xEC\\xBB\\x20\\xF1\\xE6\\x51.{1}\\x78\\x9C/ (RegexpError)

I also tried:

regex_String = <<'TEXT'
.{4}\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.{1}\x78\x9C
TEXT
pat = Regexp.compile(regex_String)
start_match, end_match = string.enum_for(:scan, pat).map { Regexp.last_match.begin(0) }

But it results in the same error.

To place it in context, here is the whole script:

# Commented lines are the original python code
# Uncommented lines are the translated ruby code

#import zlib
#import sys
#import re
#import binascii
require "zlib"
require "hex_string"

#if(len(sys.argv) < 2 or sys.argv[1] == "-h"):
#    print "usage: python DecompNewDell.py <biosupdate.exe>"
#    exit()

if ARGV.length < 1 or ARGV[0] == "-h"
    puts "usage: ruby DecompNewDell.rb <biosupdate.exe>";
    exit
end

#f = open(sys.argv[1], "rb")
#string = f.read()
f = File.open(ARGV[0], 'rb')
string = f.read

#pat = re.compile(r'.{4}\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.{1}\x78\x9C')
#match = pat.search(string)
#(start_match, end_match) = match.span()
pat = Regexp.compile('.{4}\\xAA\\xEE\\xAA\\x76\\x1B\\xEC\\xBB\\x20\\xF1\\xE6\\x51.{1}\\x78\\x9C')
start_match, end_match = string.enum_for(:scan, pat).map { Regexp.last_match.begin(0) }

#compessed_len = string[start_match:start_match+4]
compressed_len = string[start_match..start_match+4]

#compessed_len = binascii.b2a_hex(compessed_len[::-1])
compessed_len.reverse!
compessed_len = compessed_len.to_hex_string(false)

#compessed_len = long(compessed_len, 16)
compessed_len = compessed_len.to_i(16)

#read len bytes out of the file into the new string to decompress
#f.seek(start_match+16)
#string = f.read(compessed_len)
f.seek start_match+16
string = f.read compessed_len

#o = zlib.decompress(string)
o = Zlib::Inflate.inflate(string)

#f2 = open(sys.argv[1] + "_decompressed.hdr", "wb")
#f2.write(o)
#f.close()
#f2.close()
#print "Decompressed data written to %s_decompressed.hdr" % sys.argv[1]
f2 = File.open(ARGV[0] + "_decompressed.hdr", 'wb')
f2.write(o)
f.close()
f2.close()
puts "Decompressed data written to #{ARGV[0]}_decompressed.hdr"

1 Answer 1

1

This answer shows why the problem raised.
https://stackoverflow.com/a/47785810/12349985

And there has a solution for this situation.
https://techoverflow.net/2013/12/29/solving-invalid-multibyte-escape-xfexff-in-ruby-vpim/

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that did the trick. I also had to use single backslashes instead of escaped ones.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.