Allow arbitrary bytes in the mime metadata key

This commit is contained in:
Kovid Goyal 2022-12-03 09:21:36 +05:30
parent fa6527cdf3
commit a622a149f6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 34 additions and 4 deletions

View File

@ -180,6 +180,18 @@ class ProtocolType(Enum):
osc_5522 = 5522 osc_5522 = 5522
def encode_mime(x: str) -> str:
import base64
return base64.standard_b64encode(x.encode('utf-8')).decode('ascii')
def decode_metadata_value(k: str, x: str) -> str:
if k == 'mime':
import base64
x = base64.standard_b64decode(x).decode('utf-8')
return x
class ReadRequest(NamedTuple): class ReadRequest(NamedTuple):
is_primary_selection: bool = False is_primary_selection: bool = False
mime_types: Tuple[str, ...] = ('text/plain',) mime_types: Tuple[str, ...] = ('text/plain',)
@ -193,7 +205,7 @@ class ReadRequest(NamedTuple):
if self.id: if self.id:
ans += f':id={self.id}' ans += f':id={self.id}'
if mime: if mime:
ans += f':mime={mime}' ans += f':mime={encode_mime(mime)}'
a = ans.encode('ascii') a = ans.encode('ascii')
if payload: if payload:
import base64 import base64
@ -318,7 +330,7 @@ class ClipboardRequestManager:
except Exception: except Exception:
log_error('Malformed OSC 5522: metadata is not key=value pairs') log_error('Malformed OSC 5522: metadata is not key=value pairs')
return return
m[k] = v m[k] = decode_metadata_value(k, v)
typ = m.get('type', '') typ = m.get('type', '')
if typ == 'read': if typ == 'read':
payload = base64.standard_b64decode(epayload) payload = base64.standard_b64decode(epayload)

View File

@ -160,6 +160,23 @@ func (self *Output) assign_mime_type(available_mimes []string) (err error) {
return fmt.Errorf("The MIME type %s for %s not available on the clipboard", self.mime_type, self.arg) return fmt.Errorf("The MIME type %s for %s not available on the clipboard", self.mime_type, self.arg)
} }
func escape_metadata_value(k, x string) (ans string) {
if k == "mime" {
x = base64.StdEncoding.EncodeToString(utils.UnsafeStringToBytes(x))
}
return x
}
func unescape_metadata_value(k, x string) (ans string) {
if k == "mime" {
b, err := base64.StdEncoding.DecodeString(x)
if err == nil {
x = string(b)
}
}
return x
}
func encode_bytes(metadata map[string]string, payload []byte) string { func encode_bytes(metadata map[string]string, payload []byte) string {
ans := strings.Builder{} ans := strings.Builder{}
ans.Grow(2048) ans.Grow(2048)
@ -172,7 +189,7 @@ func encode_bytes(metadata map[string]string, payload []byte) string {
} }
ans.WriteString(k) ans.WriteString(k)
ans.WriteString("=") ans.WriteString("=")
ans.WriteString(v) ans.WriteString(escape_metadata_value(k, v))
} }
if len(payload) > 0 { if len(payload) > 0 {
ans.WriteString(";") ans.WriteString(";")
@ -217,7 +234,8 @@ func parse_escape_code(etype loop.EscapeCodeType, data []byte) (metadata map[str
if len(rp) == 2 { if len(rp) == 2 {
v = string(rp[1]) v = string(rp[1])
} }
metadata[string(rp[0])] = v k := string(rp[0])
metadata[k] = unescape_metadata_value(k, v)
} }
} }