Change ASCII conversion for hash and add tests
Hash was printed using snprintf(), but we can just write yet another hex
conversion utility!
Change-Id: I04f1992deaf5bf1b3e2751c8f07072f8ed6660e9
diff --git a/Android.mk b/Android.mk
index ce1a603..e353a4f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -7,38 +7,59 @@
LOCAL_PATH:= $(call my-dir)
+common_src_files := \
+ VolumeManager.cpp \
+ CommandListener.cpp \
+ VoldCommand.cpp \
+ NetlinkManager.cpp \
+ NetlinkHandler.cpp \
+ Volume.cpp \
+ DirectVolume.cpp \
+ logwrapper.c \
+ Process.cpp \
+ Fat.cpp \
+ Loop.cpp \
+ Devmapper.cpp \
+ ResponseCode.cpp \
+ Xwarp.cpp
+
+common_c_includes := \
+ $(KERNEL_HEADERS) \
+ external/openssl/include
+
+common_shared_libraries := \
+ libsysutils \
+ libcutils \
+ libdiskconfig \
+ libcrypto
+
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
- main.cpp \
- VolumeManager.cpp \
- CommandListener.cpp \
- VoldCommand.cpp \
- NetlinkManager.cpp \
- NetlinkHandler.cpp \
- Volume.cpp \
- DirectVolume.cpp \
- logwrapper.c \
- Process.cpp \
- Fat.cpp \
- Loop.cpp \
- Devmapper.cpp \
- ResponseCode.cpp \
- Xwarp.cpp
+LOCAL_MODULE := libvold
+
+LOCAL_SRC_FILES := $(common_src_files)
+
+LOCAL_C_INCLUDES := $(common_c_includes)
+
+LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
+
+LOCAL_MODULE_TAGS := eng tests
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
LOCAL_MODULE:= vold
-LOCAL_C_INCLUDES := \
- $(KERNEL_HEADERS) \
- external/openssl/include
+LOCAL_SRC_FILES := \
+ main.cpp \
+ $(common_src_files)
+
+LOCAL_C_INCLUDES := $(common_c_includes)
LOCAL_CFLAGS :=
-LOCAL_SHARED_LIBRARIES := \
- libsysutils \
- libcutils \
- libdiskconfig \
- libcrypto
+LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
include $(BUILD_EXECUTABLE)
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 8a70c37..4f803fc 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -63,26 +63,34 @@
delete mActiveContainers;
}
-#define MD5_ASCII_LENGTH ((MD5_DIGEST_LENGTH*2)+1)
-
char *VolumeManager::asecHash(const char *id, char *buffer, size_t len) {
+ static const char* digits = "0123456789abcdef";
+
unsigned char sig[MD5_DIGEST_LENGTH];
- if (len < MD5_ASCII_LENGTH) {
- SLOGE("Target hash buffer size < %d bytes (%d)", MD5_ASCII_LENGTH, len);
+ if (buffer == NULL) {
+ SLOGE("Destination buffer is NULL");
+ errno = ESPIPE;
+ return NULL;
+ } else if (id == NULL) {
+ SLOGE("Source buffer is NULL");
+ errno = ESPIPE;
+ return NULL;
+ } else if (len < MD5_ASCII_LENGTH_PLUS_NULL) {
+ SLOGE("Target hash buffer size < %d bytes (%d)",
+ MD5_ASCII_LENGTH_PLUS_NULL, len);
errno = ESPIPE;
return NULL;
}
MD5(reinterpret_cast<const unsigned char*>(id), strlen(id), sig);
- memset(buffer, 0, len);
-
+ char *p = buffer;
for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
- char tmp[3];
- snprintf(tmp, 3, "%.02x", sig[i]);
- strcat(buffer, tmp);
+ *p++ = digits[sig[i] >> 4];
+ *p++ = digits[sig[i] & 0x0F];
}
+ *p = '\0';
return buffer;
}
diff --git a/VolumeManager.h b/VolumeManager.h
index 2ec9eb3..0693fd0 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -24,6 +24,9 @@
#include "Volume.h"
+/* The length of an MD5 hash when encoded into ASCII hex characters */
+#define MD5_ASCII_LENGTH_PLUS_NULL ((MD5_DIGEST_LENGTH*2)+1)
+
typedef android::List<char *> AsecIdCollection;
class VolumeManager {
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..8ae4b5d
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,36 @@
+# Build the unit tests.
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+test_src_files := \
+ VolumeManager_test.cpp
+
+shared_libraries := \
+ liblog \
+ libstlport \
+ libcrypto
+
+static_libraries := \
+ libvold \
+ libgtest \
+ libgtest_main
+
+c_includes := \
+ external/openssl/include \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport
+
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+ $(eval LOCAL_SRC_FILES := $(file)) \
+ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+ $(eval include $(BUILD_EXECUTABLE)) \
+)
diff --git a/tests/VolumeManager_test.cpp b/tests/VolumeManager_test.cpp
new file mode 100644
index 0000000..c0c1fa5
--- /dev/null
+++ b/tests/VolumeManager_test.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+#include <errno.h>
+
+#define LOG_TAG "VolumeManager_test"
+#include <utils/Log.h>
+#include <openssl/md5.h>
+#include "../VolumeManager.h"
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class VolumeManagerTest : public testing::Test {
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+};
+
+TEST_F(VolumeManagerTest, AsecHashTests) {
+ char buffer[MD5_ASCII_LENGTH_PLUS_NULL];
+ char* dst = reinterpret_cast<char*>(&buffer);
+
+ const char* src1 = "";
+ const char* exp1 = "d41d8cd98f00b204e9800998ecf8427e";
+
+ EXPECT_TRUE(VolumeManager::asecHash(exp1, (char*)NULL, sizeof(buffer)) == NULL && errno == ESPIPE)
+ << "Should return NULL and set errno to ESPIPE when destination buffer is NULL";
+ EXPECT_TRUE(VolumeManager::asecHash(exp1, dst, 0) == NULL && errno == ESPIPE)
+ << "Should return NULL and set errno to ESPIPE when destination buffer length is 0";
+ EXPECT_TRUE(VolumeManager::asecHash((const char*)NULL, dst, sizeof(buffer)) == NULL && errno == ESPIPE)
+ << "Should return NULL and set errno to ESPIPE when source buffer is NULL";
+
+ EXPECT_FALSE(VolumeManager::asecHash(src1, dst, sizeof(buffer)) == NULL)
+ << "Should not return NULL on valid source, destination, and destination size";
+ EXPECT_STREQ(exp1, dst)
+ << "MD5 summed output should match";
+
+ const char* src2 = "android";
+ const char* exp2 = "c31b32364ce19ca8fcd150a417ecce58";
+ EXPECT_FALSE(VolumeManager::asecHash(src2, dst, sizeof(buffer)) == NULL)
+ << "Should not return NULL on valid source, destination, and destination size";
+ EXPECT_STREQ(exp2, dst)
+ << "MD5 summed output should match";
+}
+
+}