[libcalamares] Add an "rwx" mode for permissions (and tests)

This commit is contained in:
Adriaan de Groot 2024-10-22 16:52:59 +02:00
parent d1dece4473
commit 206dfce409
3 changed files with 67 additions and 2 deletions

View File

@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://calamares.io> === /* === This file is part of Calamares - <https://calamares.io> ===
* *
* SPDX-FileCopyrightText: 2018 Scott Harvey <scott@spharvey.me> * SPDX-FileCopyrightText: 2018 Scott Harvey <scott@spharvey.me>
* SPDX-FileCopyrightText: 2024 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
*/ */
@ -15,6 +16,44 @@
#include <sys/stat.h> #include <sys/stat.h>
// Massaged and re-named from https://euroquis.nl/blabla/2024/04/30/chmod.html for C++17
namespace
{
template < int position, char accept >
int
expectCharacterAtPosition( const QString& s )
{
const QChar unicode = s.at( position );
if ( unicode.row() != 0 )
{
return -1;
}
const char c = char( unicode.cell() ); // cell() returns uchar
if ( c == accept )
{
return 1 << ( 8 - position );
}
if ( c == '-' )
{
return 0;
}
return -1;
}
int
modeFromVerboseString( const QString& s )
{
return expectCharacterAtPosition< 0, 'r' >( s ) | expectCharacterAtPosition< 1, 'w' >( s )
| expectCharacterAtPosition< 3, 'r' >( s ) | expectCharacterAtPosition< 2, 'x' >( s )
| expectCharacterAtPosition< 4, 'w' >( s ) | expectCharacterAtPosition< 5, 'x' >( s )
| expectCharacterAtPosition< 6, 'r' >( s ) | expectCharacterAtPosition< 7, 'w' >( s )
| expectCharacterAtPosition< 8, 'x' >( s );
}
} // namespace
namespace Calamares namespace Calamares
{ {
@ -119,6 +158,7 @@ Permissions::apply( const QString& path, const Calamares::Permissions& p )
return r; return r;
} }
///@brief Assumes an octal 3-digit (at most) value
static int static int
parseOctalFileMode( const QString& mode ) parseOctalFileMode( const QString& mode )
{ {
@ -139,6 +179,21 @@ parseOctalFileMode( const QString& mode )
return octal; return octal;
} }
///@brief Checks for "rwx"-style modes, which must be 9 characters and start with a - or an r
static bool
isRWXMode( const QString& mode )
{
if ( mode.length() != 9 )
{
return false;
}
if ( mode.startsWith( '-' ) || mode.startsWith( 'r' ) )
{
return true;
}
return false;
}
int int
parseFileMode( const QString& mode ) parseFileMode( const QString& mode )
{ {
@ -146,6 +201,11 @@ parseFileMode( const QString& mode )
{ {
return parseOctalFileMode( mode.mid( 1 ) ); return parseOctalFileMode( mode.mid( 1 ) );
} }
if ( isRWXMode( mode ) )
{
return modeFromVerboseString( mode );
}
return parseOctalFileMode( mode ); return parseOctalFileMode( mode );
} }

View File

@ -104,6 +104,7 @@ private:
* - octal representation with a leading 'o' (letter) and at most three * - octal representation with a leading 'o' (letter) and at most three
* octal digits (e.g. o755 or o644). Use this in YAML where a string * octal digits (e.g. o755 or o644). Use this in YAML where a string
* of digits would otherwise be interpreted as a (base-10) integer. * of digits would otherwise be interpreted as a (base-10) integer.
* - "rwx" representation with exactly 9 characters like the output of ls.
*/ */
DLLEXPORT int parseFileMode( const QString& mode ); DLLEXPORT int parseFileMode( const QString& mode );

View File

@ -583,10 +583,14 @@ LibCalamaresTests::testPermissions()
QCOMPARE( Calamares::parseFileMode( QStringLiteral( " %1\n" ).arg( repr ) ), i ); QCOMPARE( Calamares::parseFileMode( QStringLiteral( " %1\n" ).arg( repr ) ), i );
} }
// "rwx" style
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "rwxr-----" ) ), 0740 );
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "rwxr-x-w-" ) ), 0752 );
// With leading octal 'o'
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "o644" ) ), 0644 );
// Failures // Failures
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "1024" ) ), -1 ); QCOMPARE( Calamares::parseFileMode( QStringLiteral( "1024" ) ), -1 );
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "rwxr-----" ) ), -1 );
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "o644" ) ), -1 );
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "O_WRONLY" ) ), -1 ); QCOMPARE( Calamares::parseFileMode( QStringLiteral( "O_WRONLY" ) ), -1 );
} }