// Copyright (c) 2012, 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. #include "bin/file.h" #include "bin/dartutils.h" #include "bin/directory.h" #include "bin/test_utils.h" #include "platform/assert.h" #include "platform/globals.h" #include "vm/unit_test.h" namespace dart { TEST_CASE(Read) { const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); bin::File* file = bin::File::Open(nullptr, kFilename, bin::File::kRead); EXPECT(file != nullptr); char buffer[16]; buffer[0] = '\0'; EXPECT(file->ReadFully(buffer, 13)); // ReadFully returns true. buffer[13] = '\0'; EXPECT_STREQ("// Copyright ", buffer); EXPECT(!file->WriteByte(1)); // Cannot write to a read-only file. file->Release(); } TEST_CASE(OpenUri_RelativeFilename) { const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all characters 'c' for (const char* p = kFilename; *p != '\0'; p++) { if (*p == 'c') { *t++ = '%'; *t++ = '6'; *t++ = '3'; } else { *t++ = *p; } } *t = 0; bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file != nullptr); char buffer[16]; buffer[0] = '\0'; EXPECT(file->ReadFully(buffer, 13)); // ReadFully returns true. buffer[13] = '\0'; EXPECT_STREQ("// Copyright ", buffer); EXPECT(!file->WriteByte(1)); // Cannot write to a read-only file. file->Release(); } TEST_CASE(OpenUri_AbsoluteFilename) { const char* kRelativeFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); const char* kFilename = bin::File::GetCanonicalPath(nullptr, kRelativeFilename); EXPECT_NOTNULL(kFilename); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all characters 'c' for (const char* p = kFilename; *p != '\0'; p++) { if (*p == 'c') { *t++ = '%'; *t++ = '6'; *t++ = '3'; } else { *t++ = *p; } } *t = 0; bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file != nullptr); char buffer[16]; buffer[0] = '\0'; EXPECT(file->ReadFully(buffer, 13)); // ReadFully returns true. buffer[13] = '\0'; EXPECT_STREQ("// Copyright ", buffer); EXPECT(!file->WriteByte(1)); // Cannot write to a read-only file. file->Release(); } static const char* Concat(const char* a, const char* b) { const intptr_t len = strlen(a) + strlen(b); char* c = bin::DartUtils::ScopedCString(len + 1); EXPECT_NOTNULL(c); snprintf(c, len + 1, "%s%s", a, b); return c; } TEST_CASE(OpenUri_ValidUri) { const char* kRelativeFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); const char* kAbsoluteFilename = bin::File::GetCanonicalPath(nullptr, kRelativeFilename); EXPECT_NOTNULL(kAbsoluteFilename); const char* kFilename = Concat("file:///", kAbsoluteFilename); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all characters 'c' for (const char* p = kFilename; *p != '\0'; p++) { if (*p == 'c') { *t++ = '%'; *t++ = '6'; *t++ = '3'; } else { *t++ = *p; } } *t = 0; bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file != nullptr); char buffer[16]; buffer[0] = '\0'; EXPECT(file->ReadFully(buffer, 13)); // ReadFully returns true. buffer[13] = '\0'; EXPECT_STREQ("// Copyright ", buffer); EXPECT(!file->WriteByte(1)); // Cannot write to a read-only file. file->Release(); } TEST_CASE(OpenUri_UriWithSpaces) { const char* kRelativeFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); const char* strSystemTemp = bin::Directory::SystemTemp(nullptr); EXPECT_NOTNULL(strSystemTemp); const char* kTempDir = Concat(strSystemTemp, "/foo bar"); const char* strTempDir = bin::Directory::CreateTemp(nullptr, kTempDir); EXPECT_NOTNULL(strTempDir); const char* kTargetFilename = Concat(strTempDir, "/file test.cc"); bool result = bin::File::Copy(nullptr, kRelativeFilename, kTargetFilename); EXPECT(result); const char* kAbsoluteFilename = bin::File::GetCanonicalPath(nullptr, kTargetFilename); EXPECT_NOTNULL(kAbsoluteFilename); const char* kFilename = Concat("file:///", kAbsoluteFilename); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all spaces for (const char* p = kFilename; *p != '\0'; p++) { if (*p == ' ') { *t++ = '%'; *t++ = '2'; *t++ = '0'; } else { *t++ = *p; } } *t = 0; printf("encoded: %s\n", encoded); bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file != nullptr); char buffer[16]; buffer[0] = '\0'; EXPECT(file->ReadFully(buffer, 13)); // ReadFully returns true. buffer[13] = '\0'; EXPECT_STREQ("// Copyright ", buffer); EXPECT(!file->WriteByte(1)); // Cannot write to a read-only file. file->Release(); bin::Directory::Delete(nullptr, strTempDir, /* recursive= */ true); } TEST_CASE(OpenUri_InvalidUriPercentEncoding) { const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all characters 'c' for (const char* p = kFilename; *p != '\0'; p++) { if (*p == 'c') { *t++ = '%'; *t++ = 'f'; *t++ = 'o'; } else { *t++ = *p; } } *t = 0; bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file == nullptr); } TEST_CASE(OpenUri_TruncatedUriPercentEncoding) { const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc"); char* encoded = reinterpret_cast( bin::DartUtils::ScopedCString(strlen(kFilename) * 3 + 1)); char* t = encoded; // percent-encode all characters 'c' for (const char* p = kFilename; *p != '\0'; p++) { if (*p == 'c') { *t++ = '%'; *t++ = 'f'; *t++ = 'o'; } else { *t++ = *p; } } *(t - 1) = 0; // truncate last uri encoding bin::File* file = bin::File::OpenUri(nullptr, encoded, bin::File::kRead); EXPECT(file == nullptr); } TEST_CASE(FileLength) { const char* kFilename = bin::test::GetFileName("runtime/tests/vm/data/fixed_length_file"); bin::File* file = bin::File::Open(nullptr, kFilename, bin::File::kRead); EXPECT(file != nullptr); EXPECT_EQ(42, file->Length()); file->Release(); } TEST_CASE(FilePosition) { char buf[42]; const char* kFilename = bin::test::GetFileName("runtime/tests/vm/data/fixed_length_file"); bin::File* file = bin::File::Open(nullptr, kFilename, bin::File::kRead); EXPECT(file != nullptr); EXPECT(file->ReadFully(buf, 12)); EXPECT_EQ(12, file->Position()); EXPECT(file->ReadFully(buf, 6)); EXPECT_EQ(18, file->Position()); file->Release(); } } // namespace dart