Skip to content

Commit

Permalink
Update operatingSystemVersion on MacOS/iOS to return system version i…
Browse files Browse the repository at this point in the history
…nstead 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 <zra@google.com>
Commit-Queue: Zichang Guo <zichangguo@google.com>
  • Loading branch information
zichangg authored and commit-bot@chromium.org committed Jul 7, 2020
1 parent 5c99205 commit b8a6e77
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 7 deletions.
3 changes: 2 additions & 1 deletion runtime/bin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ executable("run_vm_tests") {
"snapshot_utils.h",
"vmservice_impl.cc",
"vmservice_impl.h",
] + builtin_impl_tests + vm_tests + compiler_tests + heap_tests
] + builtin_impl_tests + vm_tests + compiler_tests + heap_tests +
io_impl_tests

if (!is_win) {
# Adds all symbols to the dynamic symbol table, not just used ones.
Expand Down
3 changes: 3 additions & 0 deletions runtime/bin/io_impl_sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ io_impl_sources = [
"platform_fuchsia.cc",
"platform_linux.cc",
"platform_macos.cc",
"platform_macos.h",
"platform_win.cc",
"process.cc",
"process.h",
Expand Down Expand Up @@ -107,3 +108,5 @@ io_impl_sources = [
"typed_data_utils.cc",
"typed_data_utils.h",
]

io_impl_tests = [ "platform_macos_test.cc" ]
4 changes: 4 additions & 0 deletions runtime/bin/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include "platform/globals.h"
#include "platform/utils.h"

#if defined(HOST_OS_MACOS)
#include "bin/platform_macos.h"
#endif // defined(HOST_OS_MACOS)

namespace dart {
namespace bin {

Expand Down
75 changes: 69 additions & 6 deletions runtime/bin/platform_macos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#if defined(HOST_OS_MACOS)

#include "bin/platform.h"
#include "bin/platform_macos.h"

#include <CoreFoundation/CoreFoundation.h>

Expand All @@ -14,13 +15,12 @@
#endif // !HOST_OS_IOS
#include <errno.h> // NOLINT
#include <mach-o/dyld.h>
#include <signal.h> // NOLINT
#include <string.h> // NOLINT
#include <signal.h> // NOLINT
#include <sys/resource.h> // NOLINT
#include <sys/sysctl.h> // NOLINT
#include <sys/types.h> // NOLINT
#include <sys/utsname.h> // NOLINT
#include <unistd.h> // NOLINT
#include <sys/sysctl.h> // NOLINT
#include <sys/types.h> // NOLINT
#include <sys/utsname.h> // NOLINT
#include <unistd.h> // NOLINT

#include "bin/console.h"
#include "bin/file.h"
Expand Down Expand Up @@ -114,7 +114,70 @@ const char* Platform::OperatingSystem() {
#endif
}

char* ExtractsOSVersionFromString(char* str) {
char* pos = strstr(str, "<key>ProductVersion</key>");
if (pos == NULL) {
return NULL;
}
pos = strstr(pos, "<string>");
if (pos == NULL) {
return NULL;
}
// Shift the index by the length of "<string>".
pos += 8;
char* end_pos = strstr(pos, "</string>");
if (end_pos == NULL) {
return NULL;
}

int length = end_pos - pos;
char* result =
reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char)) + 1);
strncpy(result, pos, length);
result[length] = '\0';
return result;
}

static char* GetOSVersionFromPlist() {
const char* path = "/System/Library/CoreServices/SystemVersion.plist";
File* file = File::Open(NULL, path, File::kRead);
if (file == NULL) {
return NULL;
}
int length = file->Length();
if (length < 0) {
return NULL;
}
char* buffer =
reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char) + 1));
int bytes = file->ReadFully(buffer, length);
buffer[length * sizeof(char)] = '\0';
file->Close();
file->Release();
if (bytes < 0) {
return NULL;
}
return ExtractsOSVersionFromString(buffer);
}

const char* Platform::OperatingSystemVersion() {
char str[64];
size_t size = sizeof(str);
// This is only available to some versions later than 10.13.*. If it failed,
// try to read from "SystemVersion.plist".
int res = sysctlbyname("kern.osproductversion", str, &size, NULL, 0);
if (res == 0) {
int len = snprintf(NULL, 0, "%s", str);
char* result_string = DartUtils::ScopedCString(len + 1);
strncpy(result_string, str, len);
result_string[len] = '\0';
return result_string;
}
char* result_string = GetOSVersionFromPlist();
if (result_string != NULL) {
return result_string;
}

struct utsname info;
int ret = uname(&info);
if (ret != 0) {
Expand Down
27 changes: 27 additions & 0 deletions runtime/bin/platform_macos.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_BIN_PLATFORM_MACOS_H_
#define RUNTIME_BIN_PLATFORM_MACOS_H_

#if !defined(RUNTIME_BIN_PLATFORM_H_)
#error Do not include platform_macos.h directly;
#error use platform.h instead.
#endif

namespace dart {
namespace bin {

// This function extracts OSVersion from SystemVersion.plist.
// The format of input should be:
// <key>ProductVersion</key>
// <string>10.15.4</string>
// Returns the string representation of OSVersion. For example, "10.15.4" will
// be returned in the previous example.
char* ExtractsOSVersionFromString(char* str);

} // namespace bin
} // namespace dart

#endif // RUNTIME_BIN_PLATFORM_MACOS_H_
53 changes: 53 additions & 0 deletions runtime/bin/platform_macos_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#if defined(HOST_OS_MACOS)
#include "bin/platform.h"
#include "vm/unit_test.h"

namespace dart {

TEST_CASE(Platform_ExtractsOSVersionFromString) {
char str[] =
"some overheads\n<key>ProductVersion</key>\nsome bytes<string>Fake "
"version</string>";
char* result = bin::ExtractsOSVersionFromString(str);
EXPECT(result != NULL);
EXPECT_STREQ("Fake version", result);

EXPECT(bin::ExtractsOSVersionFromString("<key>ProductVersion</key>") == NULL);

// Incomplete file
EXPECT(bin::ExtractsOSVersionFromString(
"<key>ProductVersion</key><string>Fake version</string") != NULL);

// A copy of actual SystemVersion.plist on mac.
str =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<dict>\n"
" <key>ProductBuildVersion</key>\n"
" <string>19E287</string>\n"
" <key>ProductCopyright</key>\n"
" <string>1983-2020 Apple Inc.</string>\n"
" <key>ProductName</key>\n"
" <string>Mac OS X</string>\n"
" <key>ProductUserVisibleVersion</key>\n"
" <string>10.15.4</string>\n"
" <key>ProductVersion</key>\n"
" <string>10.15.4</string>\n"
" <key>iOSSupportVersion</key>\n"
" <string>13.4</string>\n"
"</dict>\n"
"</plist>"

result = bin::ExtractsOSVersionFromString(str);
EXPECT(result != NULL);
EXPECT_STREQ("10.15.4", result);
}

} // namespace dart
#endif // defined(HOST_OS_MACOS)

0 comments on commit b8a6e77

Please sign in to comment.