PyQt5: cannot write cookie to file using QFile - python

I have a file named cookies.txt.
fd = QFile(":/cookies.txt")
available_cookies = QtNetwork.QNetworkCookieJar().allCookies()
for cookie in available_cookies:
print(cookie.toRawForm(1))
QTextStream(cookie.toRawForm(1), fd.open(QIODevice.WriteOnly))
fd.close()
Here is my full traceback:
QTextStream(cookie.toRawForm(1), fd.open(QIODevice.WriteOnly))
TypeError: arguments did not match any overloaded call:
QTextStream(): too many arguments
QTextStream(QIODevice): argument 1 has unexpected type 'QByteArray'
QTextStream(QByteArray, mode: Union[QIODevice.OpenMode, QIODevice.OpenModeFlag] = QIODevice.ReadWrite): argument 2 has unexpected type 'bool'
I am following the C++ documentation, and I am having trouble writing the corresponding python syntax.

In QTextStream(cookie.toRawForm(1), fd.open(QIODevice.WriteOnly)), you pass 2 arguments, a QByteArray, and a bool (QIODevice::open returns a boolean), but QTextStream cannot take a QByteArray with a bool.

Are you really trying to write to a resource path? Resources are read-only, so that is not going to work.
To write to a non-resource path:
fd = QFile('/tmp/cookies.txt')
if fd.open(QIODevice.WriteOnly):
available_cookies = QtNetwork.QNetworkCookieJar().allCookies()
stream = QTextStream(fd)
for cookie in available_cookies:
data = cookie.toRawForm(QtNetwork.QNetworkCookie.Full)
stream << data
fd.close()

Related

Upload file to Databricks DBFS with Python API

I'm following the Databricks example for uploading a file to DBFS (in my case .csv):
import json
import requests
import base64
DOMAIN = '<databricks-instance>'
TOKEN = '<your-token>'
BASE_URL = 'https://%s/api/2.0/dbfs/' % (DOMAIN)
def dbfs_rpc(action, body):
""" A helper function to make the DBFS API request, request/response is encoded/decoded as JSON """
response = requests.post(
BASE_URL + action,
headers={'Authorization': 'Bearer %s' % TOKEN },
json=body
)
return response.json()
# Create a handle that will be used to add blocks
handle = dbfs_rpc("create", {"path": "/temp/upload_large_file", "overwrite": "true"})['handle']
with open('/a/local/file') as f:
while True:
# A block can be at most 1MB
block = f.read(1 << 20)
if not block:
break
data = base64.standard_b64encode(block)
dbfs_rpc("add-block", {"handle": handle, "data": data})
# close the handle to finish uploading
dbfs_rpc("close", {"handle": handle})
When using the tutorial as is, I get an error:
Traceback (most recent call last):
File "db_api.py", line 65, in <module>
data = base64.standard_b64encode(block)
File "C:\Miniconda3\envs\dash_p36\lib\base64.py", line 95, in standard_b64encode
return b64encode(s)
File "C:\Miniconda3\envs\dash_p36\lib\base64.py", line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
I tried doing with open('./sample.csv', 'rb') as f: before passing the blocks to base64.standard_b64encode but then getting another error:
TypeError: Object of type 'bytes' is not JSON serializable
This happens when the encoded block data is being sent into the API call.
I tried skipping encoding entirely and just passing the blocks into the post call. In this case the file gets created in the DBFS but has 0 bytes size.
At this point I'm trying to make sense of it all. It doesn't want a string but it doesn't want bytes either. What am I doing wrong? Appreciate any help.
In Python we have strings and bytes, which are two different entities note that there is no implicit conversion between them, so you need to know when to use which and how to convert when necessary. This answer provides nice explanation.
With the code snippet I see two issues:
This you already got - open by default reads the file as text. So your block is a string, while standard_b64encode expects bytes and returns bytes. To read bytes from file it needs to be opened in binary mode:
with open('/a/local/file', 'rb') as f:
Only strings can be encoded as JSON. There's no source code available for dbfs_rpc (or I can't find it), but apparently it expects a string, which it internally encodes. Since your data is bytes, you need to convert it to string explicitly and that's done using decode:
dbfs_rpc("add-block", {"handle": handle, "data": data.decode('utf8')})

"must be a string without null bytes" or "can't concat str to bytes" passing a payload on a command line

I am trying to create an exploit for an exercise but I have a problem with the following code:
#!/usr/bin/python
import os
import struct
address = struct.pack("I",0x201014)
payload = address+"." + ".%x."*131 + ".%n."
os.system("/home/osboxes/Desktop/formatString " + payload)
But the mistake is as follows:
TypeError: system() argument 1 must be string without null bytes, not str
I am trying to upgrade to the current version of python with "subprocess" utility:
#!/usr/bin/python3
import subprocess
import struct
address = struct.pack("I",0x201014)
payload = address+"." + ".%x."*131 + ".%n."
subprocess.call("/home/osboxes/Desktop/formatString " + payload, shell=True)
But the mistake is as follows:
TypeError: can't concat str to bytes
How could I fix the byte or str conversion problem for both versions? both programs agree that the error is in the line of "payload = ..."
That string isn't capable of being passed as a command-line argument on UNIX.
Why? Because it contains NUL literals, and UNIX command lines are made up of C strings -- which are NUL-terminated.
>>> address = struct.pack("I",0x201014)
>>> address
b'\x14\x10 \x00'
See that \x00? Not allowed, not possible -- not as one command-line argument, at least.
But you can put it in an argv, as long as it's split into multiple arguments. Note that shell=False below:
payload = (address + (b'.%x.' * 131) + b'.%n.').split(b'\0')
subprocess.call(['/home/osboxes/Desktop/formatString'] + payload)
How does this work? Because the \x00s that terminate each individual C string are implicitly present at the boundary points.

Why does python protobuf json_format.Parse throw a TypeError?

I am experimenting with protobuf serialization to JSON. I made a simple proto file with the following messages:
syntax = "proto3";
message Bool {
bool data = 1;
}
message BoolArray {
repeated Bool bools = 1;
}
I then run some basic code to build the message, push to Json, then read it back in:
pb_bool_array = pb_bool.BoolArray()
b = pb_bool_array.bools.add()
b.data = True
bools_as_json = MessageToJson( pb_bool_array )
Parse(bools_as_json, proto.bool_pb2.BoolArray )
but the Parse function throws a TypeError with the following message:
google.protobuf.json_format.ParseError: Failed to parse bools field:
unbound method ClearField() must be called with BoolArray instance as
first argument (got str instance instead).
I traced the Parse function and this error fires off on line 519 in Google's json_format code. Why would this TypeError occur? Am I missing something in my proto spec and/or abusing the python API?
Thanks!
After further analysis of the json_format.Parse() function, I realized that I was abusing the API.
Parse(bools_as_json, proto.bool_pb2.BoolArray )
should really be:
Parse(bools_as_json, proto.bool_pb2.BoolArray() )
The API expects a message instance to fill, not the type of message. Everything works as expected.

Why do I get "'str' object has no attribute 'read'" when trying to use `json.load` on a string? [duplicate]

This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 29 days ago.
In Python I'm getting an error:
Exception: (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)
Given python code:
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.load(jsonStr)['data']['children']
What does this error mean and what did I do to cause it?
The problem is that for json.load you should pass a file like object with a read function defined. So either you use json.load(response) or json.loads(response.read()).
Ok, this is an old thread but.
I had a same issue, my problem was I used json.load instead of json.loads
This way, json has no problem with loading any kind of dictionary.
Official documentation
json.load - Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads - Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You need to open the file first. This doesn't work:
json_file = json.load('test.json')
But this works:
f = open('test.json')
json_file = json.load(f)
If you get a python error like this:
AttributeError: 'str' object has no attribute 'some_method'
You probably poisoned your object accidentally by overwriting your object with a string.
How to reproduce this error in python with a few lines of code:
#!/usr/bin/env python
import json
def foobar(json):
msg = json.loads(json)
foobar('{"batman": "yes"}')
Run it, which prints:
AttributeError: 'str' object has no attribute 'loads'
But change the name of the variablename, and it works fine:
#!/usr/bin/env python
import json
def foobar(jsonstring):
msg = json.loads(jsonstring)
foobar('{"batman": "yes"}')
This error is caused when you tried to run a method within a string. String has a few methods, but not the one you are invoking. So stop trying to invoke a method which String does not define and start looking for where you poisoned your object.
AttributeError("'str' object has no attribute 'read'",)
This means exactly what it says: something tried to find a .read attribute on the object that you gave it, and you gave it an object of type str (i.e., you gave it a string).
The error occurred here:
json.load(jsonStr)['data']['children']
Well, you aren't looking for read anywhere, so it must happen in the json.load function that you called (as indicated by the full traceback). That is because json.load is trying to .read the thing that you gave it, but you gave it jsonStr, which currently names a string (which you created by calling .read on the response).
Solution: don't call .read yourself; the function will do this, and is expecting you to give it the response directly so that it can do so.
You could also have figured this out by reading the built-in Python documentation for the function (try help(json.load), or for the entire module (try help(json)), or by checking the documentation for those functions on http://docs.python.org .
Instead of json.load() use json.loads() and it would work:
ex:
import json
from json import dumps
strinjJson = '{"event_type": "affected_element_added"}'
data = json.loads(strinjJson)
print(data)
So, don't use json.load(data.read()) use json.loads(data.read()):
def findMailOfDev(fileName):
file=open(fileName,'r')
data=file.read();
data=json.loads(data)
return data['mail']
use json.loads() function , put the s after that ... just a mistake btw i just realized after i searched error
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.loads(jsonStr)['data']['children']
try this
Open the file as a text file first
json_data = open("data.json", "r")
Now load it to dict
dict_data = json.load(json_data)
If you need to convert string to json. Then use loads() method instead of load(). load() function uses to load data from a file so used loads() to convert string to json object.
j_obj = json.loads('["label" : "data"]')

xmlrpc newPaste - expected an object with the buffer interface

in py2 there was
rv = xmlrpc.pastes.newPaste(language, code, None, filename, mimetype, private)
I'm getting error : expected an object with the buffer interface
Can't find any docs about xmlrpc and py3. I found only this snippet :
p1 = subprocess.Popen(['gpg','--clearsign'], stdin = subprocess.PIPE, stdout=subprocess.PIPE)
p1.stdin.write(bytes(input, 'UTF8'))
output = p1.communicate()[0]
s = ServerProxy('http://paste.pocoo.org/xmlrpc/')
pasteid = s.pastes.newPaste('text',output.decode())
print ("http://paste.pocoo.org/raw/",pasteid,"/", sep="")
but I'm still being confused about it... my version used many arguments, where can I find full description of it / fix for it ?
Thank you.
That error message usually means it's looking for str (which is Unicode in Python 3), not bytes . Like in the example, you'll need to decode the argument which is in bytes. Maybe:
rv = xmlrpc.pastes.newPaste(language, code.decode(), None, filename, mimetype, private)
But it's hard to tell what the problem is without seeing your code.
In Python 3. xmlrpclib has been split into two modules, xmlrpc.client and xmlrpc.server.
The docs for 3.2.1 can be found at:
http://docs.python.org/release/3.2.1/library/xmlrpc.client.html
http://docs.python.org/release/3.2.1/library/xmlrpc.server.html

Categories