rufimelo/DeltaSecommits huggingface dataset:
Vulnerability: libuv before 0.10.34 does not properly drop group privileges, which allows context-dependent attackers to gain privileges via unspecified vectors.
Vulnerability ID: CVE-2015-0278
CWE: CWE-264
Severity score: 10
Project: https://github.com/libuv/libuv
Published: 2015-05-18
File: src/unix/process.c
Commit message: unix: call setgoups before calling setuid/setgid

Partial fix for #1093
Commit author: Saúl Ibarra Corretgé

Vulnerable version (before fix):
 static void uv__process_child_init(const uv_process_options_t* options,     _exit(127);   }    if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {     uv__write_int(error_fd, -errno);     perror("setgid()");

Fixed version (after fix):
 static void uv__process_child_init(const uv_process_options_t* options,     _exit(127);   }    if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {     /* When dropping privileges from root, the `setgroups` call will      * remove any extraneous groups. If we don't call this, then      * even though our uid has dropped, we may still have groups      * that enable us to do super-user things. This will fail if we      * aren't root, so don't bother checking the return value, this      * is just done as an optimistic privilege dropping function.      */     SAVE_ERRNO(setgroups(0, NULL));   }    if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {     uv__write_int(error_fd, -errno);     perror("setgid()");

Patch:
patch: @@ -330,6 +330,17 @@ static void uv__process_child_init(const uv_process_options_t* options,
     _exit(127);
   }
 
+  if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
+    /* When dropping privileges from root, the `setgroups` call will
+     * remove any extraneous groups. If we don't call this, then
+     * even though our uid has dropped, we may still have groups
+     * that enable us to do super-user things. This will fail if we
+     * aren't root, so don't bother checking the return value, this
+     * is just done as an optimistic privilege dropping function.
+     */
+    SAVE_ERRNO(setgroups(0, NULL));
+  }
+
   if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
     uv__write_int(error_fd, -errno);
     perror("setgid()");
path: src/unix/process.c
Vulnerability: daemon/Greeter.cpp in sddm before 0.13.0 does not properly disable the KDE crash handler, which allows local users to gain privileges by crashing a greeter when using certain themes, as demonstrated by the plasma-workspace breeze theme.
Vulnerability ID: CVE-2015-0856
CWE: CWE-264
Severity score: 6.4
Project: https://github.com/sddm/sddm
Published: 2015-11-24
File: src/daemon/Greeter.cpp
Commit message: Disable greeters from loading KDE's debug hander

Some themes may use KDE components which will automatically load KDE's
crash handler.

If the greeter were to then somehow crash, that would leave a crash
handler allowing other actions, albeit as the locked down SDDM user.

Only SDDM users using the breeze theme from plasma-workspace are
affected. Safest and simplest fix is to handle this inside SDDM
disabling kcrash via an environment variable for all future themes that
may use these libraries.

CVE-2015-0856
Commit author: David Edmundson

Vulnerable version (before fix):
 namespace SDDM {             env.insert(QStringLiteral("XDG_VTNR"), QString::number(m_display->terminalId()));             env.insert(QStringLiteral("XDG_SESSION_CLASS"), QStringLiteral("greeter"));             env.insert(QStringLiteral("XDG_SESSION_TYPE"), m_display->sessionType());             m_auth->insertEnvironment(env);              // log message

Fixed version (after fix):
 namespace SDDM {             env.insert(QStringLiteral("XDG_VTNR"), QString::number(m_display->terminalId()));             env.insert(QStringLiteral("XDG_SESSION_CLASS"), QStringLiteral("greeter"));             env.insert(QStringLiteral("XDG_SESSION_TYPE"), m_display->sessionType());              //some themes may use KDE components and that will automatically load KDE's crash handler which we don't want             //counterintuitively setting this env disables that handler             env.insert(QStringLiteral("KDE_DEBUG"), QStringLiteral("1"));             m_auth->insertEnvironment(env);              // log message

Patch:
patch: @@ -145,6 +145,10 @@ namespace SDDM {
             env.insert(QStringLiteral("XDG_VTNR"), QString::number(m_display->terminalId()));
             env.insert(QStringLiteral("XDG_SESSION_CLASS"), QStringLiteral("greeter"));
             env.insert(QStringLiteral("XDG_SESSION_TYPE"), m_display->sessionType());
+
+            //some themes may use KDE components and that will automatically load KDE's crash handler which we don't want
+            //counterintuitively setting this env disables that handler
+            env.insert(QStringLiteral("KDE_DEBUG"), QStringLiteral("1"));
             m_auth->insertEnvironment(env);
 
             // log message
path: src/daemon/Greeter.cpp
Vulnerability: Multiple cross-site scripting (XSS) vulnerabilities in the print_language_selectbox function in classes/adminpage.inc.php in Saurus CMS Community Edition before 4.7 2015-02-04 allow remote attackers to inject arbitrary web script or HTML via unspecified vectors.
Vulnerability ID: CVE-2015-0876
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/sauruscms/Saurus-CMS-Community-Edition
Published: 2015-04-07
File: classes/adminpage.inc.php
Commit message: Fix stored and reflected XSS vulnerabilities

as described in VN: JVN#18387086 / TN: JPCERT#95011159 advisory.
Commit author: Reigo

Vulnerable version (before fix):
 function print_language_selectbox() {     <table border="0" cellspacing="0" cellpadding="1"> 	<form name="languageform" method=get> 	<? foreach($site->fdat as $fdat_field=>$fdat_value) { 		if($fdat_field != 'flt_keel') {?> 		<input type=hidden name="<?=$fdat_field?>" value="<?=$fdat_value?>"> 	<?	}

Fixed version (after fix):
 function print_language_selectbox() {     <table border="0" cellspacing="0" cellpadding="1"> 	<form name="languageform" method=get> 	<? foreach($site->fdat as $fdat_field=>$fdat_value) { 		$fdat_value = htmlspecialchars(xss_clean($fdat_value)); 		$fdat_field = htmlspecialchars(xss_clean($fdat_field));  		if($fdat_field != 'flt_keel') {?> 		<input type=hidden name="<?=$fdat_field?>" value="<?=$fdat_value?>"> 	<?	}

Patch:
patch: @@ -302,6 +302,8 @@ function print_language_selectbox() {
     <table border="0" cellspacing="0" cellpadding="1">
 	<form name="languageform" method=get>
 	<? foreach($site->fdat as $fdat_field=>$fdat_value) {
+		$fdat_value = htmlspecialchars(xss_clean($fdat_value));
+		$fdat_field = htmlspecialchars(xss_clean($fdat_field)); 
 		if($fdat_field != 'flt_keel') {?>
 		<input type=hidden name="<?=$fdat_field?>" value="<?=$fdat_value?>">
 	<?	}
path: classes/adminpage.inc.php
Vulnerability: Memory leak in the __key_link_end function in security/keys/keyring.c in the Linux kernel before 4.1.4 allows local users to cause a denial of service (memory consumption) via many add_key system calls that refer to existing keys.
Vulnerability ID: CVE-2015-1333
CWE: CWE-119
Severity score: 6.9
Project: https://github.com/torvalds/linux
Published: 2015-08-31
File: security/keys/keyring.c
Commit message: KEYS: ensure we free the assoc array edit if edit is valid

__key_link_end is not freeing the associated array edit structure
and this leads to a 512 byte memory leak each time an identical
existing key is added with add_key().

The reason the add_key() system call returns okay is that
key_create_or_update() calls __key_link_begin() before checking to see
whether it can update a key directly rather than adding/replacing - which
it turns out it can.  Thus __key_link() is not called through
__key_instantiate_and_link() and __key_link_end() must cancel the edit.

CVE-2015-1333

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
Commit author: Colin Ian King

Vulnerable version (before fix):
 void __key_link_end(struct key *keyring, 	if (index_key->type == &key_type_keyring) 		up_write(&keyring_serialise_link_sem);  	if (edit && !edit->dead_leaf) { 		key_payload_reserve(keyring, 				    keyring->datalen - KEYQUOTA_LINK_BYTES); 		assoc_array_cancel_edit(edit); 	} 	up_write(&keyring->sem);

Fixed version (after fix):
 void __key_link_end(struct key *keyring, 	if (index_key->type == &key_type_keyring) 		up_write(&keyring_serialise_link_sem);  	if (edit) { 		if (!edit->dead_leaf) { 			key_payload_reserve(keyring, 				keyring->datalen - KEYQUOTA_LINK_BYTES); 		} 		assoc_array_cancel_edit(edit); 	} 	up_write(&keyring->sem);

Patch:
patch: @@ -1181,9 +1181,11 @@ void __key_link_end(struct key *keyring,
 	if (index_key->type == &key_type_keyring)
 		up_write(&keyring_serialise_link_sem);
 
-	if (edit && !edit->dead_leaf) {
-		key_payload_reserve(keyring,
-				    keyring->datalen - KEYQUOTA_LINK_BYTES);
+	if (edit) {
+		if (!edit->dead_leaf) {
+			key_payload_reserve(keyring,
+				keyring->datalen - KEYQUOTA_LINK_BYTES);
+		}
 		assoc_array_cancel_edit(edit);
 	}
 	up_write(&keyring->sem);
path: security/keys/keyring.c
Vulnerability: Memory leak in the cuse_channel_release function in fs/fuse/cuse.c in the Linux kernel before 4.4 allows local users to cause a denial of service (memory consumption) or possibly have unspecified other impact by opening /dev/cuse many times.
Vulnerability ID: CVE-2015-1339
CWE: CWE-399
Severity score: 6.9
Project: https://github.com/torvalds/linux
Published: 2016-04-27
File: fs/fuse/cuse.c
Commit message: cuse: fix memory leak

The problem is that fuse_dev_alloc() acquires an extra reference to cc.fc,
and the original ref count is never dropped.

Reported-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Fixes: cc080e9e9be1 ("fuse: introduce per-instance fuse_dev structure")
Cc: <stable@vger.kernel.org> # v4.2+
Commit author: Miklos Szeredi

Vulnerable version (before fix):
 static int cuse_channel_release(struct inode *inode, struct file *file) 		unregister_chrdev_region(cc->cdev->dev, 1); 		cdev_del(cc->cdev); 	}  	rc = fuse_dev_release(inode, file);	/* puts the base reference */ 

Fixed version (after fix):
 static int cuse_channel_release(struct inode *inode, struct file *file) 		unregister_chrdev_region(cc->cdev->dev, 1); 		cdev_del(cc->cdev); 	} 	/* Base reference is now owned by "fud" */ 	fuse_conn_put(&cc->fc);  	rc = fuse_dev_release(inode, file);	/* puts the base reference */ 

Patch:
patch: @@ -549,6 +549,8 @@ static int cuse_channel_release(struct inode *inode, struct file *file)
 		unregister_chrdev_region(cc->cdev->dev, 1);
 		cdev_del(cc->cdev);
 	}
+	/* Base reference is now owned by "fud" */
+	fuse_conn_put(&cc->fc);
 
 	rc = fuse_dev_release(inode, file);	/* puts the base reference */
path: fs/fuse/cuse.c
Vulnerability: Cross-site scripting (XSS) vulnerability in client.inc.php in osTicket before 1.9.5.1 allows remote attackers to inject arbitrary web script or HTML via the lang parameter.
Vulnerability ID: CVE-2015-1347
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/osTicket/osTicket-1.8
Published: 2015-01-23
File: client.inc.php
Commit message: xss: Fix possible vuln setting client lang pref
Commit author: Jared Hancock

Vulnerable version (before fix):
 $thisclient = UserAuthenticationBackend::getUser();  if (isset($_GET['lang']) && $_GET['lang']) {     $_SESSION['client:lang'] = $_GET['lang']; }  // Bootstrap gettext translations as early as possible, but after attempting

Fixed version (after fix):
 $thisclient = UserAuthenticationBackend::getUser();  if (isset($_GET['lang']) && $_GET['lang']) {     if (Internationalization::getLanguageInfo($_GET['lang']))         $_SESSION['client:lang'] = $_GET['lang']; }  // Bootstrap gettext translations as early as possible, but after attempting

Patch:
patch: @@ -48,7 +48,8 @@
 $thisclient = UserAuthenticationBackend::getUser();
 
 if (isset($_GET['lang']) && $_GET['lang']) {
-    $_SESSION['client:lang'] = $_GET['lang'];
+    if (Internationalization::getLanguageInfo($_GET['lang']))
+        $_SESSION['client:lang'] = $_GET['lang'];
 }
 
 // Bootstrap gettext translations as early as possible, but after attempting
path: client.inc.php
Vulnerability: The message_options function in includes/ucp/ucp_pm_options.php in phpBB before 3.0.13 does not properly validate the form key, which allows remote attackers to conduct CSRF attacks and change the full folder setting via unspecified vectors.
Vulnerability ID: CVE-2015-1432
CWE: CWE-352
Severity score: 6.4
Project: https://github.com/phpbb/phpbb
Published: 2015-02-10
File: phpBB/includes/ucp/ucp_pm_options.php
Commit message: [ticket/13526] Correctly validate the ucp_pm_options form key.

PHPBB3-13526
Commit author: Joas Schilling

Vulnerable version (before fix):
 function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit 	// Change "full folder" setting - what to do if folder is full 	if (isset($_POST['fullfolder'])) 	{ 		check_form_key('ucp_pm_options', $config['form_token_lifetime'], $redirect_url); 		$full_action = request_var('full_action', 0);  		$set_folder_id = 0;

Fixed version (after fix):
 function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit 	// Change "full folder" setting - what to do if folder is full 	if (isset($_POST['fullfolder'])) 	{ 		if (!check_form_key('ucp_pm_options')) 		{ 			trigger_error('FORM_INVALID'); 		}  		$full_action = request_var('full_action', 0);  		$set_folder_id = 0;

Patch:
patch: @@ -29,7 +29,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
 	// Change "full folder" setting - what to do if folder is full
 	if (isset($_POST['fullfolder']))
 	{
-		check_form_key('ucp_pm_options', $config['form_token_lifetime'], $redirect_url);
+		if (!check_form_key('ucp_pm_options'))
+		{
+			trigger_error('FORM_INVALID');
+		}
+
 		$full_action = request_var('full_action', 0);
 
 		$set_folder_id = 0;
path: phpBB/includes/ucp/ucp_pm_options.php
Vulnerability: SQL injection vulnerability in userprofile.lib.php in Pragyan CMS 3.0 allows remote attackers to execute arbitrary SQL commands via the user parameter to the default URI.
Vulnerability ID: CVE-2015-1471
CWE: CWE-89
Severity score: 6.4
Project: https://github.com/delta/pragyan
Published: 2015-02-12
File: index.php
Commit message: Update index.php
Commit author: Nivash Srinivasa Ragavan

Vulnerable version (before fix):
 ///Case 2 : request for a user profile page else if(isset($_GET['user'])) { 	$publicPageRequest = true; 	$userProfileId = $_GET['user']; 	//This is just to prevent parsing a NULL url when someone misplaces the code for User profile parser 	$pageFullPath = "home"; }

Fixed version (after fix):
 ///Case 2 : request for a user profile page else if(isset($_GET['user'])) { 	$publicPageRequest = true; 	$userProfileId = safe_html(escape($_GET['user'])); 	//This is just to prevent parsing a NULL url when someone misplaces the code for User profile parser 	$pageFullPath = "home"; }

Patch:
patch: @@ -144,7 +144,7 @@
 ///Case 2 : request for a user profile page
 else if(isset($_GET['user'])) {
 	$publicPageRequest = true;
-	$userProfileId = $_GET['user'];
+	$userProfileId = safe_html(escape($_GET['user']));
 	//This is just to prevent parsing a NULL url when someone misplaces the code for User profile parser
 	$pageFullPath = "home";
 }
path: index.php
Vulnerability: The BN_GF2m_mod_inv function in crypto/bn/bn_gf2m.c in OpenSSL before 0.9.8s, 1.0.0 before 1.0.0e, 1.0.1 before 1.0.1n, and 1.0.2 before 1.0.2b does not properly handle ECParameters structures in which the curve is over a malformed binary polynomial field, which allows remote attackers to cause a denial of service (infinite loop) via a session that uses an Elliptic Curve algorithm, as demonstrated by an attack against a server that supports client authentication.
Vulnerability ID: CVE-2015-1788
CWE: CWE-399
Severity score: 2.9
Project: https://github.com/openssl/openssl
Published: 2015-06-12
File: crypto/bn/bn_gf2m.c
Commit message: bn/bn_gf2m.c: avoid infinite loop wich malformed ECParamters.

CVE-2015-1788

Reviewed-by: Matt Caswell <matt@openssl.org>
Commit author: Andy Polyakov

Vulnerable version (before fix):
 int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)     } # else     {         int i, ubits = BN_num_bits(u), vbits = BN_num_bits(v), /* v is copy                                                                 * of p */             top = p->top;         BN_ULONG *udp, *bdp, *vdp, *cdp;          bn_wexpand(u, top); int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)                 ubits--;             }              if (ubits <= BN_BITS2 && udp[0] == 1)                 break;              if (ubits < vbits) {                 i = ubits;

Fixed version (after fix):
 int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)     } # else     {         int i;         int ubits = BN_num_bits(u);         int vbits = BN_num_bits(v); /* v is copy of p */         int top = p->top;         BN_ULONG *udp, *bdp, *vdp, *cdp;          bn_wexpand(u, top); int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)                 ubits--;             }              if (ubits <= BN_BITS2) {                 if (udp[0] == 0) /* poly was reducible */                     goto err;                 if (udp[0] == 1)                     break;             }              if (ubits < vbits) {                 i = ubits;

Patch:
patch: @@ -691,9 +691,10 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     }
 # else
     {
-        int i, ubits = BN_num_bits(u), vbits = BN_num_bits(v), /* v is copy
-                                                                * of p */
-            top = p->top;
+        int i;
+        int ubits = BN_num_bits(u);
+        int vbits = BN_num_bits(v); /* v is copy of p */
+        int top = p->top;
         BN_ULONG *udp, *bdp, *vdp, *cdp;
 
         bn_wexpand(u, top);
@@ -737,8 +738,12 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                 ubits--;
             }
 
-            if (ubits <= BN_BITS2 && udp[0] == 1)
-                break;
+            if (ubits <= BN_BITS2) {
+                if (udp[0] == 0) /* poly was reducible */
+                    goto err;
+                if (udp[0] == 1)
+                    break;
+            }
 
             if (ubits < vbits) {
                 i = ubits;
path: crypto/bn/bn_gf2m.c
Vulnerability: The InvertibleRWFunction::CalculateInverse function in rw.cpp in libcrypt++ 5.6.2 does not properly blind private key operations for the Rabin-Williams digital signature algorithm, which allows remote attackers to obtain private keys via a timing attack.
Vulnerability ID: CVE-2015-2141
CWE: CWE-200
Severity score: 2.9
Project: https://github.com/weidai11/cryptopp
Published: 2015-07-01
File: rw.cpp
Commit message: Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting. Squaring to satisfy Jacobi requirements suggested by JPM.
Commit author: Jeffrey Walton

Vulnerable version (before fix):
 Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const 	DoQuickSanityCheck(); 	ModularArithmetic modn(m_n); 	Integer r, rInv; 	do {	// do this in a loop for people using small numbers for testing 		r.Randomize(rng, Integer::One(), m_n - Integer::One()); 		rInv = modn.MultiplicativeInverse(r); 	} while (rInv.IsZero()); 	Integer re = modn.Square(r); 	re = modn.Multiply(re, x);			// blind 

Fixed version (after fix):
 Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const 	DoQuickSanityCheck(); 	ModularArithmetic modn(m_n); 	Integer r, rInv;  	// do this in a loop for people using small numbers for testing 	do { 		r.Randomize(rng, Integer::One(), m_n - Integer::One()); 		// Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting. 		// Squaring to satisfy Jacobi requirements suggested by JPM. 		r = modn.Square(r); 		rInv = modn.MultiplicativeInverse(r); 	} while (rInv.IsZero());  	Integer re = modn.Square(r); 	re = modn.Multiply(re, x);			// blind 

Patch:
patch: @@ -126,10 +126,16 @@ Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const
 	DoQuickSanityCheck();
 	ModularArithmetic modn(m_n);
 	Integer r, rInv;
-	do {	// do this in a loop for people using small numbers for testing
+
+	// do this in a loop for people using small numbers for testing
+	do {
 		r.Randomize(rng, Integer::One(), m_n - Integer::One());
+		// Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting.
+		// Squaring to satisfy Jacobi requirements suggested by JPM.
+		r = modn.Square(r);
 		rInv = modn.MultiplicativeInverse(r);
 	} while (rInv.IsZero());
+
 	Integer re = modn.Square(r);
 	re = modn.Multiply(re, x);			// blind
path: rw.cpp
Vulnerability: node/utils/ExportEtherpad.js in Etherpad 1.5.x before 1.5.2 might allow remote attackers to obtain sensitive information by leveraging an improper substring check when exporting a padID.
Vulnerability ID: CVE-2015-2298
CWE: CWE-200
Severity score: 2.9
Project: https://github.com/ether/etherpad-lite
Published: 2018-01-12
File: src/node/utils/ExportEtherpad.js
Commit message: oops, fix export with wildcards
Commit author: webzwo0i

Vulnerable version (before fix):
 exports.getPadRaw = function(padId, callback){   async.waterfall([   function(cb){      // Get the Pad available content keys     db.findKeys("pad:"+padId+"*", null, function(err,records){       if(!err){         cb(err, records);       }     })

Fixed version (after fix):
 exports.getPadRaw = function(padId, callback){   async.waterfall([   function(cb){      // Get the Pad     db.findKeys("pad:"+padId, null, function(err,padcontent){       if(!err){         cb(err, padcontent);       }     })   },   function(padcontent,cb){      // Get the Pad available content keys     db.findKeys("pad:"+padId+":*", null, function(err,records){       if(!err){         for (var key in padcontent) { records.push(padcontent[key]);}         cb(err, records);       }     })

Patch:
patch: @@ -23,9 +23,19 @@ exports.getPadRaw = function(padId, callback){
   async.waterfall([
   function(cb){
 
+    // Get the Pad
+    db.findKeys("pad:"+padId, null, function(err,padcontent){
+      if(!err){
+        cb(err, padcontent);
+      }
+    })
+  },
+  function(padcontent,cb){
+
     // Get the Pad available content keys
-    db.findKeys("pad:"+padId+"*", null, function(err,records){
+    db.findKeys("pad:"+padId+":*", null, function(err,records){
       if(!err){
+        for (var key in padcontent) { records.push(padcontent[key]);}
         cb(err, records);
       }
     })
path: src/node/utils/ExportEtherpad.js