Skip to content

Commit b8a6e77

Browse files
zichanggcommit-bot@chromium.org
authored andcommitted
Update operatingSystemVersion on MacOS/iOS to return system version instead of kernel version
Platform.operatingSystemVersion on MacOS/iOS returns the version of the kernel. It should instead returns system version. This cl will try to use recently added "kern.osproductversion" to get the system version. If it failed, try to read from "SystemVersion.plist". Falls back to original kernal version if none of them succeed. Bug: #41725 Change-Id: Ibbf78f10dc6d21b79d83d82fbcdacfd22ebc716d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151165 Reviewed-by: Zach Anderson <[email protected]> Commit-Queue: Zichang Guo <[email protected]>
1 parent 5c99205 commit b8a6e77

File tree

6 files changed

+158
-7
lines changed

6 files changed

+158
-7
lines changed

runtime/bin/BUILD.gn

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,8 @@ executable("run_vm_tests") {
10561056
"snapshot_utils.h",
10571057
"vmservice_impl.cc",
10581058
"vmservice_impl.h",
1059-
] + builtin_impl_tests + vm_tests + compiler_tests + heap_tests
1059+
] + builtin_impl_tests + vm_tests + compiler_tests + heap_tests +
1060+
io_impl_tests
10601061

10611062
if (!is_win) {
10621063
# Adds all symbols to the dynamic symbol table, not just used ones.

runtime/bin/io_impl_sources.gni

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ io_impl_sources = [
4949
"platform_fuchsia.cc",
5050
"platform_linux.cc",
5151
"platform_macos.cc",
52+
"platform_macos.h",
5253
"platform_win.cc",
5354
"process.cc",
5455
"process.h",
@@ -107,3 +108,5 @@ io_impl_sources = [
107108
"typed_data_utils.cc",
108109
"typed_data_utils.h",
109110
]
111+
112+
io_impl_tests = [ "platform_macos_test.cc" ]

runtime/bin/platform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include "platform/globals.h"
1010
#include "platform/utils.h"
1111

12+
#if defined(HOST_OS_MACOS)
13+
#include "bin/platform_macos.h"
14+
#endif // defined(HOST_OS_MACOS)
15+
1216
namespace dart {
1317
namespace bin {
1418

runtime/bin/platform_macos.cc

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#if defined(HOST_OS_MACOS)
77

88
#include "bin/platform.h"
9+
#include "bin/platform_macos.h"
910

1011
#include <CoreFoundation/CoreFoundation.h>
1112

@@ -14,13 +15,12 @@
1415
#endif // !HOST_OS_IOS
1516
#include <errno.h> // NOLINT
1617
#include <mach-o/dyld.h>
17-
#include <signal.h> // NOLINT
18-
#include <string.h> // NOLINT
18+
#include <signal.h> // NOLINT
1919
#include <sys/resource.h> // NOLINT
20-
#include <sys/sysctl.h> // NOLINT
21-
#include <sys/types.h> // NOLINT
22-
#include <sys/utsname.h> // NOLINT
23-
#include <unistd.h> // NOLINT
20+
#include <sys/sysctl.h> // NOLINT
21+
#include <sys/types.h> // NOLINT
22+
#include <sys/utsname.h> // NOLINT
23+
#include <unistd.h> // NOLINT
2424

2525
#include "bin/console.h"
2626
#include "bin/file.h"
@@ -114,7 +114,70 @@ const char* Platform::OperatingSystem() {
114114
#endif
115115
}
116116

117+
char* ExtractsOSVersionFromString(char* str) {
118+
char* pos = strstr(str, "<key>ProductVersion</key>");
119+
if (pos == NULL) {
120+
return NULL;
121+
}
122+
pos = strstr(pos, "<string>");
123+
if (pos == NULL) {
124+
return NULL;
125+
}
126+
// Shift the index by the length of "<string>".
127+
pos += 8;
128+
char* end_pos = strstr(pos, "</string>");
129+
if (end_pos == NULL) {
130+
return NULL;
131+
}
132+
133+
int length = end_pos - pos;
134+
char* result =
135+
reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char)) + 1);
136+
strncpy(result, pos, length);
137+
result[length] = '\0';
138+
return result;
139+
}
140+
141+
static char* GetOSVersionFromPlist() {
142+
const char* path = "/System/Library/CoreServices/SystemVersion.plist";
143+
File* file = File::Open(NULL, path, File::kRead);
144+
if (file == NULL) {
145+
return NULL;
146+
}
147+
int length = file->Length();
148+
if (length < 0) {
149+
return NULL;
150+
}
151+
char* buffer =
152+
reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char) + 1));
153+
int bytes = file->ReadFully(buffer, length);
154+
buffer[length * sizeof(char)] = '\0';
155+
file->Close();
156+
file->Release();
157+
if (bytes < 0) {
158+
return NULL;
159+
}
160+
return ExtractsOSVersionFromString(buffer);
161+
}
162+
117163
const char* Platform::OperatingSystemVersion() {
164+
char str[64];
165+
size_t size = sizeof(str);
166+
// This is only available to some versions later than 10.13.*. If it failed,
167+
// try to read from "SystemVersion.plist".
168+
int res = sysctlbyname("kern.osproductversion", str, &size, NULL, 0);
169+
if (res == 0) {
170+
int len = snprintf(NULL, 0, "%s", str);
171+
char* result_string = DartUtils::ScopedCString(len + 1);
172+
strncpy(result_string, str, len);
173+
result_string[len] = '\0';
174+
return result_string;
175+
}
176+
char* result_string = GetOSVersionFromPlist();
177+
if (result_string != NULL) {
178+
return result_string;
179+
}
180+
118181
struct utsname info;
119182
int ret = uname(&info);
120183
if (ret != 0) {

runtime/bin/platform_macos.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#ifndef RUNTIME_BIN_PLATFORM_MACOS_H_
6+
#define RUNTIME_BIN_PLATFORM_MACOS_H_
7+
8+
#if !defined(RUNTIME_BIN_PLATFORM_H_)
9+
#error Do not include platform_macos.h directly;
10+
#error use platform.h instead.
11+
#endif
12+
13+
namespace dart {
14+
namespace bin {
15+
16+
// This function extracts OSVersion from SystemVersion.plist.
17+
// The format of input should be:
18+
// <key>ProductVersion</key>
19+
// <string>10.15.4</string>
20+
// Returns the string representation of OSVersion. For example, "10.15.4" will
21+
// be returned in the previous example.
22+
char* ExtractsOSVersionFromString(char* str);
23+
24+
} // namespace bin
25+
} // namespace dart
26+
27+
#endif // RUNTIME_BIN_PLATFORM_MACOS_H_

runtime/bin/platform_macos_test.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#if defined(HOST_OS_MACOS)
6+
#include "bin/platform.h"
7+
#include "vm/unit_test.h"
8+
9+
namespace dart {
10+
11+
TEST_CASE(Platform_ExtractsOSVersionFromString) {
12+
char str[] =
13+
"some overheads\n<key>ProductVersion</key>\nsome bytes<string>Fake "
14+
"version</string>";
15+
char* result = bin::ExtractsOSVersionFromString(str);
16+
EXPECT(result != NULL);
17+
EXPECT_STREQ("Fake version", result);
18+
19+
EXPECT(bin::ExtractsOSVersionFromString("<key>ProductVersion</key>") == NULL);
20+
21+
// Incomplete file
22+
EXPECT(bin::ExtractsOSVersionFromString(
23+
"<key>ProductVersion</key><string>Fake version</string") != NULL);
24+
25+
// A copy of actual SystemVersion.plist on mac.
26+
str =
27+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
28+
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
29+
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
30+
"<plist version=\"1.0\">\n"
31+
"<dict>\n"
32+
" <key>ProductBuildVersion</key>\n"
33+
" <string>19E287</string>\n"
34+
" <key>ProductCopyright</key>\n"
35+
" <string>1983-2020 Apple Inc.</string>\n"
36+
" <key>ProductName</key>\n"
37+
" <string>Mac OS X</string>\n"
38+
" <key>ProductUserVisibleVersion</key>\n"
39+
" <string>10.15.4</string>\n"
40+
" <key>ProductVersion</key>\n"
41+
" <string>10.15.4</string>\n"
42+
" <key>iOSSupportVersion</key>\n"
43+
" <string>13.4</string>\n"
44+
"</dict>\n"
45+
"</plist>"
46+
47+
result = bin::ExtractsOSVersionFromString(str);
48+
EXPECT(result != NULL);
49+
EXPECT_STREQ("10.15.4", result);
50+
}
51+
52+
} // namespace dart
53+
#endif // defined(HOST_OS_MACOS)

0 commit comments

Comments
 (0)