Path separator for Atom / JavaScript on Windows - javascript

I have developed an Atom package which calls SyncTeX (a utility for reverse lookup for LaTeX), and then opens in Atom the file specified in the SyncTeX response. I'm developing on Linux, but now a user on Windows tells me that this doesn't work.
In detail: SyncTeX returns a pathname like C:\data\tex\main.tex, with Windows-appropriate backslash separators. My package then calls atom.workspace.open with exactly that returned string, which leads to a JavaScript error (file not found).
Strangely, if the string is modified to use forward slashes instead, C:/data/tex/main.tex, the call works and the file is opened.
My questions:
Is this behavior specific to Atom, or to some underlying technology (JavaScript, Electron, Node, ...)? I was unable to find any documentation on this.
Since the replacement \ → / is apparently necessary, is there a preferred way to implement it? Would a simple String.replace be adequate?
Do I risk breaking compatibility with other platforms if I always do the replacement?

By my best knowledge paths with forward slashes '/' work well everywhere except Windows XP.

Related

How to make python dictionary from big Javascript object

I have one string. which represents JavaScript object.
https://docs.google.com/document/d/1CFONQntMFMdtD-04rk9uut4UpLyB_OSsDH0bwDZ0tuM/edit?usp=sharing
When i'm using json.loads() python raises Exception: JSONDecodeError: Extra data.
What i'm doing wrong?
P.S.: It's dynamic object, I can't change him
As #DSupreme says, there are extra characters in your data.
This can be caused from various reasons, one being stringifying JSON files and parsing in different programs and languages. If you need to verify if a JSON string is in a correct format, you can use verifying tools such as http://jsonlint.com/ .
For your specific problem, there is an extra ' at the beginning of your string, / for escaping characters and you're also missing the double quote in the end of your string.
Is this what you are looking for
Things i changed:
Removed ' in the beginning
Remove extra / used for escaping double quotes
Added double quotes in the end
{"log_timeout":1000,"featureFlags":{"serverRenderingForBotsOnly":false,"experienceLevelOnFixedPriceJobs":true,"JSUIPaymentVerified":true,"JSUI736SaveSearchRedesign":true,"JSUI341ProposalsFilter":true},"csrfTokenCookieName":"XSRF-TOKEN","csrfTokenHeaderName":"X-Odesk-Csrf-Token","runtime_id":"32a28ec0399c4e8a-DME","clientStatsDMetrics":true,"smfAjax":false,"pageSpeedMetrics":false,"ccstCookieName":"oauth2_global_js_token","pageId":"User","isSearchWithEmptyParams":false,"queryParsedParams":{"q":"python"},"jobs":[{"title":"Python
app engine, Linux,
infrastructure","createdOn":"2017-01-31T16:57:42+00:00","type":2,"ciphertext":"~01440d6a85cc997768","description":"If
you know python and have at least some knowledge of app engine
development. Willing to learn and positive. A big plus if you have
worked with the linux environment and knows how to set up servers on
google-cloud or AWS. \n\nWe can offer a job for a longer period of
time if you are the right fit.\n\nAt least 5 years experience as a
developer required.","category2":"Web, Mobile & Software
Dev","subcategory2":"Other - Software
Development","skills":[{"name":"google-app-engine","prettyName":"Google
App Engine"},{"name":"python","prettyName":"Python"}],"duration":"1 to
3 months","engagement":"30+
hrs\/week","amount":{"currencyCode":"USD","amount":0},"recno":209422776,"client":{"paymentVerificationStatus":null,"location":{"country":null},"totalSpent":0,"totalReviews":0,"totalFeedback":0,"companyRid":0,"companyName":null,"edcUserId":0,"lastContractPlatform":null,"lastContractRid":0,"lastContractTitle":null,"feedbackText":"No
feedback
yet"},"freelancersToHire":0,"relevanceEncoded":"{}","maxAmount":{"currencyCode":"USD","amount":0},"enterpriseJob":false,"tierText":"Intermediate
($$)","isSaved":false,"feedback":null,"proposalsTier":"5 to
10","isApplied":false,"sticky":true,"stickyLabel":"Interesting
Job","jobTs":"1485881862000"},{"title":"Python</span>
Developer","createdOn":"2017-02-01T04:00:20+00:00","type":2,"ciphertext":"~019767ae6381e97a90","description":"Python</span> Developer who can read and
understand the legacy script and apply that understanding to an
existing Python business \nservice. ... Python Developer who can read
and understand the legacy script and apply that understanding to an
existing Python</span> business
\nservice.",
"category2":"Web,
Mobile & Software Dev",
"subcategory2":"Other - Software Development",
"skills":[],
"duration":"Less than 1 week",
"engagement":"Less than 10"
}
Problem was in { } at the end and begin of the string

encodeURIComponent encodes differently, depending on environment

I am passing an object via the url using:
encodeURIComponent(JSON.stringify(myObject))
"ä" is encoded as "%C3%A4" on my local server.
Unfortunately it is encoded as "a%CC%88" on the webserver.
Which breaks my app because it is part of the name of a database field which isn't found when wrong encoded. And I can't control that there are no ä's in field names because the app allows users to upload their own data.
How can I make sure that "ä" is always encoded correctly?
SORRY. To make this clear: The encoding happens both times client-side in the browser. But when the web-app is served from the webserver the "ä" is encoded as "%C3%A4" instead of "a%CC%88" (I've tested both in the same chrome browser)
Thanks for all your help. It got me to dig deeper:
I have code that runs on an event. It loops through checkboxes and creates an array of objects containing (also) the field names. The code gets the field names from an attribute named "feld" of the checkbox:
<div class="checkbox">
<label>
<input class="feld_waehlen" type="checkbox" dstyp="Taxonomie" datensammlung="SISF Index 2 (2005)" feld="Artname vollständig">Artname vollständig
</label>
</div>
running this code:
console.log("this.getAttribute('feld') = " + this.getAttribute('feld'));
gives as expected: $(this).attr('feld') = Artname vollständig
If while looping, I run:
console.log('encodeURIComponent("Artname vollständig") = ' + encodeURIComponent("Artname vollständig"));
the answer is correct: encodeURIComponent("Artname vollständig") = Artname%20vollst%C3%A4ndig
But if I run:
console.log("encodeURIComponent(this.getAttribute('feld')) = " + encodeURIComponent(this.getAttribute('feld')));
the answer is: encodeURIComponent(this.getAttribute('feld')) = Artname%20vollsta%CC%88ndig
This happens all in the browser. But the issue only appears, when the web-app is served from the webserver (a couchapp running on cloudant.com).
How can it be that the method "getAttribute" returns a different encoding?
The following code has been tested on Chrome 29 OS X, IE 8 Windows XP.
encodeURIComponent("ä") //%C3%A4"
decodeURIComponent("%C3%A4") //ä
so basically "%C3%A4" should be the expected output.
I think the issue here might be encodeURIComponent require a UTF-8 encoding while your server-side language returns something other than this.
encodeURICompoent - MDN
just a follow up in case somebody runs into this issue later.
It seems to be unique to cloudant.com where my couchapp was hosted.
This is the answer I got from their very helpful support:
OK - I think I've found the culprit. The issue is that, due to internal optimisations (which are not present in CouchDB), the form of unicode strings can get changed. In this case, ä is represented as:
U+0061 LATIN SMALL LETTER A character
U+0308 COMBINING DIAERESIS character (̈)
instead of
U+00E4 LATIN SMALL LETTER A WITH DIAERESIS character (ä)
Both are semantically equivalent, so the fix is to normalize your unicode strings before comparison. Unfortunately, JavaScript has no built-in unicode normalization, but you can use a library such ashttps://github.com/walling/unorm.
It's not an issue for me any more as I changed to a virtual server running on digitalocean.com with vanilla couchdb (and am very happy with it).
But I do think this could hit others developing couchapps in German or other languages needing utf8 and hosting them on cloudant.com
Thanks for your great help.
Alex

HTML5 History.pushState mangles URL's containing percent encoded non-Ascii (Unicode) chars

In an OSS web app, we have JS code that performs some Ajax update (uses jQuery, not relevant). After the page update, a call is made to the html5 history interface History.pushState, in the following code:
var updateHistory = function(url) {
var context = { state:1, rand:Math.random() };
/* -----> bedfore the problem call <------- */
History.pushState( context, "Questions", url );
/* -----> after the problem call <------- */
setTimeout(function (){
/* HACK: For some weird reson, sometimes something overrides the above pushState so we re-aplly it
This might be caused by some other JS plugin.
The delay of 10msec allows the other plugin to override the URL.
*/
History.replaceState( context, "Questions", url );
}, 10);
};
[Please note: the full code segment is provided for context, the HACK part is not the issue of this question]
The app is i18n'ed and is using URL encoded Unicode segments in the URL's, so just before the marked problem call in the above code, the URL argument contains (as inspected in Firebug):
"/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/"
The encoded segment is utf-8 in percent encoding. The URL in the browser window is: (just for completeness, doesn't really matter)
http://<base-url>/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/
Just after the call, the URL displayed in the browser window changes to:
http://<base-url>/%C3%98%C2%A7%C3%99%C2%84%C3%98%C2%A3%C3%98%C2%B3%C3%98%C2%A6%C3%99%C2%84%C3%98%C2%A9/scope:all/sort:activity-desc/page:1/
The URL encoded segment is just mojibake, the result of using the wrong encoding at some level. The correct URL would've been:
http://<base-url>/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/
This behavior has been tested on both FF and Chrome.
The history interface specs don't mention anything about encoded URL's, but I assume the default standard for URL formation (utf-8 and percent encoding etc) would apply when using URL's in function calls for the interface.
Any idea on what's going on here.
Edit:
I wasn't paying attention to the uppercase H in History - this code is actually using the History.js wrapper for the history interface. I replaced with a direct call to history.pushState (notice the lowercase h) without going through the wrapper, and the code is working as expected as far as I can tell. The issue with the original code still stands - so an issue with the History.js library it seems.
Update
As Doug S explains in the comments below, the latest version of History.js includes a fix for this behaviour. He also found that my solution caused double-encoding when used in browsers (such as IE 9 and below) which require the hash fallback, so I recommend that instead of using the fix detailed below, just download the latest version.
I've kept my original answer below, since it does explain what's going on in much more detail.
Basel found a resolution of sorts, but there's still some confusion about what's happening under the hood. This answer goes into detail about the problem and suggests a better fix. (You can skip straight to the fix if you want.)
The problem
First, open your browser's JS console and run this:
window.encodeURI(window.unescape('%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9'))
Does that look familiar? It should—that's what your URL is being mangled to. The problem lies in the implementation of History.unescapeString, specifically this line:
tmp = window.unescape(result);
window.unescape is a DOM Level 0 function—which is to say, an unstandardised relic from the hoary days of Netscape 2. It uses the escaping rules defined in RFC 2396, according to which characters outside of the unreserved range (alphanumerics and a small set of punctuation symbols) are encoded as octets.
This works fine for the US-ASCII range, but not all (indeed, the vast majority) of the characters in UTF-8 can be represented in a single byte. Since URIs do not have a built-in way of representing the character set being used, window.unescape just assumes each character maps to a single octet and blithely mangles any that don't.
In this example, the first letter in your URL is the Arabic letter alef (ا), represented by two bytes: 0xD8 0xA7. window.unescape interprets these as two separate characters: 0x00 0xD8 (Ø—capital O with stroke) and 0x00 0xA7 (§—section sign).
This is a known issue with History.js.
The fix
As noted above by the asker, the issue can be sidestepped by using the native implementation of the History API instead of the History.js wrapper, i.e. history.pushState instead of History.pushState.
This works for browsers that support the History API, but loses the benefit of having a polyfill for those that don't. Fortunately, there's a better fix. Open up the History.js source you're referencing and find this line (~1059 in my copy):
tmp = window.unescape(result);
Replace it with:
tmp = window.unescape(encodeURIComponent(result));
Or, if you're using the compressed source, replace a.unescape(c) with a.unescape(encodeURIComponent(c)).
To test this change, I ran the History.js HTML5 jQuery test suite on a local web server inside an Arabic-named directory. Before making the change, test 14 fails; after the change, all tests passed.
Credit
Though I found the problem and solution independently, Damien Antipa deserves credit for finding it first and making a pull request with the fix.
I'm still able to reproduce this in the following case:
History.pushState(null, null, "?" + some_Unicode_String_Or_A_String_With_Whitespace);
document.location.hash += "&someStuff";
In this case the _suid parameter gets removed and &someStuff as well. If the string is not unicode or doesn't have whitespaces (so no % chars) - this does not happen.
This workaround worked for me:
History.pushState(null, null, "?" + some_Unicode_String_Or_A_String_With_Whitespace + "&someStuff");

How can you set up Eclipse to remove trailing whitespace when saving a JavaScript file?

I am running Eclipse 3.6 (Helios 20110218-0911) on Ubuntu 11.04. Under Preferences, I have gone to the following panel:
JavaScript -> Editor -> Save Actions.
The "Additional actions" checkbox is checked and "Remove trailing whitespaces on all lines" is selected.
Nevertheless, when I save my JavaScript file in Eclipse, there is still trailing whitespace at the end of my lines.
What am I missing?
'Save Actions' for JavaScript is available in the JavaScript project(the project with JavaScript nature) only.
(If you can see 'Convert to JavaScript Project' in 'Configure' menu when right-click the project, try it)
I recently faced the same problem. The only way I found is to convert your project to Javascript project. Right click your project folder in the Explorer, choose [Configure] -> [Convert to Javascript project] and the Javascript Save Action will start to work.
Unfortunately, I don't know how to convert it back.
Since it's not a big problem for me, the way Converting it to javascript project indeed helps me a lot.
For the latest Eclipse -
Version: Oxygen.3a Release (4.7.3a)
Build id: 20180405-1200
The default key-binding shift+ctrl+backspace, which binds to the function "Removes the trailing whitespace of each line" will remove trailing space chars for the entire file.
(The key-binding shift+ctrl+backspace is probably already there in many earlier releases as well.)

Validating browser upload file name and extension with simple regex

I got the regexp right. Works perfectly for Firefox ONLY. How would i make this cross browser, cross platform manner. Since it is file name and extension validation you are right i am using File Upload control.
^[a-zA-Z0-9_\.]{3,28}(.pdf|.txt|.doc|.docx|.png|.gif|.jpeg|.jpg|.zip|.rar)$
matches File name must not be empty[ 3, 28 characters long].
Extension must be within the group.
When this works superb in forefox i assume because the fileUpload.value = Filename.extension in firefox. It awfully fails in Google chrome and IE. I am using the above with .net Regular Expression validator and ClientScript enabled.
I know how to validate it on server, so please no server side solutions.
note:
Google chrome:
Provides the fileupload control value as c:\fakePath\filename.extension
IE:
Provides the Full path.
You can't use the ^ to start with if you sometimes have a full path but are only interested in the filename. The dot of the filending should be escaped.
You could try something like this:
[^\\/]{3,}\.(pdf|txt|doc|docx|png|gif|jpeg|jpg|zip|rar)$
As it looks you get only the file with Firefox but the full path with other browsers.
I'd always add a prefix / to your string and than validate the last part after the last fileseprator / or \.
This example uses lookahead to check the fileseparator (or manually added /) before the file and also allows the check of max 28 char for filename. see this online regex tester:
(?<=[\\/])[\w\.]{3,28}\.(?:pdf|txt|doc|docx|png|gif|jpeg|jpg|zip|rar)$
As things stand, your regex validates garbage like the following:
....pdf
____pdf
It also rejects perfectly valid files:
i.jpg
my-pic.jpg
pic.JPG
The easiest is to validate things in multiple steps:
Extract the extension:
\.[a-zA-Z]{3,4}$
Lowercase the extension and validate it against an array of acceptable values.
Optionally validate the file's name (though I'd recommend cleaning it instead):
[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*

Categories