From 8efcf9e5bf959faaea41457f400e9ab74a147eb5 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 11:06:26 +1000 Subject: [PATCH 01/16] Make src/vsgi/vsgi-request.vala non-null compliant Non-obvious changes: * Line 131: valac chokes on using different types for the comparison to the return with the ternary operator. No idea why. * Line 156: Looking at https://github.com/GNOME/libsoup/blob/master/libsoup/soup-headers.c#L462 it doesn't seem as though header_parse_list() will push a null value onto the SList, so remove the null check. Instead, test whether Soup.Cookie.parse returned a valid result. --- src/vsgi/vsgi-request.vala | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vsgi/vsgi-request.vala b/src/vsgi/vsgi-request.vala index b2bf1a443..5e16be046 100644 --- a/src/vsgi/vsgi-request.vala +++ b/src/vsgi/vsgi-request.vala @@ -127,7 +127,9 @@ namespace VSGI { * @return the corresponding value if found, otherwise 'null' */ public string? lookup_query (string key) { - return query == null ? null : query[key]; + if (query == null) + return null; + return ((!) query)[key]; } /** @@ -144,15 +146,17 @@ namespace VSGI { */ public SList cookies { owned get { - var cookies = new SList (); - var cookie_list = headers.get_list ("Cookie"); + var cookies = new SList (); + string? cookie_list = headers.get_list ("Cookie"); if (cookie_list == null) return cookies; - foreach (var cookie in header_parse_list (cookie_list)) - if (cookie != null) - cookies.prepend (Cookie.parse (cookie, uri)); + foreach (var cookie in header_parse_list ((!) cookie_list)) { + Soup.Cookie? parsed_cookie = Cookie.parse (cookie, uri); + if (parsed_cookie != null) + cookies.prepend ((!) parsed_cookie); + } cookies.reverse (); @@ -224,7 +228,7 @@ namespace VSGI { */ public InputStream body { get { - return _body ?? this.connection.input_stream; + return (!) (_body ?? this.connection.input_stream); } } @@ -247,7 +251,7 @@ namespace VSGI { } else { headers.set_encoding (Soup.Encoding.EOF); } - _body = new ConverterInputStream (_body ?? connection.input_stream, converter); + _body = new ConverterInputStream ((!) (_body ?? connection.input_stream), converter); } /** From 8037fbfb678c29770618b90896c3c2ec6621093c Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 11:14:25 +1000 Subject: [PATCH 02/16] Make src/vsgi/vsgi-response.vala non-null compliant * Changed line 70 in line with previous commit * Type cast on line 281 to get around incorrect function signatures on old VAPIs --- src/vsgi/vsgi-response.vala | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/vsgi/vsgi-response.vala b/src/vsgi/vsgi-response.vala index 86022e6cf..bba1aae72 100644 --- a/src/vsgi/vsgi-response.vala +++ b/src/vsgi/vsgi-response.vala @@ -61,15 +61,17 @@ namespace VSGI { */ public SList cookies { owned get { - var cookies = new SList (); - var cookie_list = headers.get_list ("Set-Cookie"); + var cookies = new SList (); + string? cookie_list = headers.get_list ("Set-Cookie"); if (cookie_list == null) return cookies; - foreach (var cookie in header_parse_list (cookie_list)) - if (cookie != null) - cookies.prepend (Cookie.parse (cookie, request.uri)); + foreach (var cookie in header_parse_list ((!) cookie_list)) { + Soup.Cookie? parsed_cookie = Cookie.parse (cookie, request.uri); + if (parsed_cookie != null) + cookies.prepend ((!) parsed_cookie); + } cookies.reverse (); @@ -127,7 +129,7 @@ namespace VSGI { warning ("could not write the head in the connection stream: %s", err.message); } - return _body ?? this.request.connection.output_stream; + return (!) (_body ?? this.request.connection.output_stream); } } @@ -168,7 +170,7 @@ namespace VSGI { head.append_printf ("HTTP/%s %u %s\r\n", this.request.http_version == HTTPVersion.@1_0 ? "1.0" : "1.1", status, - reason_phrase ?? Status.get_phrase (status)); + (!) (reason_phrase ?? Status.get_phrase (status))); // headers this.headers.foreach ((name, header) => { @@ -263,7 +265,8 @@ namespace VSGI { } else { headers.set_encoding (Soup.Encoding.EOF); } - _body = new ConverterOutputStream (_body ?? request.connection.output_stream, converter); + _body = new ConverterOutputStream ((!) (_body ?? request.connection.output_stream), + converter); } /** @@ -275,7 +278,7 @@ namespace VSGI { * @since 0.3 */ public bool expand (uint8[] buffer, Cancellable? cancellable = null) throws IOError { - if (headers.get_list ("Content-Encoding") == null) { + if ((string?) headers.get_list ("Content-Encoding") == null) { headers.set_content_length (buffer.length); } size_t bytes_written; From f1070a21c1ccb5d76b713c454c0b7d40266b0bda Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 11:23:22 +1000 Subject: [PATCH 03/16] Make src/vsgi/vsgi-server.vala non-null compliant Non-obvious changes: * Line 73: Using the `new` operator to init the OptionEntry array nets us a null-terminated array, avoiding issues with the OptionEntry binding --- src/vsgi/vsgi-server.vala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vsgi/vsgi-server.vala b/src/vsgi/vsgi-server.vala index ad7cd99d5..2956cf295 100644 --- a/src/vsgi/vsgi-server.vala +++ b/src/vsgi/vsgi-server.vala @@ -70,11 +70,9 @@ namespace VSGI { ApplicationFlags.SEND_ENVIRONMENT | ApplicationFlags.NON_UNIQUE; #if GIO_2_40 - const OptionEntry[] entries = { - // general options - {"forks", 0, 0, OptionArg.INT, null, "Number of fork to create", "0"}, - {null} - }; + // general options + var entries = new OptionEntry[1]; + entries[0] = {"forks", 0, 0, OptionArg.INT, null, "Number of fork to create", "0"}; this.add_main_option_entries (entries); #endif } @@ -100,7 +98,7 @@ namespace VSGI { foreach (var uri in uris) { command_line.printerr ("master:\t\tlistening on '%s'\n", uri.to_string (false)[0:-uri.path.length]); } - var remaining = options.lookup_value ("forks", VariantType.INT32).get_int32 (); + var remaining = ((!) options.lookup_value ("forks", VariantType.INT32)).get_int32 (); for (var i = 0; i < remaining; i++) { var pid = fork (); if (pid == 0) { From c1939a768bbe907a74868344f327537bdf5a57cf Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 11:30:01 +1000 Subject: [PATCH 04/16] Make src/vsgi/vsgi-socket-listener-server.vala non-null compliant This commit edits the OptionEntry setup at line 50-ish, in line with the previous commit. --- src/vsgi/vsgi-socket-listener-server.vala | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/vsgi/vsgi-socket-listener-server.vala b/src/vsgi/vsgi-socket-listener-server.vala index 68a8a3108..a45628192 100644 --- a/src/vsgi/vsgi-socket-listener-server.vala +++ b/src/vsgi/vsgi-socket-listener-server.vala @@ -45,20 +45,18 @@ public abstract class VSGI.SocketListenerServer : Server { #if GIO_2_40 construct { - const OptionEntry[] options = { - {"any", 'a', 0, OptionArg.NONE, null, "Listen on any open TCP port"}, - {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port"}, - {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor", "0"}, - {"backlog", 'b', 0, OptionArg.INT, null, "Listen queue depth used in the listen() call", "10"}, - {null} - }; + var options = new OptionEntry[4]; + options[0] = {"any", 'a', 0, OptionArg.NONE, null, "Listen on any open TCP port"}; + options[1] = {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port"}; + options[2] = {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor", "0"}; + options[3] = {"backlog", 'b', 0, OptionArg.INT, null, "Listen queue depth used in the listen() call", "10"}; this.add_main_option_entries (options); } #endif public override void listen (Variant options) throws Error { - var backlog = options.lookup_value ("backlog", VariantType.INT32) ?? new Variant.@int32 (10); + var backlog = (!) (options.lookup_value ("backlog", VariantType.INT32) ?? new Variant.@int32 (10)); listener.set_backlog (backlog.get_int32 ()); @@ -67,12 +65,12 @@ public abstract class VSGI.SocketListenerServer : Server { _uris.append (new Soup.URI ("%s://0.0.0.0:%u/".printf (protocol, port))); _uris.append (new Soup.URI ("%s://[::]:%u/".printf (protocol, port))); } else if (options.lookup_value ("port", VariantType.INT32) != null) { - var port = (uint16) options.lookup_value ("port", VariantType.INT32).get_int32 (); + var port = (uint16) ((!) options.lookup_value ("port", VariantType.INT32)).get_int32 (); listener.add_inet_port (port, null); _uris.append (new Soup.URI ("%s://0.0.0.0:%u/".printf (protocol, port))); _uris.append (new Soup.URI ("%s://[::]:%u/".printf (protocol, port))); } else if (options.lookup_value ("file-descriptor", VariantType.INT32) != null) { - var file_descriptor = options.lookup_value ("file-descriptor", VariantType.INT32).get_int32 (); + var file_descriptor = ((!) options.lookup_value ("file-descriptor", VariantType.INT32)).get_int32 (); listener.add_socket (new Socket.from_fd (file_descriptor), null); _uris.append (new Soup.URI ("%s+fd://%u/".printf (protocol, file_descriptor))); } else { From 89467cd9a0b6e7264db3007970cf13d58842ee6f Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 12:23:56 +1000 Subject: [PATCH 05/16] Make src/vsgi-http/vsgi-http.vala non-null compliant Fiddle with OptionEntry-related lines from 200 onwards to get the compile working, as in previous commits. Unlike previous commits, however, this screws up the option order to fit into the `if soup` macros. Otherwise, just the usual syntax amendments. --- src/vsgi-http/vsgi-http.vala | 61 +++++++++++++++++------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/vsgi-http/vsgi-http.vala b/src/vsgi-http/vsgi-http.vala index 3506d5406..c32016240 100644 --- a/src/vsgi-http/vsgi-http.vala +++ b/src/vsgi-http/vsgi-http.vala @@ -126,7 +126,7 @@ namespace VSGI.HTTP { public override string? reason_phrase { owned get { return this.message.reason_phrase; } - set { this.message.reason_phrase = value ?? Status.get_phrase (this.message.status_code); } + set { this.message.reason_phrase = (!) (value ?? Status.get_phrase (this.message.status_code)); } } public override MessageHeaders headers { @@ -169,7 +169,7 @@ namespace VSGI.HTTP { get { #if SOUP_2_48 if (server != null) - _uris = server.get_uris (); + _uris = ((!) server).get_uris (); #endif return _uris; } @@ -184,35 +184,32 @@ namespace VSGI.HTTP { construct { #if GIO_2_40 - const OptionEntry[] entries = { - // port options - {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port", "3003"}, + var entries = new OptionEntry[ #if SOUP_2_48 - {"all", 'a', 0, OptionArg.NONE, null, "Listen on all interfaces '--port'"}, - {"ipv4-only", '4', 0, OptionArg.NONE, null, "Only listen on IPv4 interfaces"}, - {"ipv6-only", '6', 0, OptionArg.NONE, null, "Only listen on IPv6 interfaces"}, - - // fd options - {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor"}, - - // https options - {"https", 0, 0, OptionArg.NONE, null, "Listen for HTTPS connections rather than plain HTTP"}, + 10 +#else + 5 #endif - {"ssl-cert-file", 0, 0, OptionArg.FILENAME, null, "Path to a file containing a PEM-encoded certificate"}, - {"ssl-key-file", 0, 0, OptionArg.FILENAME, null, "Path to a file containing a PEM-encoded private key"}, + ]; + entries[0] = {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port", "3003"}; + entries[1] = {"ssl-cert-file", 0, 0, OptionArg.FILENAME, null, "Path to a file containing a PEM-encoded certificate"}; + entries[2] = {"ssl-key-file", 0, 0, OptionArg.FILENAME, null, "Path to a file containing a PEM-encoded private key"}; + entries[3] = {"server-header", 'h', 0, OptionArg.STRING, null, "Value to use for the 'Server' header on Messages processed by this server"}; + entries[4] = {"raw-paths", 0, 0, OptionArg.NONE, null, "Percent-encoding in the Request-URI path will not be automatically decoded"}; +#if SOUP_2_4 + entries[5] = {"all", 'a', 0, OptionArg.NONE, null, "Listen on all interfaces '--port'"}; + entries[6] = {"ipv4-only", '4', 0, OptionArg.NONE, null, "Only listen on IPv4 interfaces"}; + entries[7] = {"ipv6-only", '6', 0, OptionArg.NONE, null, "Only listen on IPv6 interfaces"}; + entries[8] = {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor"}; + entries[9] = {"https", 0, 0, OptionArg.NONE, null, "Listen for HTTPS connections rather than plain HTTP"}; - // headers options - {"server-header", 'h', 0, OptionArg.STRING, null, "Value to use for the 'Server' header on Messages processed by this server"}, - {"raw-paths", 0, 0, OptionArg.NONE, null, "Percent-encoding in the Request-URI path will not be automatically decoded"}, - - {null} - }; +#endif this.add_main_option_entries (entries); #endif } public override void listen (Variant options) throws Error { - var port = options.lookup_value ("port", VariantType.INT32) ?? new Variant.@int32 (3003); + var port = (!) (options.lookup_value ("port", VariantType.INT32) ?? new Variant.@int32 (3003)); if (options.lookup_value ("https", VariantType.BOOLEAN) != null) { if (options.lookup_value ("ssl-cert-file", VariantType.BYTESTRING) == null || @@ -220,8 +217,8 @@ namespace VSGI.HTTP { throw new HTTPError.FAILED ("both '--ssl-cert-file' and '--ssl-key-file' must be provided"); } - var tls_certificate = new TlsCertificate.from_files (options.lookup_value ("ssl-cert-file", VariantType.BYTESTRING).get_bytestring (), - options.lookup_value ("ssl-key-file", VariantType.BYTESTRING).get_bytestring ()); + var tls_certificate = new TlsCertificate.from_files (((!) options.lookup_value ("ssl-cert-file", VariantType.BYTESTRING)).get_bytestring (), + ((!) options.lookup_value ("ssl-key-file", VariantType.BYTESTRING)).get_bytestring ()); this.server = new Soup.Server ( #if !SOUP_2_48 @@ -240,10 +237,10 @@ namespace VSGI.HTTP { } if (options.lookup_value ("server-header", VariantType.STRING) != null) - this.server.server_header = options.lookup_value ("server-header", VariantType.STRING).get_string (); + ((!) this.server).server_header = ((!) options.lookup_value ("server-header", VariantType.STRING)).get_string (); // register a catch-all handler - this.server.add_handler (null, (server, msg, path, query, client) => { + ((!) this.server).add_handler (null, (server, msg, path, query, client) => { var connection = new Connection (server, msg); msg.set_status (Status.OK); @@ -271,17 +268,17 @@ namespace VSGI.HTTP { listen_options |= ServerListenOptions.IPV6_ONLY; if (options.lookup_value ("file-descriptor", VariantType.INT32) != null) { - this.server.listen_fd (options.lookup_value ("file-descriptor", VariantType.INT32).get_int32 (), + ((!) this.server).listen_fd (((!) options.lookup_value ("file-descriptor", VariantType.INT32)).get_int32 (), listen_options); } else if (options.lookup_value ("all", VariantType.BOOLEAN) != null) { - this.server.listen_all (port.get_int32 (), listen_options); + ((!) this.server).listen_all (port.get_int32 (), listen_options); } else { - this.server.listen_local (port.get_int32 (), listen_options); + ((!) this.server).listen_local (port.get_int32 (), listen_options); } #else - this.server.run_async (); + ((!) this.server).run_async (); _uris.append (new Soup.URI ("%s://0.0.0.0:%u".printf (options.lookup_value ("https", VariantType.BOOLEAN) == null ? "http" : - "https", server.port))); + "https", ((!) server).port))); #endif } From 623bd0f37942198a1b6300d719fbc1b10eb56141 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 12:30:41 +1000 Subject: [PATCH 06/16] Make src/vsgi-cgi/vsgi-cgi.vala non-null compliant Nothing special to report in this commit, just going through and correcting minor compiler errors. --- src/vsgi-cgi/vsgi-cgi.vala | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/vsgi-cgi/vsgi-cgi.vala b/src/vsgi-cgi/vsgi-cgi.vala index d63959e61..62651c861 100644 --- a/src/vsgi-cgi/vsgi-cgi.vala +++ b/src/vsgi-cgi/vsgi-cgi.vala @@ -51,13 +51,13 @@ namespace VSGI.CGI { public override string gateway_interface { owned get { - return Environ.get_variable (environment, "GATEWAY_INTERFACE") ?? "CGI/1.1"; + return (!) (Environ.get_variable (environment, "GATEWAY_INTERFACE") ?? "CGI/1.1"); } } public override string method { owned get { - return Environ.get_variable (environment, "REQUEST_METHOD") ?? "GET"; + return (!) (Environ.get_variable (environment, "REQUEST_METHOD") ?? "GET"); } } @@ -90,7 +90,7 @@ namespace VSGI.CGI { var https = Environ.get_variable (environment, "HTTPS"); var path_translated = Environ.get_variable (environment, "PATH_TRANSLATED"); - if (https != null && https.length > 0 || path_translated != null && path_translated.has_prefix ("https://")) + if (https != null && ((!) https).length > 0 || path_translated != null && ((!) path_translated).has_prefix ("https://")) this._uri.set_scheme ("https"); else this._uri.set_scheme ("http"); @@ -100,37 +100,37 @@ namespace VSGI.CGI { var port = Environ.get_variable (environment, "SERVER_PORT"); if (port != null) - this._uri.set_port (int.parse (port)); + this._uri.set_port (int.parse ((!) port)); var path_info = Environ.get_variable (environment, "PATH_INFO"); var request_uri = Environ.get_variable (environment, "REQUEST_URI"); - if (path_info != null && path_info.length > 0) - this._uri.set_path (path_info); - else if (request_uri != null && request_uri.length > 0) - this._uri.set_path (request_uri.split ("?", 2)[0]); // strip the query + if (path_info != null && ((!) path_info).length > 0) + this._uri.set_path ((!) path_info); + else if (request_uri != null && ((!) request_uri).length > 0) + this._uri.set_path (((!) request_uri).split ("?", 2)[0]); // strip the query else this._uri.set_path ("/"); // raw & parsed HTTP query var query_string = Environ.get_variable (environment, "QUERY_STRING"); - if (query_string != null && query_string.length > 0) { - this._uri.set_query (query_string); - this._query = Form.decode (query_string); - } else if (path_translated != null && "?" in path_translated) { - this._uri.set_query (path_translated.split ("?", 2)[1]); - this._query = Form.decode (path_translated.split ("?", 2)[1]); - } else if (request_uri != null && "?" in request_uri) { - this._uri.set_query (request_uri.split ("?", 2)[1]); - this._query = Form.decode (request_uri.split ("?", 2)[1]); + if (query_string != null && ((!) query_string).length > 0) { + this._uri.set_query ((!) query_string); + this._query = Form.decode ((!) query_string); + } else if (path_translated != null && "?" in (!) path_translated) { + this._uri.set_query (((!) path_translated).split ("?", 2)[1]); + this._query = Form.decode (((!) path_translated).split ("?", 2)[1]); + } else if (request_uri != null && "?" in (!) request_uri) { + this._uri.set_query (((!) request_uri).split ("?", 2)[1]); + this._query = Form.decode (((!) request_uri).split ("?", 2)[1]); } - var content_type = Environ.get_variable (environment, "CONTENT_TYPE") ?? "application/octet-stream"; + var content_type = (!) (Environ.get_variable (environment, "CONTENT_TYPE") ?? "application/octet-stream"); var @params = Soup.header_parse_param_list (content_type); headers.set_content_type (content_type.split (";", 2)[0], @params); // int64 content_length; - if (int64.try_parse (Environ.get_variable (environment, "CONTENT_LENGTH") ?? "0", + if (int64.try_parse ((!) (Environ.get_variable (environment, "CONTENT_LENGTH") ?? "0"), out content_length)) { headers.set_content_length (content_length); } @@ -164,7 +164,7 @@ namespace VSGI.CGI { protected override uint8[]? build_head () { var head = new StringBuilder (); - head.append_printf ("Status: %u %s\r\n", status, reason_phrase ?? Status.get_phrase (status)); + head.append_printf ("Status: %u %s\r\n", status, (!) (reason_phrase ?? Status.get_phrase (status))); this.headers.foreach ((k, v) => { head.append_printf ("%s: %s\r\n", k, v); From 845f528306edc639f0ad2ee69f6e9ad7cb72a783 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 12:40:16 +1000 Subject: [PATCH 07/16] Make src/vsgi-scgi/vsgi-scgi.vala non-null compliant Since DataInputStream.read_upto() returns null only as an error mode, replace null checks with try..catch blocks to avoid having to mess with GLib's vapi. --- src/vsgi-scgi/vsgi-scgi.vala | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/vsgi-scgi/vsgi-scgi.vala b/src/vsgi-scgi/vsgi-scgi.vala index 5922af568..85d5744de 100644 --- a/src/vsgi-scgi/vsgi-scgi.vala +++ b/src/vsgi-scgi/vsgi-scgi.vala @@ -120,10 +120,11 @@ namespace VSGI.SCGI { // buffer the request yield reader.fill_async (-1, priority, cancellable); + string size_str; size_t length; - var size_str = reader.read_upto (":", 1, out length); - - if (size_str == null) { + try { + size_str = reader.read_upto (":", 1, out length); + } catch { throw new SCGIError.FAILED ("could not read netstring length"); } @@ -140,18 +141,22 @@ namespace VSGI.SCGI { // consume and extract the environment size_t read = 0; while (read < size) { + string key; size_t key_length; - var key = reader.read_upto ("", 1, out key_length); - if (key == null) { + try { + key = reader.read_upto ("", 1, out key_length); + } catch { throw new SCGIError.FAILED ("could not read key"); } if (reader.read_byte () != '\0') { throw new SCGIError.MALFORMED_NETSTRING ("missing EOF"); } + string @value; size_t value_length; - var @value = reader.read_upto ("", 1, out value_length); - if (@value == null) { + try { + @value = reader.read_upto ("", 1, out value_length); + } catch { throw new SCGIError.FAILED ("could not read value for key '%s'", key); } if (reader.read_byte () != '\0') { @@ -177,8 +182,8 @@ namespace VSGI.SCGI { } int64 content_length; - if (!int64.try_parse (content_length_str, out content_length)) { - throw new SCGIError.BAD_CONTENT_LENGTH ("'%s' is not a valid content length", content_length_str); + if (!int64.try_parse ((!) content_length_str, out content_length)) { + throw new SCGIError.BAD_CONTENT_LENGTH ("'%s' is not a valid content length", (!) content_length_str); } // buffer the rest of the body From f1b0ab93a16bf79e5c4427184c660395b9596409 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 12:45:44 +1000 Subject: [PATCH 08/16] Make src/vsgi-fastcgi/vsgi-fastcgi.vala non-null compliant Fix up OptionEntry definitions, else just minor stuff as usual. --- src/vsgi-fastcgi/vsgi-fastcgi.vala | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vsgi-fastcgi/vsgi-fastcgi.vala b/src/vsgi-fastcgi/vsgi-fastcgi.vala index b1dd33eab..ff0a8c11f 100644 --- a/src/vsgi-fastcgi/vsgi-fastcgi.vala +++ b/src/vsgi-fastcgi/vsgi-fastcgi.vala @@ -184,13 +184,11 @@ namespace VSGI.FastCGI { construct { #if GIO_2_40 - const OptionEntry[] options = { - {"socket", 's', 0, OptionArg.FILENAME, null, "Listen to the provided UNIX domain socket (or named pipe for WinNT)"}, - {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port"}, - {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor", "0"}, - {"backlog", 'b', 0, OptionArg.INT, null, "Listen queue depth used in the listen() call", "10"}, - {null} - }; + var options = new OptionEntry[4]; + options[0] = {"socket", 's', 0, OptionArg.FILENAME, null, "Listen to the provided UNIX domain socket (or named pipe for WinNT)"}; + options[1] = {"port", 'p', 0, OptionArg.INT, null, "Listen to the provided TCP port"}; + options[2] = {"file-descriptor", 'f', 0, OptionArg.INT, null, "Listen to the provided file descriptor", "0"}; + options[3] = {"backlog", 'b', 0, OptionArg.INT, null, "Listen queue depth used in the listen() call", "10"}; this.add_main_option_entries (options); #endif @@ -204,12 +202,12 @@ namespace VSGI.FastCGI { } public override void listen (Variant options) throws Error { - var backlog = options.lookup_value ("backlog", VariantType.INT32) ?? new Variant.@int32 (10); + var backlog = (!) (options.lookup_value ("backlog", VariantType.INT32) ?? new Variant.@int32 (10)); var fd = global::FastCGI.LISTENSOCK_FILENO; if (options.lookup_value ("socket", VariantType.BYTESTRING) != null) { - var socket_path = options.lookup_value ("socket", VariantType.BYTESTRING).get_bytestring (); + var socket_path = ((!) options.lookup_value ("socket", VariantType.BYTESTRING)).get_bytestring (); fd = global::FastCGI.open_socket (socket_path, backlog.get_int32 ()); @@ -221,7 +219,7 @@ namespace VSGI.FastCGI { } else if (options.lookup_value ("port", VariantType.INT32) != null) { - var port = (options.lookup_value ("port", VariantType.INT32).get_int32 ()); + var port = ((!) options.lookup_value ("port", VariantType.INT32)).get_int32 (); fd = global::FastCGI.open_socket (":%d".printf (port), backlog.get_int32 ()); @@ -233,7 +231,7 @@ namespace VSGI.FastCGI { } else if (options.lookup_value ("file-descriptor", VariantType.INT32) != null) { - fd = options.lookup_value ("file-descriptor", VariantType.INT32).get_int32 (); + fd = ((!) options.lookup_value ("file-descriptor", VariantType.INT32)).get_int32 (); _uris.append (new Soup.URI ("fcgi+fd://%u/".printf (fd))); } From 22d6796dd2652cdbb2408b9bef1ba8a796cdb3b5 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 12:33:24 +1000 Subject: [PATCH 09/16] Make src/valum/valum-context.vala non-null compliant Exactly what it says on the tin, nothing unusual to report. --- src/valum/valum-context.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/valum/valum-context.vala b/src/valum/valum-context.vala index d54f97468..63aceead6 100644 --- a/src/valum/valum-context.vala +++ b/src/valum/valum-context.vala @@ -60,7 +60,7 @@ public class Valum.Context : Object { * @since 0.3 */ public new Value? @get (string key) { - return states[key] ?? (parent == null ? null : parent[key]); + return states[key] ?? (parent == null ? null : ((!) parent)[key]); } /** @@ -78,6 +78,6 @@ public class Valum.Context : Object { * @since 0.3 */ public bool contains (string key) { - return states.contains (key) || (parent != null && parent.contains (key)); + return states.contains (key) || (parent != null && ((!) parent).contains (key)); } } From 153e1e71c32edbd0dcbcc65ec25b6df0558b2703 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:00:48 +1000 Subject: [PATCH 10/16] Make src/valum/valum-regex-route.vala non-null compliant The only change to this file is line 60, where now we test to ensure the regex capture we're after is non-null. --- src/valum/valum-regex-route.vala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/valum/valum-regex-route.vala b/src/valum/valum-regex-route.vala index 97b8f8a08..5a21cb483 100644 --- a/src/valum/valum-regex-route.vala +++ b/src/valum/valum-regex-route.vala @@ -57,7 +57,8 @@ namespace Valum { if (/\(\?<(\w+)>.+?\)/.match (regex.get_pattern (), 0, out capture_match_info)) { try { do { - captures.append (capture_match_info.fetch (1)); + if (capture_match_info.fetch (1) != null) + captures.append ((!) capture_match_info.fetch (1)); } while (capture_match_info.next ()); } catch (RegexError err) { // ... From 54474103c8228315044987c8f13c3d70f36be46e Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:02:54 +1000 Subject: [PATCH 11/16] Make src/valum/valum-rule-route.vala non-null compliant Just marking the types hashmap as non-null after the null check. --- src/valum/valum-rule-route.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/valum/valum-rule-route.vala b/src/valum/valum-rule-route.vala index e16d11984..f86bad6dc 100644 --- a/src/valum/valum-rule-route.vala +++ b/src/valum/valum-rule-route.vala @@ -90,10 +90,10 @@ namespace Valum { if (types == null) { pattern.append_printf ("(?<%s>\\w+)", key); } else { - if (!types.contains (type)) + if (!((!) types).contains (type)) throw new RegexError.COMPILE ("using an undefined type %s", type); - pattern.append_printf ("(?<%s>%s)", key, types[type].get_pattern ()); + pattern.append_printf ("(?<%s>%s)", key, ((!) types)[type].get_pattern ()); } } } From ea965aa599d146ff6b69ba2a5c7e89aab1aa5389 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:25:21 +1000 Subject: [PATCH 12/16] Make src/valum/valum-server-sent-events.vala non-null compliant Just marking printf args as non-null around line 105. --- src/valum/valum-server-sent-events.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/valum/valum-server-sent-events.vala b/src/valum/valum-server-sent-events.vala index 76bfeada0..6a30d76a8 100644 --- a/src/valum/valum-server-sent-events.vala +++ b/src/valum/valum-server-sent-events.vala @@ -103,10 +103,10 @@ namespace Valum.ServerSentEvents { var message = new StringBuilder (); if (event != null) - message.append_printf ("event: %s\n", event); + message.append_printf ("event: %s\n", (!) event); if (id != null) - message.append_printf ("id: %s\n", id); + message.append_printf ("id: %s\n", (!) id); if (retry != null) message.append_printf ("retry: %d\n", (int) (retry / 1000)); From fad5671531b387befd641ab954a127c45fbef68a Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:09:07 +1000 Subject: [PATCH 13/16] Make src/valum/valum-basepath.vala non-null compliant Coerce location string types to `string?` to avoid incorrect function signatures on old libsoup VAPIs and mark them non-null after successful null check. --- src/valum/valum-basepath.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/valum/valum-basepath.vala b/src/valum/valum-basepath.vala index dfec18e0f..cf392cfcc 100644 --- a/src/valum/valum-basepath.vala +++ b/src/valum/valum-basepath.vala @@ -47,8 +47,8 @@ namespace Valum { try { return forward (req, res, () => { req.uri.set_path (original_path); - var location = res.headers.get_one ("Location"); - if (!res.head_written && location != null && location[0] == '/') + string? location = res.headers.get_one ("Location"); + if (!res.head_written && location != null && ((!) location)[0] == '/') res.headers.replace ("Location", path + location); return next (); }, context); @@ -64,8 +64,8 @@ namespace Valum { throw err; } finally { req.uri.set_path (original_path); - var location = res.headers.get_one ("Location"); - if (!res.head_written && location != null && location[0] == '/') + string? location = res.headers.get_one ("Location"); + if (!res.head_written && location != null && ((!) location)[0] == '/') res.headers.replace ("Location", path + location); } } else { From 005d40e3bfbb641724223c1bf72c5efafa06fecc Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:14:22 +1000 Subject: [PATCH 14/16] Make src/valum/valum-decode.vala non-null compliant * Cast MessageHeaders.get_list() result to `string?` to avoid issues with old libsoup VAPIs * Rejig for loop to use a nullable reference to the SList --- src/valum/valum-decode.vala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/valum/valum-decode.vala b/src/valum/valum-decode.vala index 43ab72078..0ea57e62a 100644 --- a/src/valum/valum-decode.vala +++ b/src/valum/valum-decode.vala @@ -44,15 +44,15 @@ namespace Valum { */ public HandlerCallback decode (DecodeFlags flags = DecodeFlags.NONE) { return (req, res, next, ctx) => { - var encodings = Soup.header_parse_list (req.headers.get_list ("Content-Encoding") ?? ""); + var encodings = Soup.header_parse_list ((!) ((string?) req.headers.get_list ("Content-Encoding") ?? "")); // decode is in the opposite order of application encodings.reverse (); req.headers.remove ("Content-Encoding"); - for (unowned SList encoding = encodings; encoding != null; encoding = encoding.next) { - switch (encoding.data.down ()) { + for (unowned SList? encoding = encodings; encoding != null; encoding = ((!) encoding).next) { + switch (((!) encoding).data.down ()) { case "gzip": case "x-gzip": req.convert (new ZlibDecompressor (ZlibCompressorFormat.GZIP)); @@ -63,17 +63,18 @@ namespace Valum { case "identity": // nothing to do, let's take a break ;) break; - default: - // reapply remaining encodings - encoding.reverse (); - foreach (var remaining in encoding) { + default: // reapply remaining encodings + // define new var since vala-0.26 chokes on some syntax + unowned SList enc = (!) encoding; + enc.reverse (); + foreach (var remaining in enc) { req.headers.append ("Content-Encoding", remaining); } if (DecodeFlags.FORWARD_REMAINING_ENCODINGS in flags) { return next (); } else { throw new ServerError.NOT_IMPLEMENTED ("The '%s' encoding is not supported.", - encoding.data); + enc.data); } } } From ca384da8fb8686b17999cf70ac8cb17f19b61a2c Mon Sep 17 00:00:00 2001 From: Bob131 Date: Mon, 30 May 2016 13:22:22 +1000 Subject: [PATCH 15/16] Make src/valum/valum-content-negotiation.vala non-null compliant Just various fixes re faulty libsoup bindings, mostly explicitly marking types as nullable. --- src/valum/valum-content-negotiation.vala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/valum/valum-content-negotiation.vala b/src/valum/valum-content-negotiation.vala index e63f3c6e7..923c280c3 100644 --- a/src/valum/valum-content-negotiation.vala +++ b/src/valum/valum-content-negotiation.vala @@ -46,10 +46,10 @@ namespace Valum.ContentNegotiation { if (param_end == -1) param_end = header.length; - var @params = Soup.header_parse_semi_param_list (header[param_start:param_end]); + HashTable @params = Soup.header_parse_semi_param_list (header[param_start:param_end]); double qvalue; - if (double.try_parse (@params["q"] ?? "1", out qvalue)) { + if (double.try_parse ((!) (@params["q"] ?? "1"), out qvalue)) { return qvalue.clamp (0, 1); } @@ -83,7 +83,7 @@ namespace Valum.ContentNegotiation { EqualFunc match = (EqualFunc) Soup.str_case_equal) { var _expectations = Soup.header_parse_quality_list (expectations, null); return (req, res, next, ctx) => { - var header = req.headers.get_list (header_name); + string? header = req.headers.get_list (header_name); if (_expectations.length () == 0) throw new ClientError.NOT_ACCEPTABLE ("'%s' cannot be satisfied: nothing is expected", header_name); if (header == null) { @@ -92,9 +92,9 @@ namespace Valum.ContentNegotiation { string? best_expectation = null; double best_qvalue = 0; - foreach (var accepted in Soup.header_parse_quality_list (header, null)) { + foreach (var accepted in Soup.header_parse_quality_list ((!) header, null)) { foreach (var expectation in _expectations) { - var current_qvalue = _qvalue_for_param (header, accepted) * _qvalue_for_param (expectations, expectation); + var current_qvalue = _qvalue_for_param ((!) header, accepted) * _qvalue_for_param (expectations, expectation); if (match (accepted, expectation) && current_qvalue > best_qvalue) { best_expectation = expectation; best_qvalue = current_qvalue; @@ -103,7 +103,7 @@ namespace Valum.ContentNegotiation { } if (best_expectation != null) { - return forward (req, res, next, ctx, best_expectation); + return forward (req, res, next, ctx, (!) best_expectation); } throw new ClientError.NOT_ACCEPTABLE ("'%s' is not satisfiable by any of '%s'.", @@ -152,7 +152,7 @@ namespace Valum.ContentNegotiation { owned NegotiateCallback forward) { return negotiate ("Accept-Charset", charsets, (req, res, next, ctx, charset) => { HashTable @params; - var content_type = res.headers.get_content_type (out @params) ?? "application/octet-stream"; + var content_type = (!) ((string?) res.headers.get_content_type (out @params) ?? "application/octet-stream"); @params["charset"] = charset; res.headers.set_content_type (content_type, @params); return forward (req, res, next, ctx, charset); From 695f3a616826542d564284729ee89a9e837a6247 Mon Sep 17 00:00:00 2001 From: Bob131 Date: Tue, 31 May 2016 16:56:19 +1000 Subject: [PATCH 16/16] Enable non-null valac flag Adds `--enable-experimental-non-null` to meson.build. --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index fb4d152e4..0519286cc 100644 --- a/meson.build +++ b/meson.build @@ -13,6 +13,7 @@ add_global_arguments(['-Wall', language: 'c') add_global_arguments(['--enable-experimental', + '--enable-experimental-non-null', '--enable-deprecated', '--fatal-warnings'], language: 'vala')