How do I put SAFEARRAY (array of bytes) to HTML Hidden field - javascript

I'd like to get array of bytes from active-x component, store that in html-form input hidden field and then pass it to server via form-submit. How can I do that?
MIDL:
HRESULT Data([out, retval] SAFEARRAY(VARIANT) *pArray);
C++/ATL
STDMETHODIMP MyActiveX::get_Data(SAFEARRAY **pArray)
{
CComSafeArray<BYTE> arr;
for (int i = 0; i < 10; i++)
{
CComVariant a;
a = (BYTE)i;
arr.Add(a);
}
arr.CopyTo(pArray);
return S_OK;
}
Javascript:
$("#hiddenField").val(myActiveX.Data);
Browser tells me: type mismatch

Although I am not familiar with your exact situation, I have seen some similar situations before.
You are correct to put your data in a field using $('#hiddenField'). If you've put a name attribute on that field so that it becomes part of the HTTP submit, that part is good.
As for myActiveX.Data, I imagine that this is some sort of JavaScript object. Remember that only a string can be put into an HTML input; it does not hold binary data.
What I would do is put a breakpoint before $("#hiddenField").val(myActiveX.Data);
. Use the debugger keyword if you're not familiar with it. Run the code in your debugger and look at the structure of the value of myActiveX.Data. It probably has some sort of wrapper field.
Alternatively, if you don't have access to a good JavaScript debugger, try the following"
for(x in myActiveX.Data)
alert(x + ": " + myActiveX.Data[x]);

I'm assuming the C++ code is the server side code.
The best way to handle this is to serialise the SAFEARRAY. From there you can handle it in two ways.
Firstly, the serialisation. I've looked at MSDN and I think using LPSAFEARRAY_Marshal and LPSAFEARRAY_Unmarshal (with an optional IDispatch or IUnknown IID to specify the type, but the documentation doesn't say how it's used) or LPSAFEARRAY_UserMarshal and LPSAFEARRAY_UserUnmarshal to convert the SAFEARRAY to/from a serialised format.
Secondly, handling the data transfer.
Option 1: Save the serialised data on the server side and put a token representing the saved file into the hidden field.
Option 2: Use Hex, Base64, etc. to encode the data into a printable format and putting that data into the hidden field.
Either way, when you need to get the data back, just de-serialise it with the matching function.

Related

Javascript crashes on special characters from query string

To use this value in my TypeScript I am getting it from my query string like this:
var UserName = #Request.QueryString["UserName"];
But I get a Unexpeted Identifier error on it because if in DevTool if I go to where it breaks that query string has a value like this:
var UserName = ANT -- ANT 37690 / THIRD PARTY
So is there a way to do some kind of sanitation on it so it wouldn't crash? I guess there are illegal characters in that value for JS?
The error has nothing to do with "special" characters, but with the fact that the right side of the assignment - unwrapped in quotes - contains what js engine views as unknown identifier[s].
One way to properly format data that becomes part of javascript code is to use JavaScriptSerializer class from System.Web.Script.Serialization namespace.
var UserName = #new System.Web.Script.Serialization.JavaScriptSerializer().Seria‌​lize(Request.Query‌​St‌​ring["UserName"]);
The shorter version of this for a string is:
var UserName = "#System.Web.HttpUtility.JavaScriptStringEncode(Request.Query‌​St‌​ring["UserName"])";
or overloaded version that wraps the result in double quotes:
var UserName = #System.Web.HttpUtility.JavaScriptStringEncode(Request.Query‌​St‌​ring["UserName"], true);
You need to include quotes for the value.
var UserName = "#(Request.QueryString["UserName"])";
Otherwise the name will come through verbatim in your code and cause the problems you are seeing.
There is no need to protect against an attack vector here as the user can alter the page as they see fit at any time with a user script, and the QueryString is entered by them and only seen as a result by them in this scenario.
If there was a need to scrub the user input, it should be done prior to it actually reaching the view on server side. However, if still concerned about scrubbing output into a view in this type of scenario in general, it would be prudent to include an encode from razor's library.
var sanitizedJsVariable = "#System.Web.HttpUtility.JavaScriptStringEncode(model.VariableFromServer)";

UTF-8 symbol is converted when inserted to dom

I have a following problem, i am building app that uses data stream from ajax calls, the data that is coming is therefore escaped inside json string.
example: 1°Set
When i insert that data to DOM it is being converted like this: 1°Set
I dont use any libraries like jQuery, pure Javascript.
I tried to store converted name also in another place but i cannot seem to convert it manually, i tried following functions:
var test = function(str) {
console.log(unescape(encodeURIComponent(str)) );
console.log(decodeURIComponent(escape(str)) );
};
test('1°Set');
It stays the same, does anyone have an idea how to convert it to a DOM like version?
I have a following problem, i am building app that uses data stream from ajax calls, the data that is coming is therefore escaped inside json string.
example: 1°Set
Sounds like you're having a problem because your backend serves a JSON that looks like:
{
"something": "1°Set"
}
Instead of a string "1°Set", you're serving HTML source code that amounts to "1°Set". This looks very unnecessary. I cannot see a good reason of using HTML escaping inside JSON, unless you actually want your JSON to actually contain a part of HTML source (with formatting and everything), rather than just a string.
My suggestion: Let's keep it simple and instead serve something like:
{
"something": "1°Set"
}
or equivalently escape it properly using JSON syntax:
{
"something": "1\u00b0Set"
}
Now you'll JavaScript will receive a plain string that can be easily displayed, for example inside element.textContent or element.value or anywhere else. You won't even need any conversions.

"Fixing" JSON coming out of MySQL

I'm fetching JSON code stored in MySQL and it has extra slashes, which I have to remove in order to parse it in JavaScript, after I print it on the page. Right now I'm doing the following:
$save = str_replace("\n", "<br>", $save); // Replace new line characters with <br>
$save = str_replace('\\"', '"', $save); // top-level JSON
$save = str_replace('\\\\"', '\"', $save); // HTML inside top level JSON
$save = str_replace('\\\\\\\\\\"', '\\\\\"', $save); // HTML inside second level JSON
Here is an example JSON code, as it comes out from MySQL:
{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}
And here is how it's supposed to look in order to get parsed correctly (using jsonlint.com to test):
{"id":2335,"editor":{"selected_shape":"spot-7488"},"general":{"name":"HTML Test","shortcode":"html-test","width":1280,"height":776},"spots":[{"id":"spot-7488","x":9.9,"y":22.6,"default_style":{"use_icon":1},"tooltip_content":{"content_type":"content-builder","plain_text":"<p class=\"test\">Test</p>","squares_json":"{\"containers\":[{\"id\":\"sq-container-293021\",\"settings\":{\"elements\":[{\"settings\":{\"name\":\"Paragraph\",\"iconClass\":\"fa fa-paragraph\"},\"options\":{\"text\":{\"text\":\"<p class=\\\"test\\\">Test</p>\"}}}]}}]}"}}]}
Please note that I have HTML code inside JSON, which is inside another JSON and this is where it gets a bit messy.
My question - is there a function or library for PHP (for JS will work too) which covers all those corner cases, because I'm sure someone will find a way to break the script.
Thanks!
The short answer, which is woefully inadequate, is for you to use stripslashes. The reason this answer is not adequate is that your JSON string might have been escaped or had addslashes called on it multiple times and you would have to call stripslashes precisely once for each time this had happened.
The proper solution is to find out where the slashes are being added and either a) avoid adding the slashes or b) understand why the slashes are there and respond accordingly. I strongly believe that the process that creates that broken JSON is where the problem lies.
Slashes are typically added in PHP in a few cases:
magic_quotes are turned on. This is an old PHP feature which has been removed. The basic idea is that PHP used to auto-escape quotes in incoming requests to let you just cram incoming strings into a db. Guess what? NOT SAFE.
add_slashes has been called. Why call this? Some folks use it as an incorrect means of escaping data before sticking stuff in a db. Others use it to keep HTML from breaking when echoing variables out (htmlspecialchars should probably be used instead). It can also come in handy in a variety of other meta situations when you are defining code in a string.
When escaping data input. The most common escaping function is mysqli_real_escape_string. It's very important to escape values before inserting them in a db to prevent sql injection and other exploits but you should never escape things twice.
So there's a possibility that your code is double-escaping things or that addslashes is getting called or something like magic_quotes is causing the problem, but I suspect it is another problem: some JS code might be supplying this JSON not as a proper JSON string, but one that has been escaped so to define a string within javascript.
If you take your example JSON string above, and slap some quotes around it:
var myJSON = "<put your string here>";
then SURPRISE your javascript is not broken and the var myJSON contains a string that is actually valid JSON and can be parsed into an a valid JSON object:
var myJSON = "{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}";
console.log(JSON.parse(myJSON)); // this is an actual object
The key here is to examine the point of entry where this JSON arrives in your system. I suspect some AJAX request has created some object and rather than sending valid JSON Of that object, it is sending instead an escaped string of a JSON object.
EDIT:
Here's a simple example of what happens when you have too many encodings. Try running this JS in your browser and observe the console output:
var myObj = {"key":"here is my value"};
console.log(myObj);
var myJSON = JSON.stringify(myObj);
console.log(myJSON);
var doubleEncoded = JSON.stringify(myJSON);
console.log(doubleEncoded);

Is there a javascript equivalent of htmlencode / htmldecode from asp.net?

The problem is this:
You have a textbox, you type in some text, send it to the server. On another page, that value is retrieved and displayed on screen in a textbox and a label.
It's important to stop scripting attacks, and asp.net won't let you submit unsafe code, so on submit you javascript replace < with < and the same for >
When the values are retrieved from the server, they will come back with < and > which is fine for displaying in the label, but when put into the textbox, they must be replaced back to < and >
The data should be stored securely in the database as other people might use this content. From a safety point of view I'd like to call htmlencode on it then store it. It is this encoded html I'd like to display in the label on the client, but the decoded version I'd like to display in the textbox.
So what I need, is a htmldecode solution in javascript. htmlencode/decode replaces more than just < > and without a definitive list I can't create my own method. Is there a solution out there?
Instead of trying to turn a string of text into HTML and then adding it to the document using innerHTML; use standard DOM methods.
myElement.appendChild(
document.createTextNode(myString)
);

store return json value in input hidden field

I was wondering if it's possible to store the return json in a hidden input field. For example this is what my json return:
[{"id":"15aea3fa","firstname":"John","lastname":"Doe"}]
I would like to just store the id in a hidden field so I can reference it later to do something with it.
Example: I have something like this:
<input id="HiddenForId" type="hidden" value="" />
and would like jquery to return the value later to me like so:
var scheduletimeid = $('#HiddenForId').val();
Although I have seen the suggested methods used and working, I think that setting the value of an hidden field only using the JSON.stringify breaks the HTML...
Here I'll explain what I mean:
<input type="hidden" value="{"name":"John"}">
As you can see the first double quote after the open chain bracket could be interpreted by some browsers as:
<input type="hidden" value="{" rubbish >
So for a better approach to this I would suggest to use the encodeURIComponent function. Together with the JSON.stringify we shold have something like the following:
> encodeURIComponent(JSON.stringify({"name":"John"}))
> "%7B%22name%22%3A%22John%22%7D"
Now that value can be safely stored in an input hidden type like so:
<input type="hidden" value="%7B%22name%22%3A%22John%22%7D">
or (even better) using the data- attribute of the HTML element manipulated by the script that will consume the data, like so:
<div id="something" data-json="%7B%22name%22%3A%22John%22%7D"></div>
Now to read the data back we can do something like:
> var data = JSON.parse(decodeURIComponent(div.getAttribute("data-json")))
> console.log(data)
> Object {name: "John"}
You can use input.value = JSON.stringify(obj) to transform the object to a string.And when you need it back you can use obj = JSON.parse(input.value)
The JSON object is available on modern browsers or you can use the json2.js library from json.org
You can store it in a hidden field, OR store it in a javascript object (my preference) as the likely access will be via javascript.
NOTE: since you have an array, this would then be accessed as myvariable[0] for the first element (as you have it).
EDIT show example:
clip...
success: function(msg)
{
LoadProviders(msg);
},
...
var myvariable ="";
function LoadProviders(jdata)
{
myvariable = jdata;
};
alert(myvariable[0].id);// shows "15aea3fa" in the alert
EDIT: Created this page:http://jsfiddle.net/GNyQn/ to demonstrate the above. This example makes the assumption that you have already properly returned your named string values in the array and simply need to store it per OP question. In the example, I also put the values of the first array returned (per OP example) into a div as text.
I am not sure why this has been viewed as "complex" as I see no simpler way to handle these strings in this array.
If you use the JSON Serializer, you can simply store your object in string format as such
myHiddenText.value = JSON.stringify( myObject );
You can then get the value back with
myObject = JSON.parse( myHiddenText.value );
However, if you're not going to pass this value across page submits, it might be easier for you, and you'll save yourself a lot of serialization, if you just tuck it away as a global javascript variable.
It looks like the return value is in an array? That's somewhat strange... and also be aware that certain browsers will allow that to be parsed from a cross-domain request (which isn't true when you have a top-level JSON object).
Anyway, if that is an array wrapper, you'll want something like this:
$('#my-hidden-field').val(theObject[0].id);
You can later retrieve it through a simple .val() call on the same field. This honestly looks kind of strange though. The hidden field won't persist across page requests, so why don't you just keep it in your own (pseudo-namespaced) value bucket? E.g.,
$MyNamespace = $MyNamespace || {};
$MyNamespace.myKey = theObject;
This will make it available to you from anywhere, without any hacky input field management. It's also a lot more efficient than doing DOM modification for simple value storage.
just set the hidden field with javascript :
document.getElementById('elementId').value = 'whatever';
or do I miss something?
base64 solution
// encode
theInput.value = btoa(JSON.stringify({ test: true }));
// decode
let decoded = JSON.parse(atob(theInput.value));
Why base64?
The input field may be processed by a backend that runs in a different programming language than JavaScript. For instance, in PHP, rawurlencode implementation is slightly different from JavaScript encodeURIComponent. By encoding it in base64, you are sure that whatever other programming language runs on the backend, it will process it as expected.

Categories

Resources