Skip to content

Commit

Permalink
Merge pull request #192 from blade-lang/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
mcfriend99 authored Sep 27, 2024
2 parents 455d62a + 7580b9c commit 821f957
Show file tree
Hide file tree
Showing 19 changed files with 183 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [ main, dev, imagine ]
branches: [ dev, imagine ]
pull_request:
branches: [ main ]

Expand Down
3 changes: 2 additions & 1 deletion libs/template/index.b
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,9 @@ class Template {
for key, value in data {
if value_name for_vars.set('${value_name}', value)
if key_name for_vars.set('${key_name}', key)
result.append(
self._process(path, json.decode(json.encode(element)), for_vars)
self._process(path, element.clone(), for_vars)
)
}
}
Expand Down
84 changes: 78 additions & 6 deletions packages/ssl/ssl.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
#include <blade.h>
#ifdef _WIN32 // wrapping to disable annoying messages from getopt.h in ming2
#define message(ignore)
#endif
#include <unistd.h>
#ifdef _WIN32
#undef message
#endif
#include "ssl.h"

#ifdef _WIN32
# define _WINSOCK_DEPRECATED_NO_WARNINGS 1
# include <winsock2.h>
# include <sdkddkver.h>
# include <ws2tcpip.h>

# define sleep _sleep
# define ioctl ioctlsocket
#else
# include <sys/socket.h>
# include <sys/ioctl.h>
#endif

DEFINE_SSL_CONSTANT(SSL_FILETYPE_PEM)
DEFINE_SSL_CONSTANT(SSL_FILETYPE_ASN1)

Expand Down Expand Up @@ -142,6 +161,15 @@ DECLARE_MODULE_METHOD(ssl_set_accept_state) {
RETURN;
}

DECLARE_MODULE_METHOD(ssl_set_tlsext_host_name) {
ENFORCE_ARG_COUNT(set_tlsext_host_name, 2);
ENFORCE_ARG_TYPE(set_tlsext_host_name, 0, IS_PTR);
ENFORCE_ARG_TYPE(set_tlsext_host_name, 1, IS_STRING);

SSL *ssl = (SSL*)AS_PTR(args[0])->pointer;
RETURN_BOOL(SSL_set_tlsext_host_name(ssl, AS_C_STRING(args[1])) == 0);
}

DECLARE_MODULE_METHOD(ssl_new_bio) {
ENFORCE_ARG_COUNT(new_bio, 1);
ENFORCE_ARG_TYPE(new_bio, 0, IS_PTR);
Expand Down Expand Up @@ -359,19 +387,59 @@ DECLARE_MODULE_METHOD(ssl_read) {
char buffer[1025];
ERR_clear_error();

int ssl_fd = SSL_get_fd(ssl);

fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(ssl_fd, &read_fds);

// struct timeval timeout = { .tv_sec = 0, .tv_usec = 500000 };

struct timeval timeout;
int option_length = sizeof(timeout);

#ifndef _WIN32
int rc = getsockopt(ssl_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, (socklen_t *) &option_length);
#else
int rc = getsockopt(ssl_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, (socklen_t*)&option_length);
#endif // !_WIN32

if (rc != 0 || sizeof(timeout) != option_length || (timeout.tv_sec == 0 && timeout.tv_usec == 0)) {
// set default timeout to 0.5 seconds
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
}

int ret = select(ssl_fd + 1, &read_fds, NULL, NULL, &timeout);
if (ret == 0) {
free(data);
RETURN_STRING("");
} else if (ret < 0) {
// Error
}

do {
int bytes = SSL_read(ssl, buffer, 1024);
int read_count = length == -1 ? 1024 : (
(length - total) < 1024 ? (length - total) : 1024
);

int bytes = SSL_read(ssl, buffer, read_count);
// printf("READ COUNT = %d, TOTAL: %d, LENGTH = %d, BYTE = %d\n", read_count, total, length, bytes);

if(bytes > 0) {
data = GROW_ARRAY(char, data,total, total + bytes);
data = GROW_ARRAY(char, data, total, total + bytes + 1);
if(data == NULL) {
RETURN_ERROR("device out of memory.");
}

vm->bytes_allocated += bytes;
memcpy(data + total, buffer, bytes);
total += bytes;
data[total] = '\0';

if(total > length && length != -1) break;
if(total >= length && length != -1) break;
if((bytes == 1024 && length == -1)) {
continue;
}
} else {
int error = SSL_get_error(ssl, bytes);
if(error == SSL_ERROR_WANT_READ) {
Expand Down Expand Up @@ -470,7 +538,8 @@ DECLARE_MODULE_METHOD(ssl_error_string) {
SSL *ssl = (SSL*)AS_PTR(args[0])->pointer;
int code = SSL_get_error(ssl, ret);
if(code != SSL_ERROR_SYSCALL) {
const char *err = ERR_reason_error_string(ERR_get_error());
// const char *err = ERR_reason_error_string(ERR_get_error());
char *err = ossl_err_as_string();
RETURN_STRING(err);
} else {
char *error = strerror(errno);
Expand All @@ -497,10 +566,12 @@ DECLARE_MODULE_METHOD(ssl_connect) {
res = SSL_connect(ssl);
int error = SSL_get_error(ssl, res);
if(error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE && error != SSL_ERROR_WANT_CONNECT) {
if(error == SSL_ERROR_SSL || error == SSL_ERROR_SYSCALL) {
RETURN_SSL_ERROR();
}
break;
}
} while(res == -1);

RETURN_BOOL(res > 0);
}

Expand Down Expand Up @@ -628,6 +699,7 @@ CREATE_MODULE_LOADER(ssl) {
{"ssl_free", true, GET_MODULE_METHOD(ssl_ssl_free)},
{"set_connect_state", true, GET_MODULE_METHOD(ssl_set_connect_state)},
{"set_accept_state", true, GET_MODULE_METHOD(ssl_set_accept_state)},
{"set_tlsext_host_name", true, GET_MODULE_METHOD(ssl_set_tlsext_host_name)},
{"new_bio", true, GET_MODULE_METHOD(ssl_new_bio)},
{"set_ssl", true, GET_MODULE_METHOD(ssl_bio_set_ssl)},
{"set_conn_hostname", true, GET_MODULE_METHOD(ssl_set_conn_hostname)},
Expand Down
12 changes: 6 additions & 6 deletions packages/ssl/ssl/context.b
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class TLSContext < SSLContext {
* @constructor
*/
TLSContext() {
parent(TLS_method)
parent(_ssl.TLS_method())
}
}

Expand All @@ -121,7 +121,7 @@ class TLSClientContext < SSLContext {
* @constructor
*/
TLSClientContext() {
parent(TLS_client_method)
parent(_ssl.TLS_client_method())
}
}

Expand All @@ -136,7 +136,7 @@ class TLSServerContext < SSLContext {
* @constructor
*/
TLSServerContext() {
parent(TLS_server_method)
parent(_ssl.TLS_server_method())
}
}

Expand All @@ -150,7 +150,7 @@ class SSLv23Context < SSLContext {
* @constructor
*/
SSLv23Context() {
parent(SSLv23_method)
parent(_ssl.SSLv23_method())
}
}

Expand All @@ -165,7 +165,7 @@ class SSLv23ClientContext < SSLContext {
* @constructor
*/
SSLv23ClientContext() {
parent(SSLv23_client_method)
parent(_ssl.SSLv23_client_method())
}
}

Expand All @@ -180,6 +180,6 @@ class SSLv23ServerContext < SSLContext {
* @constructor
*/
SSLv23ServerContext() {
parent(SSLv23_server_method)
parent(_ssl.SSLv23_server_method())
}
}
3 changes: 1 addition & 2 deletions packages/ssl/ssl/socket.b
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class TLSSocket {
if !context self._context = SSLContext(TLS_method)
else self._context = context

self._ssl = ssl
self._ssl = ssl ? ssl : SSL(self._context)
}

/**
Expand All @@ -165,7 +165,6 @@ class TLSSocket {
*/
connect(host, port, timeout) {
if self._socket.connect(host, port, timeout) {
self._ssl = SSL(self._context)
if self._ssl.set_fd(self._socket.id) {
return self._ssl.connect()
}
Expand Down
26 changes: 26 additions & 0 deletions packages/ssl/ssl/ssl.b
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,21 @@ class SSL {
* Connects to an SSL server instance.
*
* @return bool
* @throws
*/
connect() {
/* try {
var res = _ssl.connect(self._ptr)
return res
} catch Exception e {
if e.message.index_of('eof while reading') {
die Exception('timeout')
}

die e
} */

# _ssl.set_connect_state(self._ptr)
return _ssl.connect(self._ptr)
}

Expand Down Expand Up @@ -134,6 +147,19 @@ class SSL {
_ssl.shutdown(self._ptr)
}

/**
* Sets the Server Name Indication (SNI) for use by Secure Sockets
* Layer (SSL). This function should be called on a client SSL
* session before the TLS handshake for the SNI extension
* to be set properly.
*
* @param string name
* @return bool
*/
set_tlsext_host_name(name) {
return _ssl.set_tlsext_host_name(self._ptr, name)
}

/**
* Frees this SSL and all associated resources.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/blade.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,11 @@ int main(int argc, char *argv[]) {
char **std_args = (char**)calloc(opt_deviation, sizeof(char *));
if(std_args != NULL) {
if(optind > 0) {
std_args[0] = strdup(argv[0]);
std_args[0] = argv[0];
}

for(int i = optind; i < argc; i++) {
std_args[i - optind + 1] = strdup(argv[i]);
std_args[i - optind + 1] = argv[i];
}

vm->std_args = std_args;
Expand Down
8 changes: 4 additions & 4 deletions src/bstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,13 +973,13 @@ DECLARE_STRING_METHOD(split) {
if ((int)compile_options == -1) {
// not a regex, do a regular split
if (delimeter->length > 0) {
int start = 0;
for(int i = 0; i <= string->length; i++) {
// int start = 0;
for(int start = 0, i = 0; i <= string->length; i++) {
// match found.
if(memcmp(string->chars + i, delimeter->chars, delimeter->length) == 0 || i == string->length) {
write_list(vm, list, STRING_L_VAL(string->chars + start, i - start));
i += delimeter->length - 1;
start = i + 1;
i += delimeter->length;
start = i;
}
}
} else {
Expand Down
24 changes: 18 additions & 6 deletions src/bytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,32 @@ DECLARE_BYTES_METHOD(extend) {

DECLARE_BYTES_METHOD(index_of) {
ENFORCE_ARG_RANGE(index_of, 1, 2);
ENFORCE_ARG_TYPE(index_of, 0, IS_NUMBER);
ENFORCE_ARG_TYPES(index_of, 0, IS_NUMBER, IS_BYTES);
b_obj_bytes *bytes = AS_BYTES(METHOD_OBJECT);
uint8_t needle = AS_NUMBER(args[0]);

int start_index = 0;
if(arg_count == 2) {
ENFORCE_ARG_TYPE(index_of, 1, IS_NUMBER);
start_index = AS_NUMBER(args[1]);
}

if(bytes->bytes.count > 0 && start_index >= 0 && start_index < bytes->bytes.count - 1) {
for (int i = start_index; i < bytes->bytes.count; i++) {
if (bytes->bytes.bytes[i] == needle) {
RETURN_NUMBER(i);
if(IS_NUMBER(args[0])) {
uint8_t needle = AS_NUMBER(args[0]);
if(bytes->bytes.count > 0 && start_index >= 0 && start_index < bytes->bytes.count - 1) {
for (int i = start_index; i < bytes->bytes.count; i++) {
if (bytes->bytes.bytes[i] == needle) {
RETURN_NUMBER(i);
}
}
}
} else {
b_obj_bytes *needle = AS_BYTES(args[0]);

if(bytes->bytes.count > 0 && start_index >= 0 && start_index < bytes->bytes.count - 1) {
for (int i = start_index; i < bytes->bytes.count; i++) {
if (memcmp(bytes->bytes.bytes + i, needle->bytes.bytes, needle->bytes.count) == 0) {
RETURN_NUMBER(i);
}
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2147,6 +2147,7 @@ static void import_statement(b_parser *p) {
emit_byte_and_short(p, OP_NATIVE_MODULE, module);

parse_specific_import(p, module_name, module, false, true);
free(module_name);
return;
}

Expand Down Expand Up @@ -2191,10 +2192,13 @@ static void import_statement(b_parser *p) {
pop(p->vm);

parse_specific_import(p, module_name, module, false, true);
free(module_name);
return;
}

free(module_path);
free(module_file);
free(module_name);
error(p, "module not found");
return;
}
Expand All @@ -2207,6 +2211,7 @@ static void import_statement(b_parser *p) {
char *source = read_file(module_path);
if (source == NULL) {
error(p, "could not read import file %s", module_path);
free(module_file);
return;
}

Expand All @@ -2220,6 +2225,7 @@ static void import_statement(b_parser *p) {

if (function == NULL) {
error(p, "failed to import %s", module_name);
free(module_file);
return;
}

Expand All @@ -2237,6 +2243,7 @@ static void import_statement(b_parser *p) {
register_module__FILE__(p->vm, module);

parse_specific_import(p, module_name, import_constant, was_renamed, false);
free(module_file);
}

static void assert_statement(b_parser *p) {
Expand Down
2 changes: 1 addition & 1 deletion src/dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ DECLARE_DICT_METHOD(clone) {
b_obj_dict *dict = AS_DICT(METHOD_OBJECT);
b_obj_dict *n_dict = (b_obj_dict *) GC(new_dict(vm));

table_add_all(vm, &dict->items, &n_dict->items);
table_copy(vm, &dict->items, &n_dict->items);

for (int i = 0; i < dict->names.count; i++) {
write_value_arr(vm, &n_dict->names, dict->names.values[i]);
Expand Down
Loading

0 comments on commit 821f957

Please sign in to comment.