Skip to content

Commit 5682a1f

Browse files
authored
Merge pull request #74913 from Azoy/60-argc
[6.0] [stdlib] Ignore argc when setting up CommandLine.arguments
2 parents 82dd1b9 + 6ae4d2c commit 5682a1f

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

stdlib/public/core/CommandLine.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ internal func _swift_stdlib_getUnsafeArgvArgc(_: UnsafeMutablePointer<Int32>)
2020

2121
/// Command-line arguments for the current process.
2222
@frozen // namespace
23-
public enum CommandLine : ~BitwiseCopyable {
24-
}
23+
public enum CommandLine: ~BitwiseCopyable {}
2524

2625
extension CommandLine {
2726
/// The backing static variable for argument count may come either from the
2827
/// entry point or it may need to be computed e.g. if we're in the REPL.
2928
@usableFromInline
30-
internal static var _argc: Int32 = Int32()
29+
internal static var _argc: Int32 = 0
3130

3231
/// The backing static variable for arguments may come either from the
3332
/// entry point or it may need to be computed e.g. if we're in the REPL.
@@ -37,12 +36,27 @@ extension CommandLine {
3736
@usableFromInline
3837
internal static var _unsafeArgv:
3938
UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>
40-
= _swift_stdlib_getUnsafeArgvArgc(&_argc)
39+
= _swift_stdlib_getUnsafeArgvArgc(&_argc)
4140

4241
/// Access to the raw argc value from C.
4342
public static var argc: Int32 {
44-
_ = CommandLine.unsafeArgv // Force evaluation of argv.
45-
return _argc
43+
// We intentionally ignore the argc value given to us from
44+
// '_swift_stdlib_getUnsafeArgvArgc' because argv and argc are mutable, so
45+
// someone can mutate the contents of argv and never update the argc value.
46+
// This results in an out of sync argc which can lead to crashes on first
47+
// access to 'CommandLine.arguments' due to attempting to read '0 ..< argc'
48+
// strings.
49+
//
50+
// Note: It's still entirely possible that someone may update argv after
51+
// this iteration and before we actually read argv, but we have no control
52+
// over synchronizing access to argc and argv.
53+
var argc: Int32 = 0
54+
55+
while let _ = _unsafeArgv[Int(argc)] {
56+
argc += 1
57+
}
58+
59+
return argc
4660
}
4761

4862
/// Access to the raw argv value from C.

0 commit comments

Comments
 (0)