Issue #7525 has been reported by mghomn (Justin Peal). ---------------------------------------- Feature #7525: How to avoid memory leak when something gets wrong and throw exception when using win32api? https://bugs.ruby-lang.org/issues/7525 Author: mghomn (Justin Peal) Status: Open Priority: Normal Assignee: Category: Target version: require 'win32api' module Crypto # Common API NULL = 0 @GetLastError = Win32API.new('kernel32', 'GetLastError', '', 'I') @lstrlen = Win32API.new('kernel32', 'lstrlenW', 'L', 'I') # Memory API @RtlMoveMemory = Win32API.new('kernel32', 'RtlMoveMemory', 'PLL', 'I') @LocalFree = Win32API.new('kernel32', 'LocalFree', 'L', 'I') # Crypto API CRYPTPROTECT_UI_FORBIDDEN = 0x01 @CryptProtectData = Win32API.new('crypt32', 'CryptProtectData', 'PPPPPLP', 'I') @CryptUnprotectData = Win32API.new('crypt32', 'CryptUnprotectData', 'PPPPPLP', 'I') def self.error func puts "#{func} Error = #{@GetLastError.call()}" end def self.encrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') szDataDescr = (desc + "\0").encode(Encoding::UTF_16LE) pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptProtectData') if @CryptProtectData.call(pDataIn, szDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL ret end def self.decrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') ppszDataDescr = [NULL].pack('L') pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptUnprotectData') if @CryptUnprotectData.call(pDataIn, ppszDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 pszDataDescr = ppszDataDescr.unpack('L').first szDataDescr = ' '.encode(Encoding::UTF_16LE) * @lstrlen.call(pszDataDescr) return error('RtlMoveMemory') if @RtlMoveMemory.call(szDataDescr, pszDataDescr, szDataDescr.bytesize) == 0 return error('LocalFree') if @LocalFree.call(pszDataDescr) != NULL szDataDescr.encode!(Encoding::UTF_8) cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL desc = '' unless desc return error('Unmatched description') unless desc == szDataDescr ret.force_encoding(Encoding::UTF_8) end end if $0 == __FILE__ def test plain, entropy, desc puts "plain = #{plain}, entropy = #{entropy}, desc = #{desc}" cipher = Crypto.encrypt(plain, entropy, desc) puts "cipher = #{cipher.unpack('H*').first}" recover = Crypto.decrypt(cipher, entropy, desc) puts "recover = #{recover}" end begin test('abcd', 'efgh', 'ijkl') rescue puts $!.to_s.force_encoding(Encoding::UTF_8), $!.backtrace.join($/) end end
[ruby-trunk - Feature #7525][Open] How to avoid memory leak when something gets wrong and throw exce
on 2012-12-06 08:53
on 2012-12-09 13:12
Issue #7525 has been updated by mame (Yusuke Endoh). Status changed from Open to Assigned Assignee set to usa (Usaku NAKAMURA) Target version set to 2.0.0 Is this really a feature request? Or bug report? Assigning to usa. Usa-san, if this is a feature, please set the target to next minor. If this is a bug report, please consider how to fix. -- Yusuke Endoh <mame@tsg.ne.jp> ---------------------------------------- Feature #7525: How to avoid memory leak when something gets wrong and throw exception when using win32api? https://bugs.ruby-lang.org/issues/7525#change-34554 Author: mghomn (Justin Peal) Status: Assigned Priority: Normal Assignee: usa (Usaku NAKAMURA) Category: Target version: 2.0.0 require 'win32api' module Crypto # Common API NULL = 0 @GetLastError = Win32API.new('kernel32', 'GetLastError', '', 'I') @lstrlen = Win32API.new('kernel32', 'lstrlenW', 'L', 'I') # Memory API @RtlMoveMemory = Win32API.new('kernel32', 'RtlMoveMemory', 'PLL', 'I') @LocalFree = Win32API.new('kernel32', 'LocalFree', 'L', 'I') # Crypto API CRYPTPROTECT_UI_FORBIDDEN = 0x01 @CryptProtectData = Win32API.new('crypt32', 'CryptProtectData', 'PPPPPLP', 'I') @CryptUnprotectData = Win32API.new('crypt32', 'CryptUnprotectData', 'PPPPPLP', 'I') def self.error func puts "#{func} Error = #{@GetLastError.call()}" end def self.encrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') szDataDescr = (desc + "\0").encode(Encoding::UTF_16LE) pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptProtectData') if @CryptProtectData.call(pDataIn, szDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL ret end def self.decrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') ppszDataDescr = [NULL].pack('L') pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptUnprotectData') if @CryptUnprotectData.call(pDataIn, ppszDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 pszDataDescr = ppszDataDescr.unpack('L').first szDataDescr = ' '.encode(Encoding::UTF_16LE) * @lstrlen.call(pszDataDescr) return error('RtlMoveMemory') if @RtlMoveMemory.call(szDataDescr, pszDataDescr, szDataDescr.bytesize) == 0 return error('LocalFree') if @LocalFree.call(pszDataDescr) != NULL szDataDescr.encode!(Encoding::UTF_8) cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL desc = '' unless desc return error('Unmatched description') unless desc == szDataDescr ret.force_encoding(Encoding::UTF_8) end end if $0 == __FILE__ def test plain, entropy, desc puts "plain = #{plain}, entropy = #{entropy}, desc = #{desc}" cipher = Crypto.encrypt(plain, entropy, desc) puts "cipher = #{cipher.unpack('H*').first}" recover = Crypto.decrypt(cipher, entropy, desc) puts "recover = #{recover}" end begin test('abcd', 'efgh', 'ijkl') rescue puts $!.to_s.force_encoding(Encoding::UTF_8), $!.backtrace.join($/) end end
on 2012-12-21 13:56
Issue #7525 has been updated by usa (Usaku NAKAMURA).
Status changed from Assigned to Rejected
# This is not a feature request nor a bug report. Only quetion.
Generically, you can use begin-ensure-end syntax to release resources.
For example:
begin
foo = get_some_resource
do_something_and_raises_exception
ensure
release_the_resource(foo) if foo
end
----------------------------------------
Feature #7525: How to avoid memory leak when something gets wrong and
throw exception when using win32api?
https://bugs.ruby-lang.org/issues/7525#change-34939
Author: mghomn (Justin Peal)
Status: Rejected
Priority: Normal
Assignee: usa (Usaku NAKAMURA)
Category:
Target version: 2.0.0
require 'win32api'
module Crypto
# Common API
NULL = 0
@GetLastError = Win32API.new('kernel32', 'GetLastError', '', 'I')
@lstrlen = Win32API.new('kernel32', 'lstrlenW', 'L', 'I')
# Memory API
@RtlMoveMemory = Win32API.new('kernel32', 'RtlMoveMemory', 'PLL', 'I')
@LocalFree = Win32API.new('kernel32', 'LocalFree', 'L', 'I')
# Crypto API
CRYPTPROTECT_UI_FORBIDDEN = 0x01
@CryptProtectData = Win32API.new('crypt32', 'CryptProtectData',
'PPPPPLP', 'I')
@CryptUnprotectData = Win32API.new('crypt32', 'CryptUnprotectData',
'PPPPPLP', 'I')
def self.error func
puts "#{func} Error = #{@GetLastError.call()}"
end
def self.encrypt str, entropy, desc
pDataIn = [str.bytesize, str].pack('Lp')
szDataDescr = (desc + "\0").encode(Encoding::UTF_16LE)
pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp')
pvReserved = pPromptStruct = NULL
dwFlags = CRYPTPROTECT_UI_FORBIDDEN
pDataOut = [0, ''].pack('Lp')
return error('CryptProtectData') if @CryptProtectData.call(pDataIn,
szDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags,
pDataOut) == 0
cbData, pbData = pDataOut.unpack('LL')
ret = ' '.encode(Encoding::BINARY) * cbData
return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData,
cbData) == 0
return error('LocalFree') if @LocalFree.call(pbData) != NULL
ret
end
def self.decrypt str, entropy, desc
pDataIn = [str.bytesize, str].pack('Lp')
ppszDataDescr = [NULL].pack('L')
pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp')
pvReserved = pPromptStruct = NULL
dwFlags = CRYPTPROTECT_UI_FORBIDDEN
pDataOut = [0, ''].pack('Lp')
return error('CryptUnprotectData') if
@CryptUnprotectData.call(pDataIn, ppszDataDescr, pOptionalEntropy,
pvReserved, pPromptStruct, dwFlags, pDataOut) == 0
pszDataDescr = ppszDataDescr.unpack('L').first
szDataDescr = ' '.encode(Encoding::UTF_16LE) *
@lstrlen.call(pszDataDescr)
return error('RtlMoveMemory') if @RtlMoveMemory.call(szDataDescr,
pszDataDescr, szDataDescr.bytesize) == 0
return error('LocalFree') if @LocalFree.call(pszDataDescr) != NULL
szDataDescr.encode!(Encoding::UTF_8)
cbData, pbData = pDataOut.unpack('LL')
ret = ' '.encode(Encoding::BINARY) * cbData
return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData,
cbData) == 0
return error('LocalFree') if @LocalFree.call(pbData) != NULL
desc = '' unless desc
return error('Unmatched description') unless desc == szDataDescr
ret.force_encoding(Encoding::UTF_8)
end
end
if $0 == __FILE__
def test plain, entropy, desc
puts "plain = #{plain}, entropy = #{entropy}, desc = #{desc}"
cipher = Crypto.encrypt(plain, entropy, desc)
puts "cipher = #{cipher.unpack('H*').first}"
recover = Crypto.decrypt(cipher, entropy, desc)
puts "recover = #{recover}"
end
begin
test('abcd', 'efgh', 'ijkl')
rescue
puts $!.to_s.force_encoding(Encoding::UTF_8), $!.backtrace.join($/)
end
end
on 2013-01-30 01:53
Issue #7525 has been updated by mghomn (Justin Peal). Thank you for the resource release schema! ---------------------------------------- Feature #7525: How to avoid memory leak when something gets wrong and throw exception when using win32api? https://bugs.ruby-lang.org/issues/7525#change-35711 Author: mghomn (Justin Peal) Status: Rejected Priority: Normal Assignee: usa (Usaku NAKAMURA) Category: Target version: 2.0.0 require 'win32api' module Crypto # Common API NULL = 0 @GetLastError = Win32API.new('kernel32', 'GetLastError', '', 'I') @lstrlen = Win32API.new('kernel32', 'lstrlenW', 'L', 'I') # Memory API @RtlMoveMemory = Win32API.new('kernel32', 'RtlMoveMemory', 'PLL', 'I') @LocalFree = Win32API.new('kernel32', 'LocalFree', 'L', 'I') # Crypto API CRYPTPROTECT_UI_FORBIDDEN = 0x01 @CryptProtectData = Win32API.new('crypt32', 'CryptProtectData', 'PPPPPLP', 'I') @CryptUnprotectData = Win32API.new('crypt32', 'CryptUnprotectData', 'PPPPPLP', 'I') def self.error func puts "#{func} Error = #{@GetLastError.call()}" end def self.encrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') szDataDescr = (desc + "\0").encode(Encoding::UTF_16LE) pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptProtectData') if @CryptProtectData.call(pDataIn, szDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL ret end def self.decrypt str, entropy, desc pDataIn = [str.bytesize, str].pack('Lp') ppszDataDescr = [NULL].pack('L') pOptionalEntropy = [entropy.bytesize, entropy].pack('Lp') pvReserved = pPromptStruct = NULL dwFlags = CRYPTPROTECT_UI_FORBIDDEN pDataOut = [0, ''].pack('Lp') return error('CryptUnprotectData') if @CryptUnprotectData.call(pDataIn, ppszDataDescr, pOptionalEntropy, pvReserved, pPromptStruct, dwFlags, pDataOut) == 0 pszDataDescr = ppszDataDescr.unpack('L').first szDataDescr = ' '.encode(Encoding::UTF_16LE) * @lstrlen.call(pszDataDescr) return error('RtlMoveMemory') if @RtlMoveMemory.call(szDataDescr, pszDataDescr, szDataDescr.bytesize) == 0 return error('LocalFree') if @LocalFree.call(pszDataDescr) != NULL szDataDescr.encode!(Encoding::UTF_8) cbData, pbData = pDataOut.unpack('LL') ret = ' '.encode(Encoding::BINARY) * cbData return error('RtlMoveMemory') if @RtlMoveMemory.call(ret, pbData, cbData) == 0 return error('LocalFree') if @LocalFree.call(pbData) != NULL desc = '' unless desc return error('Unmatched description') unless desc == szDataDescr ret.force_encoding(Encoding::UTF_8) end end if $0 == __FILE__ def test plain, entropy, desc puts "plain = #{plain}, entropy = #{entropy}, desc = #{desc}" cipher = Crypto.encrypt(plain, entropy, desc) puts "cipher = #{cipher.unpack('H*').first}" recover = Crypto.decrypt(cipher, entropy, desc) puts "recover = #{recover}" end begin test('abcd', 'efgh', 'ijkl') rescue puts $!.to_s.force_encoding(Encoding::UTF_8), $!.backtrace.join($/) end end
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.