Strange unicode characters when reading in file in node.js app - javascript

I am attempting to write a node app that reads in a set of files, splits them into lines, and puts the lines into an array. Pretty simple. It works on quite a few files except some SQL files that I am working with. For some reason I seem to be getting some kind of unicode output when I split the lines up. The app looks something like this:
fs = require("fs");
var data = fs.readFileSync("test.sql", "utf8");
console.log(data);
lines = data.split("\n");
console.log(lines);
The input file looks something like this:
use whatever
go
The output looks like this:
��use whatever
go
[ '��u\u0000s\u0000e\u0000 \u0000w\u0000h\u0000a\u0000t\u0000e\u0000v\u0000e\u0000r\u0000',
'\u0000g\u0000o\u0000',
'\u0000' ]
As you can see there is some kind of unrecognized character at the beginning of the file. After reading the data in and directly outputting it, it looks okay except for this character. However, if I then attempt to split it up into lines, I get all these unicode-like characters. Basically it's all the actual characters with "\u0000" at the beginning of each one.
I have no idea what's going on here but it appears to have something to do with the characters in the file itself. If I copy and paste the text of the file into another new file and run the app on the new file, it works fine. I assume that whatever is causing this issue is being stripped out during the copy and paste process.

Your file is in UTF-16 Little Big Endian, not UTF-8.
var data = fs.readFileSync("test.sql", "utf16le"); //Not sure if this eats the BOM
Unfortunately node.js only supports UTF-16 Little Endian or UTF-16LE (Can't be sure from reading docs, there is a slight difference between them; namely that UTF-16LE does not use BOMs), so you have to use iconv or convert the file to UTF-8 some other way.
Example:
var Iconv = require('iconv').Iconv,
fs = require("fs");
var buffer = fs.readFileSync("test.sql"),
iconv = new Iconv( "UTF-16", "UTF-8");
var result = iconv.convert(buffer).toString("utf8");

Is this perhaps the BOM (Byte-Order-Mark)? Make sure you save your files without the BOM or include code to strip the BOM.
The BOM is usually invisible in text editors.
I know Notepad++ has a feature where you can easily strip a BOM from a file. Encoding > Encode in UTF-8 without BOM.

I did the following in Windows command prompt to convert the endianness:
type file.txt > file2.txt

Use the lite version of Iconv-lite
var result= "";
var iconv = require('iconv-lite');
var stream = fs.createReadStream(sourcefile)
.on("error",function(err){
//handle error
})
.pipe(iconv.decodeStream('win1251'))
.on("error",function(err){
//handle error
})
.on("data",function(data){
result += data;
})
.on("end",function(){
//use result
});

Related

In Javascript, how do I decode a string in which decoded string contains binary (e.g. non UTF-8) data?

I have a base64 string that represents binary data (e.g. not a nice readable string after you decode it or UTF-8 data otherwise this answer would help me -- Using Javascript's atob to decode base64 doesn't properly decode utf-8 strings). My JS Is
var byteCharacters = atob(base64str);
which results in
InvalidCharacterError: Failed to execute 'atob' on 'WorkerGlobalScope': The string to be decoded contains characters outside of the Latin1 range.
How do I decode a base 64 string that is not ASCII (or even UTF-8 data)?
Edit: Here's an example of the type of string I'm talking about. Using Mac, I can base64 encode a file like so
openssl base64 -in ~/Downloads/star.jpg -out ~/Downloads/star.base64
Here's the resulting base64 string. If you can decode this with JS tools, you've solved the problem. Got the below by doing "cat myfile.base64" so hopefully "cat" or my cutting and pasting didn't introduce any weird characters here.
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
AABJRU5ErkJggg==
Last edit: More publicity should made of this sentence from the 2015 related SO answer
The original solution (deprecated)
When mentioning atob, btoa, base64js and other libraries functions: save your time with a library and deprecate atob and btoa
Try base64.js.toByteArray with your data. Follow the link to the library Github Readme: it says it does exactly what you want, well, only that from and to.
Tested #1.3.0 succesfully with your data base64js.min.js on Chrome 66.0.3359.181
Tested #1.3.0 succesfully with your data in Nodejs #4.4.7
quote from the README:
base64js has three exposed functions, byteLength, toByteArray and fromByteArray, which both take a single argument.
byteLength - Takes a base64 string and returns length of byte array
toByteArray - Takes a base64 string and returns a byte array
fromByteArray - Takes a byte array and returns a base64 string
I would also test original binary data against whatever file type/structure it is supposed to be/have, if you can access it.
Did you test the base64 string against base64, at first, is it a proper base64 string?
To be fair a code Example link and more information in the Github repo, when included as script in the client, use:
var byteArray = base64js.toByteArray(myBase64Str)
In Node, you would do:
var fs = require('fs')
var base64js = require('base64-js')
fs.readFile('pathToMyBase64File', 'utf8', (err, data) => { // here 'utf8' is mandatory
if (err) throw err;
var byteArray = base64js.toByteArray(data)
console.log(base64js.byteLength(data) == byteArray.length)
})
Important, myBase64File should be encoded with utf-8 w/BOM or it won´t work.
P.S. : I am not any contributor to this library, just a good tool for everybody to know, LICENSE MIT.
As I already mentioned in the comments, the problem is with encoding.
Your shared base64 string has a lot of newlines('\n') in it.
Newlines are added (by cat) for user readability. But they cause troubles while decoding.
If you try after removing all '\n' in your string and try atob(), it should be working.
To get base64 string without spaces or '\n'
In Linux
$ base64 -w 0 ~/Downloads/star.jpg >~/Downloads/star.base64
In Mac, you may try -A option in openssl.
$ openssl base64 -A -in ~/Downloads/star.jpg -out ~/Downloads/star.base64
Please try atob() with the resulting string (Copy directly from file not from cat output).
Note:I'm not a Mac user
You could try the following code:
function decode_base64(s) {
var b=l=0, r='',
m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
s.split('').forEach(function (v) {
b=(b<<6)+m.indexOf(v); l+=6;
if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
});
return r;
}
Then you can create an async function that can do your job:
function decode_base64_async(s, cb) {
setTimeout(function () { cb(decode_base64(s)); }, 0);
}
P.S: I've not checked this code for non-ASCII characters, so you need to try it

Indesign Javascript load a file from serverpath

I have a problem with Indesign.
I have a document, where I want to add a picture programmatically.
This is easy, when I use a picture on my localdrive. But I want to add a picture from a server path like \myserver\pictures\pic.jpg
I tried it like I add a picture from localdrive
var f = new File("\\myserver\pictures\pic.jpg");
imgPicture.place(f, false);
Then the value in f is
//myserver/pictures/pic.jpg
I build a try catch around it. The errorMessage is undefined.
I get the same error, when i use the networkdrive letter, like
/x/pictures/pic.jpg
As i saw in the documentation for the file-object, there is only one string-parameter for the path.
Is there a solution?
On an other forum, I found a thread where someone had the same problem. But he did a dirty way to solved it. He did a fileOpenDialog and pasted the link to the file and then it downloads the file to the temp directory.
I can't do this, because I have on my server about 100,000 pictures.
Thanks for help.
Another issue of yours may be that backslash may be interpreted as escaping character thus resulting in something like : \myserverpicturespic.jpg" So you may need to escape the escaping character like : "\\myserver\pictures\pic.jpg" and then pass this string. Finally, when I have a doubt about a file path, I usually use this bit of code :
var f = File.openDialog();
if ( f ) $.writeln ( f.fsName );
FWIW
Loic
I can not get the value of f with the forward slashes as you do. I tried your code and it works fine for me if I pass the file-path as
var f = new File("//myserver/pictures/pic.jpg");
You could convert you path with .toString().replace(/\/g, '/')
Also try to replace spaces in the filepath with
CS 5.5 OSX 10.9

Javascript DOMParser and XMLSerialier removes XML entities

I am trying to preserve some XML entities when parsing XML files in javascript. The following code snippet illustrates the problem. Is there a way for me to make round-trip parse and retain the XML entities (  is nbsp; html)? This happens in Chrome FF and IE10.
var aaa='<root><div> one two</div></root>'
var doc=new DOMParser().parseFromString(aaa,'application/xml')
new XMLSerializer().serializeToString(doc)
"<root><div> one two</div></root>"
The issue is I am taking some chunks out of html and storing them in xml, and then I want to get the spaces back in XML when I'm done.
Edit:
As Dan and others have pointed out, the parser replaces it with the ascii code 160, which to my eyes looks like an ordinary space but:
var str1=new XMLSerializer().serializeToString(doc)
str1.charCodeAt(15)
160
So where ever my application is losing the spaces, it is not here.
You can use a ranged RegExp to turn the special chars back into xml representations.
as a nice re-usable function:
function escapeExtended(s){
return s.replace(/([\x80-\xff])/g, function (a, b) {
var c = b.charCodeAt();
return "&#" + b.charCodeAt()+";"
});
}
var aaa='<root><div> one two</div></root>'
var doc=new DOMParser().parseFromString(aaa,'application/xml')
var str= new XMLSerializer().serializeToString(doc);
alert(escapeExtended(str)); // shows: "<root><div> one two</div></root>"
Note that HTML entities (ex quot;) will lose their symbol name, and be converted to XML entities (the &#number; kind). you can't get back the names without a huge conversion table.

DOM Exception 5 INVALID CHARACTER error on valid base64 image string in javascript

I'm trying to decode a base64 string for an image back into binary so it can be downloaded and displayed locally by an OS.
The string I have successfully renders when put as the src of an HTML IMG element with the data URI preface (data: img/png;base64, ) but when using the atob function or a goog closure function it fails.
However decoding succeeds when put in here: http://www.base64decode.org/
Any ideas?
EDIT:
I successfully got it to decode with another library other than the built-in JS function. But, it still won't open locally - on a Mac says it's damaged or in an unknown format and can't get opened.
The code is just something like:
imgEl.src = 'data:img/png;base64,' + contentStr; //this displays successfully
decodedStr = window.atob(contentStr); //this throws the invalid char exception but i just
//used a different script to get it decode successfully but still won't display locally
the base64 string itself is too long to display here (limit is 30,000 characters)
I was just banging my head against the wall on this one for awhile.
There are a couple of possible causes to the problem. 1) Utf-8 problems. There's a good write up + a solution for that here.
In my case, I also had to make sure all the whitespace was out of the string before passing it to atob. e.g.
function decodeFromBase64(input) {
input = input.replace(/\s/g, '');
return atob(input);
}
What was really frustrating was that the base64 parsed correctly using the base64 library in python, but not in JS.
I had to remove the data:audio/wav;base64, in front of the b64, as this was given as part of the b64.
var data = b64Data.substring(b64Data.indexOf(',')+1);
var processed = atob(data);

Returning a byte string to ExternalInterface.call throws an error

I am working on my open source project Downloadify, and up until now it simply handles returning Strings in response to ExternalInterface.call commands.
I am trying to put together a test case using JSZip and Downloadify together, the end result being that a Zip file is created dynamically in the browser, then saved to the disk using FileReference.save. However, this is my problem:
The JSZip library can return either a base64 encoded string of the Zip, or the raw byte string. The problem is, if I return that byte string in response to the ExternalInterface.call command, I get this error:
Error #1085: The element type "string" must be terminated by the matching end-tag "</string>"
ActionScript 3:
var theData:* = ExternalInterface.call('Downloadify.getTextForSave',queue_name);
Where queue_name is just a string used to identify the correct instance in JS.
JavaScript:
var zip = new JSZip();
zip.add("test.txt", "Hello world!\n");
var content = zip.generate(true);
return content;
If I instead return a normal string instead of the byte string, the call works correctly.I would like to avoid using base64 as I would have to include a base64 decoder in my swf which will increase its size.
Finally: I am not looking for a AS3 Zip generator. It is imperative to my project to have that part run in JavaScript
I am admittedly not a AS3 programmer by trade, so if you need any more detail please let me know.
When data is being returned from javascript calls it's being serialized into an XML string. So if the "raw string" returned by JSZip will include characters which make the XML non-valid, which is what I think is happening here, you'll get errors like that.
What you get as a return is actually:
<string>[your JSZip generated string]</string>
Imagine your return string includes a "<" char - this will make the xml invalid, and it's hard to tell what character codes will a raw byte stream translate too.
You can read more about the external API's XML format on LiveDocs
i think the problem is caused by the fact, that flash expects a utf8 String and you throw some binary stuff at it. i think for example 0x00FF will not turn out to be valid utf8 ...
you can try fiddling around with flash.system::System.setCodePage, but i wouldn't be too optimistic ...
i guess a base64 decoder is probably really the easiest ... i'd rather worry about speed than about file size though ... this rudimentary decoder method uses less than half a K:
public function decodeBase64(source:String):ByteArray {
var ret:ByteArray = new ByteArray();
var map:Object = new Object();
var i:int = 0;
for each (var char:String in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("")) map[char] = i++;
map["="] = 0;
source = source.split("\n").join("").split("\r").join("");//remove linebreaks
for (i = 0; i < source.length/4; i++) {
var buf:int = 0;
for each (char in source.substr(i * 4, 4).split("")) buf = (buf << 6) + map[char];
ret.writeByte(buf >>> 16);
ret.writeShort(buf);
}
return ret;
}
you could simply shorten function names and take a smaller image ... or use ColorTransform or ConvolutionFilter on one image instead of four ... or compile the image into the SWF for smaller overall size ... or reduce function name length ...
so unless you're planning on working with MBs of data, this is the way to go ...

Categories