Skip to content

Commit

Permalink
fix base64 encoding ; versioned extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
spyoungtech committed Sep 20, 2023
1 parent 19500a9 commit 9170f9e
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 274 deletions.
4 changes: 3 additions & 1 deletion ahk/_async/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def __init__(
self._extension_registry: _ExtensionMethodRegistry
self._extensions: list[Extension]
if extensions == 'auto':
self._extensions = list(_extension_registry)
self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)]
else:
self._extensions = _resolve_extensions(extensions) if extensions else []
self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={})
Expand Down Expand Up @@ -2785,6 +2785,8 @@ async def image_search(

if coord_mode is not None:
args.append(coord_mode)
else:
args.append('')

resp = await self._transport.function_call('AHKImageSearch', args, blocking=blocking)
return resp
Expand Down
212 changes: 79 additions & 133 deletions ahk/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2898,7 +2898,7 @@
;#NoEnv
#Requires Autohotkey >= 2.0-
Persistent
#Warn All, Off
;#Warn All, Off
#SingleInstance Off
; BEGIN user-defined directives
{% block user_directives %}
Expand Down Expand Up @@ -3097,13 +3097,18 @@
if (detect_hw != "") {
DetectHiddenWindows(detect_hw)
}
WinKill(title, text, secondstowait, extitle, extext)
DetectHiddenWindows(current_detect_hw)
SetTitleMatchMode(current_match_mode)
SetTitleMatchMode(current_match_speed)
try {
if (secondstowait != "") {
WinKill(title, text, secondstowait, extitle, extext)
} else {
WinKill(title, text,, extitle, extext)
}
}
finally {
DetectHiddenWindows(current_detect_hw)
SetTitleMatchMode(current_match_mode)
SetTitleMatchMode(current_match_speed)
}
return FormatNoValueResponse()
{% endblock AHKWinKill %}
}
Expand Down Expand Up @@ -4563,10 +4568,11 @@
}
try {
if ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath)
if (ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) = 1) {
s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos))
else
} else {
s := FormatNoValueResponse()
}
}
finally {
if (coord_mode != "") {
Expand Down Expand Up @@ -5467,7 +5473,7 @@
AHKGetClipboardAll(command) {
{% block AHKGetClipboardAll %}
data := ClipboardAll()
return FormatBinaryResponse(data)
return FormatBinaryResponse(&data)
{% endblock AHKGetClipboardAll %}
}
Expand All @@ -5484,7 +5490,7 @@
; TODO there should be a way for us to accept a base64 string instead
filename := command[2]
contents := FileRead(filename, "RAW")
ClipboardAll(contents)
A_Clipboard := ClipboardAll(contents)
return FormatNoValueResponse()
{% endblock AHKSetClipboardAll %}
}
Expand Down Expand Up @@ -5627,66 +5633,7 @@
return ret
}
; LC_* functions are substantially from Libcrypt
; Modified from https://github.com/ahkscript/libcrypt.ahk
; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821
; Original License:
; The MIT License (MIT)
;
; Copyright (c) 2014 The ahkscript community (ahkscript.org)
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8")
{
Bin_ := Buffer(StrPut(Text_, Encoding_))
LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1)
return Base64_
}
LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8")
{
Len_ := LC_Base64_Decode(&Bin_, &Text_)
return StrGet(StrPtr(Bin_), Len_, Encoding_)
}
LC_Base64_Encode(&Out_, &In_, In_Len)
{
return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001)
}
LC_Base64_Decode(&Out_, &In_)
{
return LC_Str2Bin(&Out_, &In_, 0x1)
}
LC_Bin2Str(&Out_, &In_, In_Len, Flags_)
{
DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0)
VarSetStrCapacity(&Out_, Out_Len * 2)
DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len)
return Out_Len
}
LC_Str2Bin(&Out_, &In_, Flags_)
{
DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0)
VarSetStrCapacity(&Out_, Out_Len)
DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0)
return Out_Len
}
; End of libcrypt code
b64decode(pszString) {
b64decode(&pszString) {
; TODO load DLL globally for performance
; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw
; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted.
Expand All @@ -5696,82 +5643,80 @@
; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA.
; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed.
; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed.
return LC_Base64_Decode_Text(pszString)
; if (pszString = "") {
; return ""
; }
;
; cchString := StrLen(pszString)
;
; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers.
; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call)
if (pszString = "") {
return ""
}
cchString := StrLen(pszString)
dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers.
getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call)
; buff_size := 0 ; The function will write to this variable on our first call
; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero
; pdwFlags := 0 ; We don't need this, so make it null
;
; ; The first call calculates the required size. The result is written to pbBinary
; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags )
; if (success = 0) {
; return ""
; }
;
; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value
; ret := Buffer(buff_size, 0)
;; granted := VarSetStrCapacity(&ret, buff_size)
;
; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to
;
; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags )
; if (success=0) {
; return ""
; }
;
; return StrGet(ret, "UTF-8")
pdwSkip := 0 ; We don't use any headers or preamble, so this is zero
pdwFlags := 0 ; We don't need this, so make it null
; The first call calculates the required size. The result is written to pbBinary
success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", &buff_size := 0, "Int", pdwSkip, "Int", pdwFlags )
if (success = 0) {
return ""
}
; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value
ret := Buffer(buff_size)
; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to
success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret.Ptr, "UIntP", &buff_size, "Int", pdwSkip, "Int", pdwFlags )
if (success=0) {
return ""
}
return StrGet(ret, "UTF-8")
}
b64encode(data) {
b64encode(&data) {
; REF: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa
; [in] const BYTE *pbBinary: A pointer to the array of bytes to be converted into a string.
; [in] DWORD cbBinary: The number of elements in the pbBinary array.
; [in] DWORD dwFlags: Specifies the format of the resulting formatted string (see table in REF)
; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size
; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer
LC_Base64_Encode(&Base64_, &data, data.Size)
return Base64_
; cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1)
; if (cbBinary = 0) {
; return ""
; }
;
; dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF
;
; ; First step is to get the size so we can set the capacity of our return buffer correctly
; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size)
; if (success = 0) {
; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError)
; throw Exception(msg, -1)
; }
;
; VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1))
;
; ; Now we do the conversion to base64 and rteturn the string
;
; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size)
; if (success = 0) {
; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError)
; throw Exception(msg, -1)
; }
; return ret
cbBinary := data.Size
if (cbBinary = 0) {
return ""
}
dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF
; First step is to get the size so we can set the capacity of our return buffer correctly
success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", &buff_size := 0)
if (success = 0) {
msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError)
throw Error(msg, -1)
}
VarSetStrCapacity(&ret, buff_size * 2)
; Now we do the conversion to base64 and rteturn the string
success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", &buff_size)
if (success = 0) {
msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError)
throw Error(msg, -1)
}
return ret
}
CommandArrayFromQuery(text) {
decoded_commands := []
encoded_array := StrSplit(text, "|")
function_name := encoded_array[1]
encoded_array.RemoveAt(1)
decoded_commands.push(function_name)
for index, encoded_value in encoded_array {
decoded_value := b64decode(encoded_value)
decoded_value := b64decode(&encoded_value)
decoded_commands.push(decoded_value)
}
return decoded_commands
Expand Down Expand Up @@ -5832,9 +5777,7 @@
{% endif %}
{% endfor %}
{% if on_clipboard %}
OnClipboardChange("ClipChanged")
{% endif %}
KEEPALIVE := Chr(57344)
;SetTimer, keepalive, 1000
Expand Down Expand Up @@ -5987,6 +5930,9 @@
WriteStdout(ret)
return
}
OnClipboardChange(ClipChanged)
{% endif %}
Expand Down
4 changes: 3 additions & 1 deletion ahk/_sync/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def __init__(
self._extension_registry: _ExtensionMethodRegistry
self._extensions: list[Extension]
if extensions == 'auto':
self._extensions = list(_extension_registry)
self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)]
else:
self._extensions = _resolve_extensions(extensions) if extensions else []
self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={})
Expand Down Expand Up @@ -2773,6 +2773,8 @@ def image_search(

if coord_mode is not None:
args.append(coord_mode)
else:
args.append('')

resp = self._transport.function_call('AHKImageSearch', args, blocking=blocking)
return resp
Expand Down
2 changes: 2 additions & 0 deletions ahk/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ def __init__(
script_text: str | None = None,
includes: list[str] | None = None,
dependencies: list[Extension] | None = None,
requires_autohotkey: typing.Literal['v1', 'v2'] | None = None,
):
self._requires = requires_autohotkey
self._text: str = script_text or ''
self._includes: list[str] = includes or []
self.dependencies: list[Extension] = dependencies or []
Expand Down
Loading

0 comments on commit 9170f9e

Please sign in to comment.