Xcode 13 Warning - [NSKeyedUnarchiver validateAllowedClass:forKey:] - ios15

I am using File Storage system for saving some data models confirming to Codable Protocol.
My Save function is as below:
func save<T: Encodable>(value: T, for key: String, on path: URL) throws {
let url = path.appendingPathComponent(key, isDirectory: false)
do {
try ANFileManager.createDirectoryAtPath(path: url.deletingLastPathComponent())
let archiver = NSKeyedArchiver(requiringSecureCoding: true)
archiver.outputFormat = .binary
try archiver.encodeEncodable(value, forKey: NSKeyedArchiveRootObjectKey)
archiver.finishEncoding()
// then you can use encoded data
try archiver.encodedData.write(to: url)
} catch {
throw StorageError.cantWrite(error)
}
}
My fetch function is as below:
func fetchValue<T: Decodable>(for key: String, from path: URL) throws -> T {
let url = path.appendingPathComponent(key)
let data = try Data(contentsOf: url)
let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver.decodingFailurePolicy = .setErrorAndReturn
guard let decoded = unarchiver.decodeDecodable(T.self, forKey:
NSKeyedArchiveRootObjectKey) else {
throw StorageError.notFound
}
unarchiver.finishDecoding()
if let error = unarchiver.error {
throw StorageError.cantRead(error)
}
else {
return decoded
}
}
Save and fetch are working fine but at runtime seeing some below warning in xcode console.
*** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x7fff863014d0) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework]' for key 'NS.keys', even though it was not explicitly included in the client allowed classes set: '{(
"'NSDictionary' (0x7fff862db9a0) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]",
"'NSDate' (0x7fff862db798) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.
What should be done to suppress the warning ?

The problem is the failure to require secure coding on the unarchiver:
https://developer.apple.com/documentation/foundation/nskeyedunarchiver/1410824-requiressecurecoding
But more broadly it is very odd to pass through a keyed archiver when Codable is already saveable directly.

Related

node:assert:400 throw err; ^ AssertionError [ERR_ASSERTION]: Invalid callback object specified

I'm trying to run node compile.js but it's throwing me this error and idea what I am doing wrong:
node:assert:400 throw err; ^ AssertionError [ERR_ASSERTION]: Invalid callback object specified
my inbox.sol
pragma solidity ^0.8.9;
contract Inbox{
string public message;
function Inbox(string intialMessage) public {
message = intialMessage;
}
function setMessage(string newMessage) public {
message = newMessage;
}
}
my package.json
{
"dependencies": {
"ganache-cli": "^6.12.2",
"mocha": "^9.1.3",
"solc": "^0.8.9",
"web3": "^1.6.0"
}
}
Just rewrite your code like this in 'compile.js'.This work fine even in 0.8.0 version of solidity
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const inboxpath = path.resolve(__dirname, 'Contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxpath, 'UTF-8');
var input = {
language: 'Solidity',
sources: {
'Inbox.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
// console.log(output.contracts['Inbox.sol']['Inbox']);
// exports.abi = output.contracts['Inbox.sol']['Inbox'].abi;
// exports.bytecode = output.contracts['Inbox.sol']['Inbox'].evm.bytecode.object;
That course is outdated, solidity version 0.6.6 is released and you better update your code to that version. if you are not a good programmer you better refund that course, cause you will encounter many problems later on, you will see some errors using meta mask and Web3. that course teachs you a lot, so i really recommend you to keep learning that course and update yourself throughout the course. this is the first problem and the solution to the updated version is this.
this will be your "inbox.sol" code:
pragma solidity ^0.6.6;
contract Inbox{
string public message;
constructor (string memory initialMessage) public{
message = initialMessage;
}
function setMessage(string memory newMessage) public{
message = newMessage;
}
}
and this will be your "compile.js" code:
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const inboxpath = path.resolve(__dirname, 'Contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxpath, 'UTF-8');
var input = {
language: 'Solidity',
sources: {
'Inbox.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
exports.abi = output.contracts['Inbox.sol']['Inbox'].abi;
exports.bytecode = output.contracts['Inbox.sol'] ['Inbox'].evm.bytecode.object;
in the new solidity the compiler will give you another version of compiled code compared to old compiler, so you'll need to pass the json file to your compiler and in order to access to abi(interface) and bytecode you need to do like i did in here.
It will work with solc version 0.4.17.
Just add memory after both string which are present in function's parameters.
function Inbox(string memory initialMessage)...
AND
function setMessage(string memory newMessage)...
For the people who are here for the v0.4.17
Simply update your package.json file solc version to 0.4.17
var output = solc.compile(source,1);
console.log(output)
I guess all you have to do is rollback your complier version. You will get your output. That worked for me.

Can not determine the file type from file content using Node.js

I can not check the what is the file type from file content. I am explaining my code below.
const FileType = require('file-type');
let content = 'eyJ0ZXN0LXNjaGVtYTp0ZXN0LXNjaGVtYSI6eyJuYW1lIjoiYlpuYUpmd0VXdGwiLCJkZXZpY2UiOiJ0ZXN0ZGV2aWNlMCIsImludGVyZmFjZS1pZCI6IlRlbkdpZ0UzLzQvMy82IiwiaW50ZXJmYWNlX2Rlc2NyaXB0aW9uIjoiMkNQMGg5QllmSW1sQkdpWG9DdXRzVzBtTkN3a3U2OFdKOGRncXhCeDhBOU1aRzVsSHl2ZXVCbXNQRmlPQWlSajdOR20xUiIsImludGVyZmFjZV9kZXNjIjoieFlRWHVDOHM2ZCIsInJlZHVuZGFuY3kiOiJpbmRlcGVuZGVudCIsInZsYW4iOjEsImN2bGFuIjo4NTcsImFkZHIiOiIyNTUuMDE3LjIxMC4yNTAiLCJwb2xpY2llcyI6W3sibmFtZSI6InR4NHBoR29yRDROZSIsImJhbmR3aWR0aCI6MjY2MDU2OTU4NiwiYmFuZHdpZHRoLXVuaXQiOiJicHMifV0sInNlY29uZENvbnQiOnsic2Vjb25kT3V0ZXJMaXN0IjpbXX19fQ==';
let stepsRawData = Buffer.from(content, 'base64');
await isFileType(stepsRawData);
isFileType = async (buffer) => {
try{
console.log('filetype',await FileType.fromBuffer(buffer));
}catch(err) {
return false;
}
}
Here I am using file-type module to check what is the file type. I have some base64 encoded file content and I need to check what type(i.e- json/xml/txt) of file content this. But as per my code this console message is showing filetype undefined. Here I need to determine the file type from encoded file content.Can any body help me to fix this problem ?
isFileType = async (buffer) => {
try {
console.log('filetype', await FileType.fromBuffer(Buffer.from(buffer, 'base64')));
} catch(err) {
return false;
}
}

How to unpack an google.protobuf.Any type in gRPC nodejs client?

My protobuf file is like this:
syntax = "proto3"; import "google/protobuf/any.proto";
service RoomService {
getTestAny (Hotelid) returns (google.protobuf.Any); }
message Hotelid {
string hotelid = 1;
}
message HtlInDate {
Hotelid hotelid = 1;
string date = 2;
}
My java-gRPC-server code is like that:
#Override
public void getTestAny(Roomservice.Hotelid request, StreamObserver<Any> responseObserver) {
Roomservice.Hotelid hotelid = Roomservice.Hotelid.newBuilder()
.setHotelid("This is Hotelid")
.build();
Roomservice.HtlInDate htlDate = Roomservice.HtlInDate.newBuilder()
.setHotelid(hotelid)
.setDate("This is Data")
.build();
responseObserver.onNext(Any.pack(htlDate));
responseObserver.onCompleted();
}
And I make a request from a nodejs-gRPC-client, which code is like that:
function () {
var client = new services.RoomServiceClient('localhost:6565',
grpc.credentials.createInsecure());
var request = new messages.Hotelid();
var hotelid = "ignore";
request.setHotelid(hotelid);
var call = client.getTestAny(request, function (err, response) {
var obj = response.toObject();
console.log(obj);
});
}
The response in nodejs-gRPC-client is a type of Any. And it contains a data array:
array:["type.googleapis.com/HtlInDate", Uint8Array[10,17,10...]]
I try to use response.toObject() to get HtlInDate instance but I just get like this:
obj:{
typeUrl:"type.googleapis.com/HtlInDate",
value:"ChEKD1RoaXMgaXMgSG90ZWxpZBIMVGhpcyBpcyBEYXRh"
}
So how can I unpack the Any type response and get the HtlInDate instance exactly? Thanks a lot if you have any idea about this!
Currently, the google.protobuf.Any type is not supported in Node.js, either in Protobuf.js, which gRPC uses by default, or by google-protobuf, which is the official first party protobuf implementation.
From documentation:
https://developers.google.com/protocol-buffers/docs/reference/javascript-generated#message
// Storing an arbitrary message type in Any.
const status = new proto.foo.ErrorStatus();
const any = new Any();
const binarySerialized = ...;
any.pack(binarySerialized, 'foo.Bar');
console.log(any.getTypeName()); // foo.Bar
// Reading an arbitrary message from Any.
const bar = any.unpack(proto.foo.Bar.deserializeBinary, 'foo.Bar');
Please take a note that for browser support you need to use webpack(probably with babel loader) or browserify
As found in google-protobuf tests Any is bundled with pack and unpack functions.
Your code could be unpacked like this:
function () {
var client = new services.RoomServiceClient('localhost:6565',
grpc.credentials.createInsecure());
var request = new messages.Hotelid();
var hotelid = "ignore";
request.setHotelid(hotelid);
var call = client.getTestAny(request, function (err, response) {
var obj = response.toObject();
console.log('Any content', obj);
var date = response.unpack(messages.HtlInDate.deserializeBinary, response.getTypeName());
console.log('HtlInDate', date.toObject());
});
}
This will deserialize the bytes received in the Any object.
You could also build some Any using pack function for wrapping TypeUrl and Value:
var someAny = new Any();
someAny.pack(date.serializeBinary(), 'HtlInDate')

how to upload a file in vibe.d using the web framework

I am still new to Vibe.d so forgive me if I am missing something obvious.
I want to upload a file in Vibe.d using the web framework. However, all the examples I find, including the one in the book 'D Web Development', are not using the web framework. If I insert the non-web-framework example to my app, it crashes. It would suck if I have to abandon the web framework just for the sake of one feature, which is file upload.
The Vibe.d documentation is a good effort and I appreciate it but until now it is rather sparse and the examples are few and far between.
Here are some snippets of my code:
shared static this()
{
auto router = new URLRouter;
router.post("/upload", &upload);
router.registerWebInterface(new WebApp);
//router.get("/", staticRedirect("/index.html"));
//router.get("/ws", handleWebSockets(&handleWebSocketConnection));
router.get("*", serveStaticFiles("public/"));
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];
listenHTTP(settings, router);
conn = connectMongoDB("127.0.0.1");
appStore = new WebAppStore;
}
void upload(HTTPServerRequest req, HTTPServerResponse res)
{
auto f = "filename" in req.files;
try
{
moveFile(f.tempPath, Path("./public/uploaded/images") ~ f.filename);
}
catch(Exception e)
{
copyFile(f.tempPath, Path("./public/uploaded/images") ~ f.filename);
}
res.redirect("/uploaded");
}
Can I still access the HTTPServerRequest.files using the web framework? How? Or do I still need it? Meaning, is there another way without using HTTPServerRequest.files?
Thanks a lot!
I have totally forgotten about this question. I remember how frustrating it was when you cannot readily find an answer to a question that seems to be elementary to those who already know.
Make sure you state 'multipart/form-data' in the enctype of your form:
form(method="post", action="new_employee", enctype="multipart/form-data")
Then a field in that form should include an input field of type 'file', something like this:
input(type="file", name="picture")
In the postNewEmployee() method of your web framework class, get the file through request.files:
auto pic = "picture" in request.files;
Here is a sample postNewEmployee() method being passed an Employee struct:
void postNewEmployee(Employee emp)
{
Employee e = emp;
string photopath = "No photo submitted";
auto pic = "picture" in request.files;
if(pic !is null)
{
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath));
}
}
e.photo = photopath;
empModel.addEmployee(e);
redirect("list_employees");
}
When I tried to learn Vibe.d again, I again became aware of the dearth of tutorials, so I wrote a tutorial myself while everything is fresh as a learner:
https://github.com/reyvaleza/vibed
Hope you find this useful.
Put the upload function inside the WebApp class and use it to handle the form post form(action="/upload", method ="post")
class WebApp {
addUpload(HTTPServerRequest req, ...)
{
auto file = file in req.files;
...
}
}
You can try hunt-framework, Hunt Framework is a high-level D Programming Language Web framework that encourages rapid development and clean, pragmatic design. It lets you build high-performance Web applications quickly and easily.
Sample code for action:
#Action
string upload()
{
string message;
if (request.hasFile("file1"))
{
auto file = request.file("file1");
if (file.isValid())
{
// File save path: file.path()
// Origin name: file.originalName()
// File extension: file.extension()
// File mimetype: file.mimeType()
if (file.store("uploads/myfile.zip"))
{
message = "upload is successed";
}
else
{
message = "save as error";
}
}
else
{
message = "file is not valid";
}
}
else
{
message = "not get this file";
}
return message;
}

core data crashed when save it to a directory created by myself in LibraryDirectory

here is my code thar return a directory to save core data files.
lazy var applicationDocumentsDirectory: NSString = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.triplec.WKCC" in the application's documents Application Support directory.
var libP = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true).first! as NSString
let path = libP.stringByAppendingPathComponent("coredata") as String
let fileManager = NSFileManager.defaultManager()
if fileManager.fileExistsAtPath(path) {
do {
try fileManager.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil)
} catch { }
}
print(path)
return path as NSString
}()
when I called function below, it crashed. The crash log says that the file couldn’t be saved.
let url = NSURL.fileURLWithPath(self.applicationDocumentsDirectory.stringByAppendingPathComponent("SingleViewCoreData.sqlite"))
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
abort()
}
And when I did't append string to libP, it did work。
Anyone knows how to save core data files in a diretory created by myself?
You haven't even tested your code that's supposed to create the directory to see if it works. This code:
if fileManager.fileExistsAtPath(path) {
do {
try fileManager.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil)
} catch { }
}
...says that if the directory already exists then create it. But if the directory doesn't exist, do nothing.

Resources