Sun, 17 Dec 2023 15:33:50 +0100
fix faulty string to int conversion utilities
Probably it was expected that errno is set to EINVAL when illegal characters are encountered. But this is not standard and does not happen on every system, allowing illegal strings to be parsed as valid integers.
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2018 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef WEBDAV_H #define WEBDAV_H #include <inttypes.h> #include <stdbool.h> #include <cx/map.h> #include <cx/mempool.h> #include <cx/linked_list.h> #include <cx/string.h> #include <cx/buffer.h> #include <curl/curl.h> #include <libxml/tree.h> #ifdef __cplusplus extern "C" { #endif typedef char DavBool; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef struct DavContext DavContext; typedef struct DavProxy DavProxy; typedef struct DavSession DavSession; typedef struct DavResource DavResource; typedef struct DavResult DavResult; typedef struct DavNamespace DavNamespace; typedef struct DavProperty DavProperty; typedef struct DavPropName DavPropName; typedef struct DavKey DavKey; typedef struct DavNSInfo DavNSInfo; typedef struct DavXmlNode DavXmlNode; typedef struct DavXmlAttr DavXmlAttr; typedef struct DavInputStream DavInputStream; typedef struct DavOutputStream DavOutputStream; typedef size_t(*dav_read_func)(void*, size_t, size_t, void*); typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*); typedef int(*dav_seek_func)(const void *, long, int); typedef int(*dav_auth_func)(DavSession *, void *); typedef void(*dav_progress_func)(DavResource *, int64_t, int64_t, void *); typedef void(*dav_rqlog_func)( DavSession *sn, const char *method, const char *url, const char *request_body, size_t request_bodylen, int status, const char *response_body, size_t response_bodylen); enum DavError { DAV_OK = 0, DAV_ERROR, DAV_NOT_FOUND, DAV_UNAUTHORIZED, DAV_FORBIDDEN, DAV_METHOD_NOT_ALLOWED, DAV_CONFLICT, DAV_LOCKED, DAV_UNSUPPORTED_PROTOCOL, DAV_COULDNT_RESOLVE_PROXY, DAV_COULDNT_RESOLVE_HOST, DAV_COULDNT_CONNECT, DAV_TIMEOUT, DAV_SSL_ERROR, DAV_QL_ERROR, DAV_CONTENT_VERIFICATION_ERROR, DAV_PRECONDITION_FAILED, DAV_REQUEST_ENTITY_TOO_LARGE, DAV_REQUEST_URL_TOO_LONG, DAV_PROXY_AUTH_REQUIRED, DAV_NET_AUTH_REQUIRED }; typedef enum DavError DavError; enum DavXmlNodeType { DAV_XML_NONE = 0, DAV_XML_ELEMENT, DAV_XML_TEXT }; typedef enum DavXmlNodeType DavXmlNodeType; #define DAV_SESSION_ENCRYPT_CONTENT 0x0001 #define DAV_SESSION_ENCRYPT_NAME 0x0002 #define DAV_SESSION_ENCRYPT_PROPERTIES 0x0004 #define DAV_SESSION_DECRYPT_CONTENT 0x0008 #define DAV_SESSION_DECRYPT_NAME 0x0010 #define DAV_SESSION_DECRYPT_PROPERTIES 0x0020 #define DAV_SESSION_STORE_HASH 0x0040 #define DAV_SESSION_CONTENT_ENCRYPTION 0x0009 #define DAV_SESSION_FULL_ENCRYPTION 0x003f #define DAV_NS "http://davutils.org/" #define DAV_PROPS_NS "http://davutils.org/props/" struct DavNamespace { char *prefix; char *name; }; struct DavResource { DavSession *session; DavResource *prev; DavResource *next; DavResource *parent; DavResource *children; char *name; char *path; char *href; uint64_t contentlength; char *contenttype; time_t creationdate; time_t lastmodified; void *data; int iscollection; int exists; }; struct DavSession { DavContext *context; CURL *handle; char *base_url; CxMempool *mp; CxMap *pathcache; DavKey *key; void *locks; uint32_t flags; DavError error; char *errorstr; int(*auth_prompt)(DavSession *sn, void *userdata); void *authprompt_userdata; dav_rqlog_func logfunc; void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); void *progress_userdata; }; struct DavContext { CxMap *namespaces; CxMap *namespaceinfo; CxMap *keys; CxList *sessions; DavProxy *http_proxy; DavProxy *https_proxy; }; struct DavProxy { char *url; char *username; char *password; char *no_proxy; }; struct DavProperty { DavNamespace *ns; char *name; DavXmlNode *value; }; struct DavPropName { char *ns; char *name; }; struct DavResult { DavResource *result; int status; }; #define DAV_KEY_AES128 0 #define DAV_KEY_AES256 1 struct DavKey { char *name; int type; void *data; size_t length; }; struct DavNSInfo { char *prefix; DavBool encrypt; }; struct DavXmlNode { DavXmlNodeType type; char *namespace; char *name; DavXmlNode *prev; DavXmlNode *next; DavXmlNode *children; DavXmlNode *parent; DavXmlAttr *attributes; char *content; size_t contentlength; }; struct DavXmlAttr { char *name; char *value; DavXmlAttr *next; }; DavContext* dav_context_new(void); void dav_context_destroy(DavContext *ctx); void dav_context_add_key(DavContext *context, DavKey *key); DavKey* dav_context_get_key(DavContext *context, const char *name); int dav_add_namespace(DavContext *context, const char *prefix, const char *ns); DavNamespace* dav_get_namespace(DavContext *context, const char *prefix); DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix); int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt); int dav_namespace_is_encrypted(DavContext *context, const char *ns); DavSession* dav_session_new(DavContext *context, char *base_url); DavSession* dav_session_new_auth( DavContext *context, char *base_url, char *user, char *password); void dav_session_set_auth(DavSession *sn, const char *user, const char *password); void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring password); void dav_session_set_baseurl(DavSession *sn, char *base_url); void dav_session_enable_encryption(DavSession *sn, DavKey *key, int flags); void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata); void dav_session_set_progresscallback(DavSession *sn, dav_progress_func get, dav_progress_func put, void *userdata); void dav_session_destroy(DavSession *sn); void dav_session_destructor(DavSession *sn); void* dav_session_malloc(DavSession *sn, size_t size); void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size); void* dav_session_realloc(DavSession *sn, void *ptr, size_t size); void dav_session_free(DavSession *sn, void *ptr); char* dav_session_strdup(DavSession *sn, const char *str); void dav_set_effective_href(DavSession *sn, DavResource *resource); DavResource* dav_get(DavSession *sn, char *path, const char *properties); CxList* parse_properties_string(DavContext *context, cxstring str); DavResource* dav_query(DavSession *sn, char *query, ...); cxmutstr dav_property_key(const char *ns, const char *name); void dav_get_property_namespace_str( DavContext *ctx, char *prefixed_name, char **ns, char **name); DavNamespace* dav_get_property_namespace( DavContext *ctx, char *prefixed_name, char **name); /* ------------------------ resource functions ------------------------ */ DavResource* dav_resource_new(DavSession *sn, const char *path); DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name); DavResource* dav_resource_new_href(DavSession *sn, const char *href); void dav_resource_free(DavResource *res); void dav_resource_free_all(DavResource *res); char* dav_resource_get_href(DavResource *resource); DavResource* dav_create_child(DavResource *parent, char *name); int dav_delete(DavResource *res); int dav_create(DavResource *res); int dav_exists(DavResource *res); int dav_copy(DavResource *res, char *newpath); int dav_move(DavResource *res, char *newpath); int dav_copy_o(DavResource *res, char *newpath, DavBool override); int dav_move_o(DavResource *res, char *newpath, DavBool override); int dav_copyto(DavResource *res, char *url, DavBool override); int dav_moveto(DavResource *res, char *url, DavBool override); int dav_lock(DavResource *res); int dav_lock_t(DavResource *res, time_t timeout); int dav_unlock(DavResource *res); DavXmlNode* dav_get_property(DavResource *res, char *name); DavXmlNode* dav_get_property_ns(DavResource *res, const char *ns, const char *name); DavXmlNode* dav_get_encrypted_property_ns(DavResource *res, const char *ns, const char *name); char* dav_get_string_property(DavResource *res, char *name); char* dav_get_string_property_ns(DavResource *res, char *ns, char *name); void dav_set_string_property(DavResource *res, char *name, char *value); void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value); void dav_set_property(DavResource *res, char *name, DavXmlNode *value); void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); void dav_remove_property(DavResource *res, char *name); void dav_remove_property_ns(DavResource *res, char *ns, char *name); void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value); void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name); DavPropName* dav_get_property_names(DavResource *res, size_t *count); void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, dav_seek_func seek_func); void dav_set_content_data(DavResource *res, char *content, size_t length); void dav_set_content_length(DavResource *res, size_t length); int dav_load(DavResource *res); int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop); int dav_store(DavResource *res); int dav_get_content(DavResource *res, void *stream, dav_write_func write_func); DavInputStream* dav_inputstream_open(DavResource *res); size_t dav_read(void *buf, size_t size, size_t nitems, DavInputStream *in); void dav_inputstream_close(DavInputStream *in); DavOutputStream* dav_outputstream_open(DavResource *res); size_t dav_write(const void *buf, size_t size, size_t nitems, DavOutputStream *out); int dav_outputstream_close(DavOutputStream *out); void dav_verbose_log( DavSession *sn, const char *method, const char *url, const char *request_body, size_t request_bodylen, int status, const char *response_body, size_t response_bodylen); // private int dav_propfind(DavSession *sn, DavResource *root, CxBuffer *rqbuf); /* --------------------------- DeltaV ---------------------------- */ int dav_versioncontrol(DavResource *res); int dav_checkout(DavResource *res); int dav_checkin(DavResource *res); int dav_uncheckout(DavResource *res); DavResource* dav_versiontree(DavResource *res, char *properties); /* ------------------------ xml functions ------------------------ */ char* dav_xml_getstring(DavXmlNode *node); DavBool dav_xml_isstring(DavXmlNode *node); DavXmlNode* dav_xml_nextelm(DavXmlNode *node); DavXmlNode* dav_text_node(DavSession *sn, const char *text); DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text); DavXmlNode* dav_copy_node(DavXmlNode *node); void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node); void dav_free_xml_node(DavXmlNode *node); DavXmlNode* dav_xml_createnode(const char *ns, const char *name); DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text); DavXmlNode* dav_xml_createtextnode(const char *text); void dav_xml_add_child(DavXmlNode *node, DavXmlNode *child); void dav_xml_add_attr(DavXmlNode *node, const char *name, const char *value); char* dav_xml_get_attr(DavXmlNode *node, const char *name); DavXmlNode* dav_parse_xml(DavSession *sn, const char *str, size_t len); #ifdef __cplusplus } #endif #endif /* WEBDAV_H */