Skip to content

Commit

Permalink
Utils: Port hostname validation from distinst and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
meisenzahl committed Oct 1, 2024
1 parent 64ef863 commit fff2b00
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
run: |
meson setup build
ninja -C build install
ninja -C build test
lint:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ subdir('common')
subdir('daemon')
subdir('src')
subdir('data')
subdir('test')
47 changes: 47 additions & 0 deletions src/HostnameValidator.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
/*-
* Copyright 2024 elementary, Inc. (https://elementary.io)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Marius Meisenzahl <[email protected]>
*/

namespace Utils {
private bool hostname_is_valid_char (char c) {
return ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '-' ||
c == '.');
}

// Based on https://github.com/pop-os/hostname-validator/blob/458fa5a1df98cb663f0456dffb542e1a907861c9/src/lib.rs#L29
public bool hostname_is_valid (string hostname) {
for (int i = 0; i < hostname.char_count (); i++) {
char c = hostname[i];
if (!hostname_is_valid_char (c)) {
return false;
}
}

string[] labels = hostname.split (".", -1);
foreach (string label in labels) {
if (label.char_count () == 0 || label.length > 63 || label[0] == '-' || label[label.length - 1] == '-') {
return false;
}
}

return !(hostname.char_count () == 0 || hostname.length > 253);
}
}
7 changes: 7 additions & 0 deletions src/Utils.vala
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ namespace Utils {
string hostname = get_ubiquity_compatible_hostname () ?? ("elementary-os" + "-" + get_chassis ());
hostname += "-" + get_machine_id ().substring (0, 8);

// If the automatic hostname logic fails in some way, it's possible we may generate an invalid
// hostname. We could fix this by trimming traling/leading hyphens or other invalid characters.
// But it's probably a bad hostname anyway, so just fallback
if (!hostname_is_valid (hostname)) {
hostname = "elementary-os";
}

return hostname;
}
}
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
vala_files = [
'Application.vala',
'HostnameValidator.vala',
'MainWindow.vala',
'Utils.vala',
'Helpers/InstallerDaemon.vala',
Expand Down
24 changes: 24 additions & 0 deletions test/HostnameValidatorTest.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
void add_hostname_validator_tests () {
Test.add_func ("/valid", () => {
assert (Utils.hostname_is_valid ("VaLiD-HoStNaMe"));
assert (Utils.hostname_is_valid ("50-name"));
assert (Utils.hostname_is_valid ("235235"));
assert (Utils.hostname_is_valid ("example.com"));
assert (Utils.hostname_is_valid ("VaLid.HoStNaMe"));
assert (Utils.hostname_is_valid ("123.456"));
});

Test.add_func ("/invalid", () => {
assert (!Utils.hostname_is_valid ("-invalid-name"));
assert (!Utils.hostname_is_valid ("also-invalid-"));
assert (!Utils.hostname_is_valid ("asdf@fasd"));
assert (!Utils.hostname_is_valid ("@asdfl"));
assert (!Utils.hostname_is_valid ("asd f@"));
assert (!Utils.hostname_is_valid (".invalid"));
assert (!Utils.hostname_is_valid ("invalid.name."));
assert (!Utils.hostname_is_valid ("foo.label-is-way-to-longgggggggggggggggggggggggggggggggggggggggggggg.org"));
assert (!Utils.hostname_is_valid ("invalid.-starting.char"));
assert (!Utils.hostname_is_valid ("invalid.ending-.char"));
assert (!Utils.hostname_is_valid ("empty..label"));
});
}
5 changes: 5 additions & 0 deletions test/Test.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void main (string[] args) {
Test.init (ref args);
add_hostname_validator_tests ();
Test.run ();
}
13 changes: 13 additions & 0 deletions test/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
test_dependencies = [
glib_dep,
]

tests = executable(
meson.project_name() + '-tests',
'HostnameValidatorTest.vala',
'Test.vala',
meson.project_source_root() + '/src/HostnameValidator.vala',
dependencies: test_dependencies
)

test('Test', tests)

0 comments on commit fff2b00

Please sign in to comment.