From 431444c47e8c19b7765ae2edcf2a37db02bb20b5 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Thu, 22 Jun 2017 12:29:13 +0200
Subject: [PATCH 01/16] [SystemInfo] Fix for "BATTERY" property value change
listener callbacks
Callbacks called on "BATTERY" property value change threw an exception,
if "lowThreshold" or "highThreshold" SystemInfoOptions were specified.
[Verification] Tested in Chrome DevTools, registered callbacks work
fine.
Change-Id: Ie50dfb0710e9b203e072ff5336b77ff27c464031
Signed-off-by: Pawel Wasowski
---
src/systeminfo/systeminfo_api.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/systeminfo/systeminfo_api.js b/src/systeminfo/systeminfo_api.js
index 2e5dc4f..bb656c0 100644
--- a/src/systeminfo/systeminfo_api.js
+++ b/src/systeminfo/systeminfo_api.js
@@ -898,13 +898,13 @@ function _systeminfoBatteryListenerCallback(eventObj) {
for (var watchId in callbacks) {
if (callbacks.hasOwnProperty(watchId)) {
var listener = callbacks[watchId];
+ var propObj = !listener.isArrayType ?
+ _createProperty(property, eventObj.result.array[0]) :
+ _createPropertyArray(property, eventObj.result);
var executeCall = (T_.isUndefined(listener.lowThreshold) ||
(propObj.level <= listener.lowThreshold)) ||
(T_.isUndefined(listener.highThreshold) ||
(propObj.level >= listener.highThreshold));
- var propObj = !listener.isArrayType ?
- _createProperty(property, eventObj.result.array[0]) :
- _createPropertyArray(property, eventObj.result);
if (executeCall) {
listener.callback(propObj);
}
--
2.7.4
From 8cce89cd15716deacefede58942ea342009ad928 Mon Sep 17 00:00:00 2001
From: Lukasz Bardeli
Date: Wed, 28 Jun 2017 08:24:32 +0200
Subject: [PATCH 02/16] [Application][Alarm] Free app_control_h using
app_control_destroy
[Verification] Code compiles without error. TCT passrate
Alarm 100%
AppControl 100%
Application 100%
Change-Id: I5c32e2307d9b7e8b36df0919c670c97b5828a572
---
src/alarm/alarm_utils.cc | 26 ++++++++++++++++++++------
src/application/application_utils.cc | 23 +++++++++++++++++------
2 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/src/alarm/alarm_utils.cc b/src/alarm/alarm_utils.cc
index 1c9ee9d..ba8872c 100755
--- a/src/alarm/alarm_utils.cc
+++ b/src/alarm/alarm_utils.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include
+
#include "alarm_utils.h"
#include "common/logger.h"
@@ -34,9 +36,19 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
}
- app_control_create(app_control);
+ app_control_h app_control_tmp = nullptr;
+ int result = app_control_create(&app_control_tmp);
+
+ if (APP_CONTROL_ERROR_NONE != result) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Creation AppControl failed.",
+ ("Problem with create handle."));
+ }
+
+ std::unique_ptr::type, int(*)(app_control_h)> app_control_ptr(
+ app_control_tmp, &app_control_destroy);
+
- int ret = app_control_set_operation(*app_control, it_operation->second.get().c_str());
+ int ret = app_control_set_operation(app_control_tmp, it_operation->second.get().c_str());
if (APP_CONTROL_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error while setting operation.",
("Failed app_control_set_operation(): %d (%s)", ret, get_error_message(ret)));
@@ -44,7 +56,7 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
const auto it_uri = obj.find("uri");
if (it_end != it_uri && it_uri->second.is()) {
- ret = app_control_set_uri(*app_control, it_uri->second.get().c_str());
+ ret = app_control_set_uri(app_control_tmp, it_uri->second.get().c_str());
if (APP_CONTROL_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error while setting uri.",
("Failed app_control_set_uri(): %d (%s)", ret, get_error_message(ret)));
@@ -53,7 +65,7 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
const auto it_mime = obj.find("mime");
if (it_end != it_mime && it_mime->second.is()) {
- ret = app_control_set_mime(*app_control, it_mime->second.get().c_str());
+ ret = app_control_set_mime(app_control_tmp, it_mime->second.get().c_str());
if (APP_CONTROL_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error while setting mime.",
("Failed app_control_set_mime(): %d (%s)", ret, get_error_message(ret)));
@@ -62,7 +74,7 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
const auto it_category = obj.find("category");
if (it_end != it_category && it_category->second.is()) {
- ret = app_control_set_category(*app_control, it_category->second.get().c_str());
+ ret = app_control_set_category(app_control_tmp, it_category->second.get().c_str());
if (APP_CONTROL_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error while setting category.",
("Failed app_control_set_category(): %d (%s)", ret, get_error_message(ret)));
@@ -75,7 +87,7 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
for (auto iter = data.begin(); iter != data.end(); ++iter) {
- result = AppControlToServiceExtraData(iter->get(), app_control);
+ result = AppControlToServiceExtraData(iter->get(), &app_control_tmp);
if (!result) {
LoggerE("Failed AppControlToServiceExtraData()");
return result;
@@ -83,6 +95,8 @@ PlatformResult AppControlToService(const picojson::object& obj, app_control_h *a
}
}
+ *app_control = app_control_ptr.release();
+
return PlatformResult(ErrorCode::NO_ERROR);
}
diff --git a/src/application/application_utils.cc b/src/application/application_utils.cc
index a7860c1..8d56999 100644
--- a/src/application/application_utils.cc
+++ b/src/application/application_utils.cc
@@ -207,24 +207,33 @@ PlatformResult ApplicationUtils::ApplicationControlToService(
return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter was passed.");
}
- app_control_create(app_control);
+ app_control_h app_control_tmp = nullptr;
+ int result = app_control_create(&app_control_tmp);
+
+ if (APP_CONTROL_ERROR_NONE != result) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Creation AppControl failed.",
+ ("Problem with create handle."));
+ }
+
+ std::unique_ptr::type, int(*)(app_control_h)> app_control_ptr(
+ app_control_tmp, &app_control_destroy);
// operation
- app_control_set_operation(*app_control, it_operation->second.get().c_str());
+ app_control_set_operation(app_control_tmp, it_operation->second.get().c_str());
// uri
if (it_uri->second.is()) {
- app_control_set_uri(*app_control, it_uri->second.get().c_str());
+ app_control_set_uri(app_control_tmp, it_uri->second.get().c_str());
}
// mime
if (it_mime->second.is()) {
- app_control_set_mime(*app_control, it_mime->second.get().c_str());
+ app_control_set_mime(app_control_tmp, it_mime->second.get().c_str());
}
// category
if (it_category->second.is()) {
- app_control_set_category(*app_control, it_category->second.get().c_str());
+ app_control_set_category(app_control_tmp, it_category->second.get().c_str());
}
// ApplicationControlData
@@ -233,7 +242,7 @@ PlatformResult ApplicationUtils::ApplicationControlToService(
for (auto iter = data.begin(); iter != data.end(); ++iter) {
if (iter->is()) {
PlatformResult ret =
- ApplicationControlDataToServiceExtraData(iter->get(), *app_control);
+ ApplicationControlDataToServiceExtraData(iter->get(), app_control_tmp);
if (ret.IsError()) {
LoggerE("Failed ApplicationControlDataToServiceExtraData()");
return ret;
@@ -241,6 +250,8 @@ PlatformResult ApplicationUtils::ApplicationControlToService(
}
}
+ *app_control = app_control_ptr.release();
+
return PlatformResult(ErrorCode::NO_ERROR);
}
--
2.7.4
From 5d1ec94bd224dbde3b64ba124f8e6f2ad0bdd486 Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Wed, 28 Jun 2017 08:48:39 +0200
Subject: [PATCH 03/16] [version] 1.88
Change-Id: I8944a33b7b9421c481f988f09f753c668fae927c
Signed-off-by: Piotr Kosko
---
packaging/webapi-plugins.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index 737966a..e823e27 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -10,7 +10,7 @@
%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 1.87
+Version: 1.88
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
--
2.7.4
From 3b71b0bac5e1bb09c50c97168dba1619b3ed40d6 Mon Sep 17 00:00:00 2001
From: Jakub Skowron
Date: Fri, 30 Jun 2017 16:02:34 +0200
Subject: [PATCH 04/16] [Utils] Fix privilege bypass, StringCopy function
User could redefine String and String.indexOf to bypass privilege
check and to go outside of virtual-root by ../ in path
Change-Id: Ia9f7210ba685d1df18c9c443706361f624a38c1e
Signed-off-by: Jakub Skowron
---
src/filesystem/js/common.js | 2 ++
src/utils/utils_api.js | 66 ++++++++++++++++++++++++++++++---------------
2 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/src/filesystem/js/common.js b/src/filesystem/js/common.js
index adf52c7..e900cb3 100644
--- a/src/filesystem/js/common.js
+++ b/src/filesystem/js/common.js
@@ -169,6 +169,8 @@ var commonFS_ = (function() {
}
function checkPathWithoutDots(aPath) {
+ aPath = xwalk.utils.StringCopy(aPath);
+
if (-1 !== aPath.indexOf('/../')) {
return false;
}
diff --git a/src/utils/utils_api.js b/src/utils/utils_api.js
index 3c4d46e..b9a4a83 100644
--- a/src/utils/utils_api.js
+++ b/src/utils/utils_api.js
@@ -3,20 +3,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-//Object xwalk.JSON - guaranteed to not being modified by the application programmer
-var JSON_ = {stringify: JSON.stringify, parse: JSON.parse};
-Object.freeze(JSON_);
-exports.JSON = JSON_;
+//We're in a function set up by XWALK which 'use strict' mode,
+//so we use below function to get out of the strict mode to get global 'this'
+var _global = (new Function('return this'))();
+
+var shallow_copy_own_elements = function(orig) {
+ var copy = {};
+ //copy only own properties
+ var names = Object.getOwnPropertyNames(orig);
+ for( var i in names ) {
+ var key = names[i]
+ copy[key] = orig[key];
+ }
+ return copy;
+};
-var _enableJsLogs = false;
+//xwalk.JSON: guaranteed to not being modified by the application programmer
+exports.JSON = shallow_copy_own_elements(JSON);
+Object.freeze(exports.JSON);
-var _global = {};
-if (typeof window != 'undefined') {
- _global = window;
-}
-else if (typeof global != 'undefiend') {
- _global = global;
-}
+var _enableJsLogs = false;
/**
* @deprecated Used only by validateArguments()
@@ -146,6 +152,21 @@ function Utils() {
});
}
+var origString = String;
+var StringPrototypeCopy = shallow_copy_own_elements(String.prototype);
+Object.freeze(StringPrototypeCopy);
+
+var StringCopy = function(str) {
+ return Object.setPrototypeOf( new origString(str), StringPrototypeCopy );
+};
+StringCopy.fromCharCode = String.fromCharCode;
+StringCopy.fromCodePoint = String.fromCodePoint;
+StringCopy.raw = String.raw;
+Object.freeze(StringCopy);
+
+//xwalk.utils.StringCopy: returns a sanitized version of String - user cannot modify its prototype
+Utils.prototype.StringCopy = StringCopy;
+
Utils.prototype.error = console.error.bind(console);
Utils.prototype.warn = console.warn.bind(console);
Utils.prototype.log = _enableJsLogs ? console.log.bind(console) : function(){};
@@ -331,8 +352,9 @@ Type.prototype.isUndefined = function(obj) {
};
Type.prototype.isA = function(obj, type) {
- var clas = Object.prototype.toString.call(obj).slice(8, -1);
- return (obj !== undefined) && (obj !== null) && (clas === type);
+ return obj !== undefined && obj !== null &&
+ obj.constructor !== null && obj.constructor !== undefined &&
+ obj.constructor.name === type;
};
Type.prototype.isEmptyObject = function(obj) {
@@ -475,7 +497,7 @@ Converter.prototype.toDouble = function(val, nullable) {
};
function _toString(val) {
- return String(val);
+ return StringCopy(val).toString();
}
Converter.prototype.toString = function(val, nullable) {
@@ -1018,7 +1040,7 @@ var NativeManager = function(extension) {
});
extension_.setMessageListener(function(json) {
- var msg = JSON_.parse(json);
+ var msg = exports.JSON.parse(json);
var id;
if (msg.hasOwnProperty(this.CALLBACK_ID_KEY)) {
@@ -1082,7 +1104,7 @@ NativeManager.prototype.call = function(cmd, args, callback) {
};
NativeManager.prototype.callSync = function(cmd, args) {
- var request = JSON_.stringify({
+ var request = exports.JSON.stringify({
cmd: cmd,
args: args || {}
});
@@ -1092,7 +1114,7 @@ NativeManager.prototype.callSync = function(cmd, args) {
/* C++ extension didn't set sync response using Instance::SendSyncReply */
throw new WebAPIException(WebAPIException.ABORT_ERR, "Internal error");
}
- return JSON_.parse(response);
+ return exports.JSON.parse(response);
};
NativeManager.prototype.sendRuntimeMessage = function(msg, body) {
@@ -1346,13 +1368,13 @@ var NativeBridge = (function (extension, debug) {
var Bridge = function () {};
Bridge.prototype = {
sync: function (data) {
- var json = JSON_.stringify({
+ var json = exports.JSON.stringify({
cmd: data.cmd,
args: data
});
if (debug) xwalk.utilss.log('bridge.sync, json: ' + json);
var result = extension.internal.sendSyncMessage(json);
- var obj = JSON_.parse(result);
+ var obj = exports.JSON.parse(result);
if (obj.error)
throw new WebAPIException(obj.code, obj.name, obj.message);
return obj.result;
@@ -1360,7 +1382,7 @@ var NativeBridge = (function (extension, debug) {
async: function (data) {
var l = new Listener();
data.cid = Listeners.getInstance().add(l);
- var json = JSON_.stringify({
+ var json = exports.JSON.stringify({
cmd: data.cmd,
args: data
});
@@ -1398,7 +1420,7 @@ var NativeBridge = (function (extension, debug) {
*/
if (debug) xwalk.utils.log('bridge.setMessageListener, json: ' + json);
- var data = JSON_.parse(json);
+ var data = exports.JSON.parse(json);
if (data.cid && data.action) {
setTimeout(function() {
Listeners.getInstance().resolve(data.cid, data.action, data.args, data.keep);
--
2.7.4
From d5bd447a6a340355b9fe73fef974e71c1d1a9866 Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Wed, 5 Jul 2017 09:10:11 +0200
Subject: [PATCH 05/16] [version] 1.89
Change-Id: Icf0dcfdfa530d3fad644cc560a00ea1933064188
Signed-off-by: Piotr Kosko
---
packaging/webapi-plugins.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index e823e27..ad09fb8 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -10,7 +10,7 @@
%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 1.88
+Version: 1.89
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
--
2.7.4
From 6c92d0b126ad6ba3e86976708879ceacbd1b0cb3 Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Mon, 10 Jul 2017 11:46:02 +0200
Subject: [PATCH 06/16] [Filesystem] Support for 2GB+ files added
[Feature] Plugins are build with '-D_FILE_OFFSET_BITS=64' flag to
support files larger that 2GB.
[Verification] Code compiles without errors.
TCT passrate 100%.
Checked in console with code:
// bigfiletest contains 4GB file
tizen.filesystem.resolve(
'images/bigfiletest',
function(dir) {
function onsuccess(files) {
for (var i = 0; i < files.length; i++) {
console.log(files[i].name + " size: " + files[i].fileSize );
}
}
dir.listFiles(onsuccess);
}, function(e) {
console.log("Error: " + e.message);
}, "r"
);
/// result
// BIG.txt size: 4294967296
Change-Id: I21513b533eeee0294267888d416ec3d0a85c91bf
Signed-off-by: Piotr Kosko
---
src/filesystem/filesystem.gyp | 3 +++
src/filesystem/filesystem_stat.h | 7 ++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/filesystem/filesystem.gyp b/src/filesystem/filesystem.gyp
index 0ab9152..9a3c737 100644
--- a/src/filesystem/filesystem.gyp
+++ b/src/filesystem/filesystem.gyp
@@ -30,6 +30,9 @@
'filesystem_utils.cc',
'filesystem_utils.h',
],
+ 'cflags': [
+ '-D_FILE_OFFSET_BITS=64',
+ ],
'conditions': [
[ 'tizen == 1', {
'variables': { 'packages': [
diff --git a/src/filesystem/filesystem_stat.h b/src/filesystem/filesystem_stat.h
index 87e7e47..a984ab1 100755
--- a/src/filesystem/filesystem_stat.h
+++ b/src/filesystem/filesystem_stat.h
@@ -39,7 +39,12 @@ class FilesystemStat {
bool readOnly;
std::time_t ctime;
std::time_t mtime;
- size_t size;
+
+#ifndef __USE_FILE_OFFSET64
+ __off_t size;
+#else
+ __off64_t size;
+#endif
size_t nlink;
picojson::value toJSON() const;
--
2.7.4
From 1d4ef70b38e9279d1933d8a8fc873a498e17c25c Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Mon, 10 Jul 2017 12:31:20 +0200
Subject: [PATCH 07/16] [FMRadio] Fixing memory leak
There was a memory leak, which happened when user called
tizen.fmradio.scanStop, after starting scanning.
user_data was allocated in method FMRadioManager::ScanStart
but it was lost when scanning was interrupted.
FMRadio TCT passed 100%.
Signed-off-by: Szymon Jastrzebski
Change-Id: I2f4b8b74c8a7703dd9d31f5ca8e338caa5e90c45
---
src/radio/radio_manager.cc | 38 ++++++++++++++++++++------------------
src/radio/radio_manager.h | 19 +++++++++++++++++++
2 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/src/radio/radio_manager.cc b/src/radio/radio_manager.cc
index a6871a8..d94f4e9 100755
--- a/src/radio/radio_manager.cc
+++ b/src/radio/radio_manager.cc
@@ -111,21 +111,6 @@ double ToMHz(int frequency) {
return static_cast(frequency) / 1000.0;
}
-struct RadioData {
- explicit RadioData(FMRadioManager& manager)
- : manager_(manager),
- callback_id_(0.0) {
- }
-
- FMRadioManager& manager_;
- double callback_id_;
-};
-
-struct RadioScanData : public RadioData {
- using RadioData::RadioData;
- std::vector frequencies_;
-};
-
void RadioSeekCallback(int frequency, void* user_data) {
LoggerD("Enter, freq: %d", frequency);
@@ -181,6 +166,7 @@ void ScanCompleteCallback(void* user_data) {
common::TaskQueue::GetInstance().Async(std::bind(&PostAsyncSuccess,
&data->manager_, data->callback_id_, event));
+ data->manager_.SetScanData(nullptr);
delete data;
}
@@ -190,6 +176,8 @@ void ScanStopCallback(void *user_data) {
common::TaskQueue::GetInstance().Async(std::bind(
&FMRadioManager::PostResultCallbackSuccess, &data->manager_, data->callback_id_));
+ delete data->manager_.GetScanData();
+ data->manager_.SetScanData(nullptr);
delete data;
}
@@ -250,6 +238,14 @@ bool FMRadioManager::IsMuted() {
return muted;
}
+RadioScanData *FMRadioManager::GetScanData() {
+ return this->scan_data;
+}
+
+void FMRadioManager::SetScanData(RadioScanData *scan_data) {
+ this->scan_data = scan_data;
+}
+
void FMRadioManager::SetMute(bool mute) {
LoggerD("Enter");
@@ -332,7 +328,8 @@ double FMRadioManager::GetSignalStrength() {
FMRadioManager::FMRadioManager(RadioInstance& instance)
: instance_(instance),
- radio_instance_(nullptr) {
+ radio_instance_(nullptr),
+ scan_data(nullptr) {
LoggerD("Enter");
const auto err = radio_create(&radio_instance_);
@@ -352,9 +349,8 @@ FMRadioManager::~FMRadioManager() {
if (RADIO_ERROR_NONE != err) {
LoggerE("radio_destroy() failed: %d", err);
}
-
- radio_instance_ = nullptr;
}
+ delete scan_data;
}
PlatformResult FMRadioManager::Start(double frequency) {
@@ -468,7 +464,9 @@ void FMRadioManager::ScanStart(double callback_id) {
radio_unset_scan_completed_cb(radio_instance_);
PostResultFailure(callback_id, GetPlatformResult("radio_scan_start", err));
delete user_data;
+ return;
}
+ this->scan_data = user_data;
}
void FMRadioManager::ScanStop(double callback_id) {
@@ -483,6 +481,8 @@ void FMRadioManager::ScanStop(double callback_id) {
PostResultFailure(callback_id,
GetPlatformResult("radio_unset_scan_completed_cb", err));
delete user_data;
+ delete this->scan_data;
+ this->scan_data = nullptr;
return;
}
@@ -491,6 +491,8 @@ void FMRadioManager::ScanStop(double callback_id) {
LoggerE("Failed");
PostResultFailure(callback_id, GetPlatformResult("radio_scan_stop", err));
delete user_data;
+ delete this->scan_data;
+ this->scan_data = nullptr;
}
}
diff --git a/src/radio/radio_manager.h b/src/radio/radio_manager.h
index 614f415..fd9ea34 100755
--- a/src/radio/radio_manager.h
+++ b/src/radio/radio_manager.h
@@ -32,6 +32,7 @@ namespace extension {
namespace radio {
class RadioInstance;
+struct RadioScanData;
class FMRadioManager {
public:
@@ -52,6 +53,8 @@ class FMRadioManager {
common::PlatformResult UnsetAntennaChangeListener();
bool IsMuted();
+ RadioScanData *GetScanData();
+ void SetScanData(RadioScanData *scan_data);
void SetMute(bool mute);
common::PlatformResult SetFrequency(double frequency);
double GetFrequency();
@@ -67,6 +70,22 @@ class FMRadioManager {
private:
RadioInstance& instance_;
radio_h radio_instance_;
+ RadioScanData *scan_data;
+};
+
+struct RadioData {
+ explicit RadioData(FMRadioManager& manager)
+ : manager_(manager),
+ callback_id_(0.0) {
+ }
+
+ FMRadioManager& manager_;
+ double callback_id_;
+};
+
+struct RadioScanData : public RadioData {
+ using RadioData::RadioData;
+ std::vector frequencies_;
};
} // namespace radio
--
2.7.4
From 4c236233a4dbfee12a27efcc30a25a442471d97c Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Fri, 7 Jul 2017 14:41:54 +0200
Subject: [PATCH 08/16] [Messaging] Replacing call of email_attachment_data_t
structure constructor to calloc
Native function email_free_attachment_data uses free() to release allocated
memory pointing by tmp. Thus, we should call calloc() instead of structure's
constructor.
Messaging-email TCT passed 100%.
Change-Id: Ib81f1da2e0270cfa76aef0eab7005d968c1f102c
Signed-off-by: Szymon Jastrzebski
---
src/messaging/message.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/messaging/message.cc b/src/messaging/message.cc
index bdd7873..57703b1 100755
--- a/src/messaging/message.cc
+++ b/src/messaging/message.cc
@@ -591,7 +591,7 @@ PlatformResult addSingleEmailAttachment(std::shared_ptr message,
PlatformResult ret = copyFileToTemp(att->getFilePath(), &dirPath);
if (ret.IsError()) return ret;
- email_attachment_data_t* tmp = new email_attachment_data_t();
+ email_attachment_data_t* tmp = (email_attachment_data_t*)calloc(1, sizeof(email_attachment_data_t));
tmp->attachment_name = strdup(att->getShortFileName().c_str());
tmp->attachment_path = strdup(std::string(dirPath + "/"
+ att->getShortFileName()).c_str());
--
2.7.4
From c89325b9add59ed08e7b4900b58083c11b56a717 Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Mon, 10 Jul 2017 13:12:39 +0200
Subject: [PATCH 09/16] [Bluetooth] Fixing memory leak
user_data was lost when native function app_control_send_launch_request
returned value different from APP_CONTROL_ERROR_NONE.
In case of fail, we need to delete allocated memory manually.
TCT bluetooth passed 100%.
Change-Id: I5aa08bfdda97a5dfab7718177be0fbb3f4c9dae0
Signed-off-by: Szymon Jastrzebski
---
src/bluetooth/bluetooth_adapter.cc | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/bluetooth/bluetooth_adapter.cc b/src/bluetooth/bluetooth_adapter.cc
index dd30661..126de34 100755
--- a/src/bluetooth/bluetooth_adapter.cc
+++ b/src/bluetooth/bluetooth_adapter.cc
@@ -602,6 +602,7 @@ void BluetoothAdapter::SetPowered(const picojson::value& data, picojson::object&
ret = LogAndCreateResult(
ErrorCode::UNKNOWN_ERR, "app control set launch request failed",
("app control set launch request failed: %d", err));
+ delete user_data;
} else {
this->requested_powered_ = new_powered;
this->user_request_list_[SET_POWERED] = true;
--
2.7.4
From 71285dffa6192c4e1a719941272100145bed228d Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Wed, 12 Jul 2017 11:28:36 +0200
Subject: [PATCH 10/16] [version] 1.90
Change-Id: Iae694af4c97bdd2a918a8a2ca59d2633f1863b7b
Signed-off-by: Piotr Kosko
---
packaging/webapi-plugins.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index ad09fb8..9d193c9 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -10,7 +10,7 @@
%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 1.89
+Version: 1.90
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
--
2.7.4
From e7a3c0c0f7c3c2788bea8e7294696deabf2feff6 Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Thu, 13 Jul 2017 08:19:53 +0200
Subject: [PATCH 11/16] [Contact] Fixing bug when adding Contact to AddressBook
There was a bug, which caused application to crash everytime
when adding more than one nickname.
In every iteration of nicknames, the same nickname-handler
was added to parent-handler. The crash happened during attempting
to free parent-handler with all its children (double free).
Contact TCT passed 100%.
Change-Id: Ibaddf2ce17aacb6dcf40422fc0303ec5e1142089
Signed-off-by: Szymon Jastrzebski
---
src/contact/contact_util.cc | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/src/contact/contact_util.cc b/src/contact/contact_util.cc
index bcccd3b..6251ee1 100755
--- a/src/contact/contact_util.cc
+++ b/src/contact/contact_util.cc
@@ -584,39 +584,29 @@ PlatformResult ExportContactNameToContactsRecord(
for (auto& nickname : nicknames) {
contacts_record_h nickname_record = nullptr;
- err = contacts_record_get_child_record_at_p(
- contacts_record, _contacts_contact.nickname, 0, &nickname_record);
- if (CONTACTS_ERROR_NONE != err && nullptr == nickname_record) {
- err = contacts_record_create(_contacts_nickname._uri, &nickname_record);
- PlatformResult status =
- ContactUtil::ErrorChecker(err, "Contacts record create error");
- if (status.IsError()) {
- LoggerE("Error: %s", status.message().c_str());
- return status;
- }
-
- update = false;
+ err = contacts_record_create(_contacts_nickname._uri, &nickname_record);
+ PlatformResult status = ContactUtil::ErrorChecker(err, "Contacts record create error");
+ if (status.IsError()) {
+ LoggerE("Error: %s", status.message().c_str());
+ return status;
}
ContactsRecordHPtr nickname_ptr(&nickname_record, ContactsDeleter);
- PlatformResult status =
- ContactUtil::SetStrInRecord(*nickname_ptr, _contacts_nickname.name,
- JsonCast(nickname).c_str());
+ status = ContactUtil::SetStrInRecord(*nickname_ptr, _contacts_nickname.name,
+ JsonCast(nickname).c_str());
if (status.IsError()) {
LoggerE("Error: %s", status.message().c_str());
return status;
}
- if (!update) {
- err = contacts_record_add_child_record(
- contacts_record, _contacts_contact.nickname, *nickname_ptr);
- PlatformResult status =
- ContactUtil::ErrorChecker(err, "Contacts record add child error");
- if (status.IsError()) {
- LoggerE("Error: %s", status.message().c_str());
- return status;
- }
+ err = contacts_record_add_child_record(contacts_record, _contacts_contact.nickname,
+ *nickname_ptr);
+ status = ContactUtil::ErrorChecker(err, "Contacts record add child error");
+ if (status.IsError()) {
+ LoggerE("Error: %s", status.message().c_str());
+ return status;
}
+
// Do not delete record, it is passed to the platform
nickname_ptr.release();
}
--
2.7.4
From 797bf22c8636937caf9e4f48187bb22591ff742d Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Thu, 13 Jul 2017 21:57:37 +0200
Subject: [PATCH 12/16] [Application] Fix category array population bug
Problem: application's categories were not passed from C++ to JS layer
Verification: it has been proved in tests in Chrome DevTools, that
application's categories may be obtained with Application API
TCT Application pass rate: 100%
Change-Id: I0995cd464315c9194196874fa488d52de49b1e69
Signed-off-by: Pawel Wasowski
---
src/application/application_utils.cc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/application/application_utils.cc b/src/application/application_utils.cc
index 8d56999..060dd09 100644
--- a/src/application/application_utils.cc
+++ b/src/application/application_utils.cc
@@ -77,7 +77,6 @@ void ApplicationUtils::CreateApplicationInformation(const pkgmgrinfo_appinfo_h h
// categories
picojson::value categories = picojson::value(picojson::array());
picojson::array& categories_array = categories.get();
- app_info->insert(std::make_pair("categories", categories));
ret = pkgmgrinfo_appinfo_foreach_category(
handle,
@@ -92,6 +91,8 @@ void ApplicationUtils::CreateApplicationInformation(const pkgmgrinfo_appinfo_h h
},
&categories_array);
+ app_info->insert(std::make_pair("categories", categories));
+
if (PMINFO_R_OK != ret) {
LoggerE("Failed to get categories: %d (%s)", ret, get_error_message(ret));
}
--
2.7.4
From 53b941ffca00a9cc12d3207280f179f16452cbba Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Fri, 7 Jul 2017 18:02:53 +0200
Subject: [PATCH 13/16] [EXIF] Fix privilege issue
Problem: implementation of getExifInfo() used Web API filesystem
resolve() function to check, if file exists on the device. Use of this
function required declaring http://tizen.org/privilege/filesystem.read.
File existence checking has been implemented in EXIF plugin and does not
require declaring any additional privileges.
[Verification] TCT EXIF: 100% pass rate,
manuall tests with Chrome DevTools did not show any problems
Change-Id: Id9d19965eddb31902f14817eac0bd5ad897f1568
Signed-off-by: Pawel Wasowski
---
src/common/tools.cc | 55 +++++++++++++++++++++++++++++++++++++++++++++++
src/common/tools.h | 6 ++++++
src/exif/exif_api.js | 21 ++----------------
src/exif/exif_instance.cc | 16 ++++++++++++++
4 files changed, 79 insertions(+), 19 deletions(-)
diff --git a/src/common/tools.cc b/src/common/tools.cc
index 638352f..cd8beea 100644
--- a/src/common/tools.cc
+++ b/src/common/tools.cc
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#ifdef PRIVILEGE_USE_DB
#include
@@ -480,5 +481,59 @@ char* BinToHex(const unsigned char* bin, int size, char* hex, int hex_size) {
return hex;
}
+bool IsPathValid(const std::string& path) {
+ LoggerD("Enter");
+
+ /*
+ * Directory dot-referencing is not allowed
+ */
+ return std::string::npos == path.find("/../") &&
+ std::string::npos == path.find("/./") &&
+ 0 != path.find("./") &&
+ 0 != path.find("../") &&
+ path.length() - 2 != path.rfind("/.") &&
+ path.length() - 3 != path.rfind("/..");
+}
+
+PlatformResult CheckFileStatus(const std::string& path) {
+ LoggerD("Enter");
+
+ struct stat buf;
+
+ if (stat(path.c_str(), &buf)) {
+ LoggerD("Failed to stat path: %s", path.c_str());
+
+ if (ENOENT == errno) {
+ return PlatformResult(ErrorCode::NOT_FOUND_ERR, "File does not exist: " + path);
+ } else if (EACCES == errno) {
+ return PlatformResult(ErrorCode::IO_ERR, "The user cannot access the file: " + path);
+ }
+
+ LoggerD("stat() error: %s", common::tools::GetErrorString(errno).c_str());
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get status of the file: " + path);
+ }
+
+ if (!S_ISREG(buf.st_mode)) {
+ return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Path does not point to a regular file: "
+ + path);
+ }
+
+ if (!(S_IRUSR & buf.st_mode)) {
+ return PlatformResult(ErrorCode::IO_ERR, "The user cannot read the file: " + path);
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CheckFileAvailability(const std::string& path) {
+ LoggerD("Enter");
+
+ if (!IsPathValid(path)) {
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid path: " + path);
+ }
+
+ return CheckFileStatus(path);
+}
+
} // namespace tools
} // namespace common
diff --git a/src/common/tools.h b/src/common/tools.h
index 5d8eec6..fc905ec 100644
--- a/src/common/tools.h
+++ b/src/common/tools.h
@@ -85,6 +85,12 @@ int HexToInt(char c);
unsigned char* HexToBin(const char* hex, int size, unsigned char* bin, int bin_size);
char* BinToHex(const unsigned char* bin, int size, char* hex, int hex_size);
+bool IsPathValid(const std::string& path);
+
+PlatformResult CheckFileStatus(const std::string& path);
+
+PlatformResult CheckFileAvailability(const std::string& path);
+
} // namespace tools
} // namespace common
diff --git a/src/exif/exif_api.js b/src/exif/exif_api.js
index d209d8a..3040336 100644
--- a/src/exif/exif_api.js
+++ b/src/exif/exif_api.js
@@ -205,7 +205,6 @@ ExifManager.prototype.getExifInfo = function() {
if (native_.isFailure(result)) {
native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
} else {
-
// call to c++ code. Fields that do not exist are undefined.
var exifInfoNative = native_.getResultObject(result);
@@ -218,15 +217,7 @@ ExifManager.prototype.getExifInfo = function() {
}
};
- tizen.filesystem.resolve(args.uri,
- function() {
- native_.call('ExifManager_getExifInfo', {'uri': args.uri}, callback);
- },
- function() {
- native_.callIfPossible(args.errorCallback, new WebAPIException(
- WebAPIException.NOT_FOUND_ERR,
- 'File can not be found.'));
- });
+ native_.call('ExifManager_getExifInfo', {'uri': args.uri}, callback);
};
ExifManager.prototype.saveExifInfo = function() {
@@ -316,15 +307,7 @@ ExifManager.prototype.getThumbnail = function() {
}
};
- tizen.filesystem.resolve(args.uri,
- function() {
- native_.call('ExifManager_getThumbnail', {'uri': args.uri}, _callback);
- },
- function() {
- native_.callIfPossible(args.errorCallback, new WebAPIException(
- WebAPIException.NOT_FOUND_ERR,
- 'File can not be found.'));
- });
+ native_.call('ExifManager_getThumbnail', {'uri': args.uri}, _callback);
};
tizen.ExifInformation = function() {
diff --git a/src/exif/exif_instance.cc b/src/exif/exif_instance.cc
index 8be6a26..6f0101a 100755
--- a/src/exif/exif_instance.cc
+++ b/src/exif/exif_instance.cc
@@ -26,6 +26,7 @@
#include "common/logger.h"
#include "common/platform_result.h"
#include "common/task-queue.h"
+#include "common/tools.h"
#include "exif/exif_information.h"
#include "exif/exif_util.h"
@@ -62,6 +63,13 @@ void ExifInstance::ExifManagerGetExifInfo(const picojson::value& args, picojson:
PlatformResult status(ErrorCode::NO_ERROR);
const std::string &file_path = ExifUtil::convertUriToPath(uri);
+
+ PlatformResult fileAvailability(common::tools::CheckFileAvailability(file_path));
+ if (!fileAvailability) {
+ LogAndReportError(fileAvailability, &response->get());
+ return;
+ }
+
LoggerD("file_path = %s", file_path.c_str());
status = GetExifInfo::LoadFromURI(uri, &result);
@@ -128,6 +136,14 @@ void ExifInstance::ExifManagerGetThumbnail(const picojson::value& args,
JsonValue result = JsonValue(JsonObject());
JsonObject &result_obj = result.get();
+ PlatformResult fileAvailability(common::tools::CheckFileAvailability(file_path));
+ if (!fileAvailability) {
+ LogAndReportError(fileAvailability, &response->get());
+ return;
+ }
+
+ LoggerD("file_path = %s", file_path.c_str());
+
std::string ext = file_path.substr(file_path.find_last_of(".") + 1);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
--
2.7.4
From 0c75237768f62a473b054feeb7c31c56c156f67f Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Tue, 18 Jul 2017 11:20:35 +0200
Subject: [PATCH 14/16] [Systeminfo] Fixed condition, which caused to call
successCallback when not needed
According to documentation, the successCallback is called in
4 different possible situations.
The condition, which fills the requirements is optimized.
[Verification] SystemInfo TCT passed 100%.
Change-Id: Ie6b24853ed233ecb8ac9d5ee28677e84d2b22f2f
Signed-off-by: Szymon Jastrzebski
---
src/systeminfo/systeminfo_api.js | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/src/systeminfo/systeminfo_api.js b/src/systeminfo/systeminfo_api.js
index bb656c0..63b3e5e 100644
--- a/src/systeminfo/systeminfo_api.js
+++ b/src/systeminfo/systeminfo_api.js
@@ -901,10 +901,20 @@ function _systeminfoBatteryListenerCallback(eventObj) {
var propObj = !listener.isArrayType ?
_createProperty(property, eventObj.result.array[0]) :
_createPropertyArray(property, eventObj.result);
- var executeCall = (T_.isUndefined(listener.lowThreshold) ||
- (propObj.level <= listener.lowThreshold)) ||
- (T_.isUndefined(listener.highThreshold) ||
- (propObj.level >= listener.highThreshold));
+ /*
+ * According to documentation, the condition should look like this:
+ *
+ * (T_.isUndefined(listener.lowThreshold) && T_.isUndefined(listener.highThreshold)) ||
+ * (!T_.isUndefined(listener.lowThreshold) && !T_.isUndefined(listener.highThreshold) && (propObj.level <= listener.lowThreshold || propObj.level >= listener.highThreshold)) ||
+ * (!T_.isUndefined(listener.lowThreshold) && (propObj.level <= listener.lowThreshold)) ||
+ * (!T_.isUndefined(listener.highThreshold) && (propObj.level >= listener.highThreshold))
+ *
+ * but it can be optimized like this:
+ */
+ var executeCall = (T_.isUndefined(listener.lowThreshold) && T_.isUndefined(listener.highThreshold)) ||
+ (!T_.isUndefined(listener.lowThreshold) && propObj.level <= listener.lowThreshold) ||
+ (!T_.isUndefined(listener.highThreshold) && propObj.level >= listener.highThreshold);
+
if (executeCall) {
listener.callback(propObj);
}
@@ -922,10 +932,12 @@ function _systeminfoCpuListenerCallback(eventObj) {
var propObj = !listener.isArrayType ?
_createProperty(property, eventObj.result.array[0]) :
_createPropertyArray(property, eventObj.result);
- var executeCall = (T_.isUndefined(listener.lowThreshold) ||
- (propObj.load <= listener.lowThreshold)) ||
- (T_.isUndefined(listener.highThreshold) ||
- (propObj.load >= listener.highThreshold));
+ /*
+ * Optimized condition:
+ * */
+ var executeCall = (T_.isUndefined(listener.lowThreshold) && T_.isUndefined(listener.highThreshold)) ||
+ (!T_.isUndefined(listener.lowThreshold) && propObj.load <= listener.lowThreshold) ||
+ (!T_.isUndefined(listener.highThreshold) && propObj.load >= listener.highThreshold);
if (executeCall) {
listener.callback(propObj);
}
@@ -958,10 +970,12 @@ function _systeminfoDisplayListenerCallback(eventObj) {
var propObj = !listener.isArrayType ?
_createProperty(property, eventObj.result.array[0]) :
_createPropertyArray(property, eventObj.result);
- var executeCall = (T_.isUndefined(listener.lowThreshold) ||
- (propObj.brightness <= listener.lowThreshold)) ||
- (T_.isUndefined(listener.highThreshold) ||
- (propObj.brightness >= listener.highThreshold));
+ /*
+ * Optimized condition:
+ * */
+ var executeCall = (T_.isUndefined(listener.lowThreshold) && T_.isUndefined(listener.highThreshold)) ||
+ (!T_.isUndefined(listener.lowThreshold) && propObj.brightness <= listener.lowThreshold) ||
+ (!T_.isUndefined(listener.highThreshold) && propObj.brightness >= listener.highThreshold);
if (executeCall) {
listener.callback(propObj);
}
--
2.7.4
From 557cd7f81bb475633bdaa8147bdce701880d1674 Mon Sep 17 00:00:00 2001
From: Lukasz Bardeli
Date: Wed, 19 Jul 2017 09:07:36 +0200
Subject: [PATCH 15/16] [version] 1.91
Change-Id: I253cb2dfb07843f3a46694eba5a69719d6006450
---
packaging/webapi-plugins.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index 9d193c9..926b460 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -10,7 +10,7 @@
%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 1.90
+Version: 1.91
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
--
2.7.4
From f0e83be2b496b74fa0dd5b8cc597a0b78141a360 Mon Sep 17 00:00:00 2001
From: Szymon Jastrzebski
Date: Wed, 19 Jul 2017 12:35:55 +0200
Subject: [PATCH 16/16] [SystemInfo] Adding casting int to double + fix
InchToMm constant
SVACE detected problem with code NO_CAST.INTEGER_DIVISION.
[Verification] Code compiles, TCT SystemInfo passed 100%.
Change-Id: Ie6249780860cd61a8c331d77648b6d37b9241c4c
Signed-off-by: Szymon Jastrzebski
---
src/systeminfo/systeminfo_properties_manager.cc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/systeminfo/systeminfo_properties_manager.cc b/src/systeminfo/systeminfo_properties_manager.cc
index 8a5c6e4..75bb33c 100644
--- a/src/systeminfo/systeminfo_properties_manager.cc
+++ b/src/systeminfo/systeminfo_properties_manager.cc
@@ -42,7 +42,7 @@ using common::ErrorCode;
namespace {
const std::string kMemoryStateNormal = "NORMAL";
const std::string kMemoryStateWarinig = "WARNING";
-const double kDisplayInchToMillimeter = 2.54;
+const double kDisplayInchToMillimeter = 25.4;
//Battery
const double kRemainingBatteryChargeMax = 100.0;
const int kVconfErrorNone = 0;
@@ -306,7 +306,7 @@ PlatformResult SysteminfoPropertiesManager::ReportDisplay(picojson::object* out)
//FETCH PHYSICAL WIDTH
if (dotsPerInchWidth != 0 && screenWidth != 0) {
- physicalWidth = (screenWidth / dotsPerInchWidth) * kDisplayInchToMillimeter;
+ physicalWidth = (static_cast(screenWidth) / dotsPerInchWidth) * kDisplayInchToMillimeter;
} else {
std::string log_msg = "Failed to get physical screen width value";
LoggerE("%s, screenWidth : %d, dotsPerInchWidth: %d", log_msg.c_str(),
@@ -315,7 +315,7 @@ PlatformResult SysteminfoPropertiesManager::ReportDisplay(picojson::object* out)
//FETCH PHYSICAL HEIGHT
if (dotsPerInchHeight != 0 && screenHeight != 0) {
- physicalHeight = (screenHeight / dotsPerInchHeight) * kDisplayInchToMillimeter;
+ physicalHeight = (static_cast(screenHeight) / dotsPerInchHeight) * kDisplayInchToMillimeter;
} else {
std::string log_msg = "Failed to get physical screen height value";
LoggerE("%s, screenHeight : %d, dotsPerInchHeight: %d", log_msg.c_str(),
--
2.7.4