Files
wehub-resource-sync 680845cb1c
Linux build / Determine Swift version (push) Waiting to run
Linux build / Linux compile check (push) Blocked by required conditions
Build containerization / Verify commit signatures (push) Has been skipped
Build containerization / containerization (push) Successful in 0s
chore: import upstream snapshot with attribution
2026-07-13 12:25:30 +08:00

115 lines
4.5 KiB
Swift

//===----------------------------------------------------------------------===//
// Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
// swiftlint:disable force_try
import Foundation
import Testing
@testable import ContainerizationEXT4
struct TestEXT4ExtendedAttribute {
@Test func compressName() {
struct TestCase {
let input: String
let expectedId: UInt8
let expectedStr: String
init(_ input: String, _ expectedId: UInt8, _ expectedStr: String) {
self.input = input
self.expectedId = expectedId
self.expectedStr = expectedStr
}
}
let tests: [TestCase] = [
.init("my.test.xattr", 0, "my.test.xattr"),
.init("user.fubar", 1, "fubar"),
.init("system.posix_acl_access.denied_su", 2, ".denied_su"),
.init("system.posix_acl_default_failed", 3, "_failed"),
.init("trusted.user", 4, "user"),
.init("trusted_user", 0, "trusted_user"),
.init("security.auth", 6, "auth"),
.init("system.admin", 7, "admin"),
.init("system.richacl.denied", 8, ".denied"),
]
for test in tests {
let ret = EXT4.ExtendedAttribute.compressName(test.input)
#expect(ret.0 == test.expectedId)
#expect(ret.1 == test.expectedStr)
}
}
@Test func lastXattrNotDroppedAtBufferBoundary() throws {
let buffer: [UInt8] = [
0, // nameLength
8, // nameIndex
0, 0, // valueOffset
0, 0, 0, 0, // valueInum
0, 0, 0, 0, // valueSize
0, 0, 0, 0, // hash
]
let attrs = try EXT4.FileXattrsState.read(buffer: buffer, start: 0, offset: 0)
try #require(attrs.count == 1)
#expect(attrs[0].fullName == "system.richacl")
}
@Test func xattrOutOfBoundsValueDoesNotCrash() throws {
let buffer: [UInt8] = [
1, // nameLength
1, // nameIndex
17, 0, // valueOffset
0, 0, 0, 0, // valueInum
4, 0, 0, 0, // valueSize
0, 0, 0, 0, // hash
UInt8(ascii: "a"), 0, 0, 0, // name
]
let attrs = try EXT4.FileXattrsState.read(buffer: buffer, start: 0, offset: 0)
#expect(attrs.isEmpty)
}
@Test func encodeDecodeAttributes() {
let xattrs: [String: Data] = [
"foo.bar": Data([1, 2, 3]),
"bar": Data([0, 0, 0]),
"system.richacl.bar": Data([99, 1, 9, 1]),
"foobar.user": Data([71, 2, 45]),
"test.xattr.cap": Data([1, 32, 3]),
"testing123": Data([12, 24, 45]),
"sys.admin": Data([16, 23, 13]),
"test.123": Data([15, 26, 54]),
"extendedattribute.test": Data([15, 26, 54, 1, 2, 4, 6, 7, 7]),
]
let blockSize = 4096
var state = EXT4.FileXattrsState(
inode: 1, inodeXattrCapacity: EXT4.InodeExtraSize, blockCapacity: UInt32(blockSize))
for (s, d) in xattrs {
let attribute = EXT4.ExtendedAttribute(name: s, value: [UInt8](d))
try! state.add(attribute)
}
var inlineAttrBuffer: [UInt8] = .init(repeating: 0, count: Int(EXT4.InodeExtraSize))
var blockAttrBuffer: [UInt8] = .init(repeating: 0, count: blockSize)
try! state.writeInlineAttributes(buffer: &inlineAttrBuffer)
try! state.writeBlockAttributes(buffer: &blockAttrBuffer)
let gotInlineXattrs = try! EXT4.EXT4Reader.readInlineExtendedAttributes(from: inlineAttrBuffer)
let gotBlockXattrs = try! EXT4.EXT4Reader.readBlockExtendedAttributes(from: blockAttrBuffer)
var gotXattrs: [String: Data] = [:]
for attr in gotBlockXattrs + gotInlineXattrs {
gotXattrs[attr.fullName] = Data(attr.value)
}
#expect(gotXattrs == xattrs)
}
}