Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9124239
search.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Subscribers
None
search.js
View Options
/**
* Search page management
* Args:
* textForm: the form containing the text input, if any
* fileForm: the form containing the file input, if any
* messageElem: the element that should display search messages
*/
var
SearchFormController
=
function
(
textForm
,
fileForm
,
messageElem
)
{
this
.
textForm
=
textForm
;
this
.
fileForm
=
fileForm
;
this
.
messageElem
=
messageElem
;
// List of hashes to check against files being processed
this
.
hashed_already
=
{
'sha1'
:
{},
'sha256'
:
{},
'sha1_git'
:
{}
};
this
.
algos
=
[
'sha1'
,
'sha256'
,
'sha1_git'
];
this
.
CHECKSUM_RE
=
/^([0-9a-f]{40}|[0-9a-f]{64})$/i
;
var
self
=
this
;
/**
* Show search messages on the page
* Args:
* msg: the message to show
*/
this
.
searchMessage
=
function
(
msg
)
{
self
.
messageElem
.
empty
();
self
.
messageElem
.
text
(
msg
);
};
/**
* Setup the text field
* Args:
* textFormInput: the text form's input
*/
this
.
setupTextForm
=
function
(
textFormInput
)
{
self
.
textForm
.
submit
(
function
(
event
)
{
var
q
=
textFormInput
.
val
();
if
(
!
q
)
{
event
.
preventDefault
();
self
.
searchMessage
(
"Please enter a SHA-1 or SHA-256 checksum."
);
}
else
if
(
q
&&
!
q
.
match
(
self
.
CHECKSUM_RE
))
{
event
.
preventDefault
();
self
.
searchMessage
(
"Invalid SHA-1 or SHA-256 checksum"
);
}
});
};
/**
* Setup the file drag&drop UI and hashing support.
* Args:
* fileDropElem: the element receptive to drag & drop
* hashedListerElem: the element that receives the hased file descriptions
* fileFormInput: the input that actually receives files
* clearButton: the button used to clear currently hashed files
*/
this
.
setupFileForm
=
function
(
fileDropElem
,
hashedListerElem
,
fileFormInput
,
clearButton
)
{
if
(
!
FileReader
||
!
CryptoJS
)
{
self
.
searchMessage
(
"Client-side file hashing is not available for your browser."
);
return
;
}
// Enable clicking on the text element for file picker
fileDropElem
.
click
(
function
(
event
)
{
event
.
preventDefault
();
fileFormInput
.
click
();
});
// Enable drag&drop
var
makeDroppable
=
function
(
fileReceptionElt
)
{
var
fileshovering
=
false
;
fileReceptionElt
.
on
(
'dragover'
,
function
(
event
)
{
event
.
stopPropagation
();
event
.
preventDefault
();
});
fileReceptionElt
.
on
(
'dragenter'
,
function
(
event
)
{
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
!
fileshovering
)
{
fileReceptionElt
.
css
(
"border-style"
,
"solid"
);
fileReceptionElt
.
css
(
"box-shadow"
,
"inset 0 3px 4px"
);
fileshovering
=
true
;
}
});
fileReceptionElt
.
on
(
'dragover'
,
function
(
event
)
{
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
!
fileshovering
)
{
fileReceptionElt
.
css
(
"border-style"
,
"solid"
);
fileReceptionElt
.
css
(
"box-shadow"
,
"inset 0 3px 4px"
);
fileshovering
=
true
;
}
});
fileReceptionElt
.
on
(
'dragleave'
,
function
(
event
)
{
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
fileshovering
)
{
fileReceptionElt
.
css
(
"border-style"
,
"dashed"
);
fileReceptionElt
.
css
(
"box-shadow"
,
"none"
);
fileshovering
=
false
;
}
});
fileReceptionElt
.
on
(
'drop'
,
function
(
event
)
{
event
.
stopPropagation
();
event
.
preventDefault
();
if
(
fileshovering
)
{
fileReceptionElt
.
css
(
"border-style"
,
"dashed"
);
fileReceptionElt
.
css
(
"box-shadow"
,
"none"
);
fileshovering
=
false
;
}
var
myfiles
=
event
.
originalEvent
.
dataTransfer
.
files
;
readAndHash
(
myfiles
);
});
};
makeDroppable
(
fileDropElem
);
// Connect input change and rehash
var
makeInputChange
=
function
(
fileInput
)
{
return
fileInput
.
each
(
function
()
{
$
(
this
).
on
(
'change'
,
function
(){
readAndHash
(
this
.
files
);
});
});
};
makeInputChange
(
fileFormInput
);
// Connect clear button
var
makeClearButton
=
function
(
button
)
{
return
button
.
each
(
function
()
{
$
(
this
).
click
(
function
(
event
)
{
event
.
preventDefault
();
hashedListerElem
.
empty
();
self
.
fileForm
.
children
(
'.search-hidden'
).
remove
();
self
.
hashed_already
=
{
'sha1'
:
{},
'sha256'
:
{},
'sha1_git'
:
{}
};
});
});
};
makeClearButton
(
clearButton
);
var
readAndHash
=
function
(
filelist
)
{
for
(
var
file_idx
=
0
;
file_idx
<
filelist
.
length
;
file_idx
++
)
{
var
file
=
filelist
.
item
(
file_idx
);
var
fr
=
new
FileReader
();
bindReader
(
fr
,
file
.
name
);
fr
.
readAsArrayBuffer
(
file
);
}
};
var
bindReader
=
function
(
freader
,
fname
)
{
freader
.
onloadend
=
function
(
event
)
{
if
(
event
.
target
.
readyState
==
FileReader
.
DONE
)
return
dedupAndAdd
(
event
.
target
.
result
,
fname
);
else
return
null
;
};
};
/**
* Hash the buffer with SHA-1, SHA-1_GIT, SHA-256
* Args:
* buffer: the buffer to hash
* fname: the file name corresponding to the buffer
* Returns:
* a dict of algo_hash: hash
*/
var
hashBuffer
=
function
(
buffer
,
fname
)
{
function
str2ab
(
header
)
{
var
buf
=
new
ArrayBuffer
(
header
.
length
);
var
view
=
new
Uint8Array
(
buf
);
// byte view, all we need is ASCII
for
(
var
idx
=
0
,
len
=
header
.
length
;
idx
<
len
;
idx
++
)
view
[
idx
]
=
header
.
charCodeAt
(
idx
);
return
buf
;
}
var
content_array
=
CryptoJS
.
lib
.
WordArray
.
create
(
buffer
);
var
git_hd_str
=
'blob '
+
buffer
.
byteLength
+
'\0'
;
var
git_hd_buffer
=
str2ab
(
git_hd_str
);
var
git_hd_array
=
CryptoJS
.
lib
.
WordArray
.
create
(
git_hd_buffer
);
var
sha1
=
CryptoJS
.
SHA1
(
content_array
);
var
sha256
=
CryptoJS
.
SHA256
(
content_array
);
var
sha1_git
=
CryptoJS
.
SHA1
(
git_hd_array
.
concat
(
content_array
));
return
{
'sha1'
:
sha1
+
''
,
'sha256'
:
sha256
+
''
,
'sha1_git'
:
sha1_git
+
''
};
};
/**
* Hash the buffer and add it to the form if it is unique
* If not, display which file has the same content
* Args:
* buffer: the buffer to hash
* fname: the file name corresponding to the buffer
*/
var
dedupAndAdd
=
function
(
buffer
,
fname
)
{
var
hashes
=
hashBuffer
(
buffer
);
var
has_duplicate
=
false
;
for
(
var
algo_s
in
hashes
)
{
if
(
self
.
hashed_already
[
algo_s
][
hashes
[
algo_s
]]
!=
undefined
)
{
// Duplicate content -- fileLister addition only, as duplicate
hashedListerElem
.
append
(
$
(
'<div>'
)
.
addClass
(
'span3'
)
.
text
(
fname
+
': duplicate of '
+
self
.
hashed_already
[
algo_s
][
hashes
[
algo_s
]]));
has_duplicate
=
true
;
break
;
}
}
// First file read with this content -- fileLister and form addition
if
(
!
has_duplicate
)
{
// Add to hashed list
for
(
var
algo_c
in
self
.
hashed_already
)
self
.
hashed_already
[
algo_c
][
hashes
[
algo_c
]]
=
fname
;
hashedListerElem
.
append
(
$
(
'<div>'
)
.
addClass
(
'span3'
)
.
text
(
fname
));
var
hashstring
=
JSON
.
stringify
(
hashes
).
replace
(
'\"'
,
'\''
);
self
.
fileForm
.
append
(
$
(
"<input>"
,
{
type
:
'hidden'
,
class
:
'search-hidden'
,
name
:
fname
,
value
:
hashes
[
'sha1'
]}
// hashstring}
));
}
};
};
};
File Metadata
Details
Attached
Mime Type
text/x-asm
Expires
Sat, Jun 21, 6:52 PM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3353175
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment