Jump to content

Upload Failed! Not a Dictionary!


applovr

Recommended Posts

Hi again everyone,  :D

 

I'm sure you were all waiting for this error post ;)

 

Here's my problem. I'm running a small BitTorrent tracker for me and some friends, but the upload (essential for a bittorrent tracker) is malfunctioning. Every time I press the upload button, I get a nice error:

 

Upload Failed! Not a Dictionary!

 

I have traced the "not a dictionary" to this function:

 

function dict_check($d, $s) {

if ($d["type"] != "dictionary");
	bark("not a dictionary");					
$a = explode(":", $s);
$dd = $d["value"];
$ret = array();
foreach ($a as $k) {
	unset($t);
	if (preg_match('/^(.*)\((.*)\)$/', $k, $m)) {
		$k = $m[1];
		$t = $m[2];
	}
	if (!isset($dd[$k]))
		bark("dictionary is missing key(s)");
	if (isset($t)) {
		if ($dd[$k]["type"] != $t)
			bark("invalid entry in dictionary");
		$ret[] = $dd[$k]["value"];
	}
	else
		$ret[] = $dd[$k];
}
return $ret;
}

 

Now I don't know what to do to eliminate this error. Can someone please help/tell me if I need to give you more information?

 

:)

 

ALex

Link to comment
https://forums.phpfreaks.com/topic/56383-upload-failed-not-a-dictionary/
Share on other sites

THis is actually part of the TBDEV.net source, so no, I didn't write it. The function is checking SOMETHING in the torrent file, but I really don't know that much about it. I know I'm a complete and total noob :( - but working on that :)

 

I'm not sure what the $d and $s are, so I will check that now.

 

Thanks!

Well, here's the file the function is in - sorry I'm not much help to myself or you yet :( that's what happens when you are brought up on html and asp :P

 

<?
require_once("include/benc.php");
require_once("include/bittorrent.php");

ini_set("upload_max_filesize",$max_torrent_size);

function bark($msg) {
genbark($msg, "Upload failed!");
}

dbconn(); 

loggedinorreturn();

if (get_user_class() < UC_UPLOADER)
  die;

foreach(explode(":","descr:type:name") as $v) {
if (!isset($_POST[$v]))
	bark("missing form data");
}

if (!isset($_FILES["file"]))
bark("missing form data");

$f = $_FILES["file"];
$fname = unesc($f["name"]);
if (empty($fname))
bark("Empty filename!");

$nfofile = $_FILES['nfo'];
if ($nfofile['name'] == '')
  bark("No NFO!");

if ($nfofile['size'] == 0)
  bark("0-byte NFO");

if ($nfofile['size'] > 65535)
  bark("NFO is too big! Max 65,535 bytes.");

$nfofilename = $nfofile['tmp_name'];

if (@!is_uploaded_file($nfofilename))
  bark("NFO upload failed");

$descr = unesc($_POST["descr"]);
if (!$descr)
  bark("You must enter a description!");

$catid = (0 + $_POST["type"]);
if (!is_valid_id($catid))
bark("You must select a category to put the torrent in!");

if (!validfilename($fname))
bark("Invalid filename!");
if (!preg_match('/^(.+)\.torrent$/si', $fname, $matches))
bark("Invalid filename (not a .torrent).");
$shortfname = $torrent = $matches[1];
if (!empty($_POST["name"]))
$torrent = unesc($_POST["name"]);

$tmpname = $f["tmp_name"];
if (!is_uploaded_file($tmpname))
bark("eek");
if (!filesize($tmpname))
bark("Empty file!");

$dict = bdec_file($tmpname, $max_torrent_size);
if (!isset($dict))
bark("What thedid you upload? This is not a bencoded file!");


/*******************************
**      Here's the relevant function      **
*******************************/
function dict_check($d, $s) {
if ($d["type"] != "dictionary")
	bark("not a dictionary");
$a = explode(":", $s);
$dd = $d["value"];
$ret = array();
foreach ($a as $k) {
	unset($t);
	if (preg_match('/^(.*)\((.*)\)$/', $k, $m)) {
		$k = $m[1];
		$t = $m[2];
	}
	if (!isset($dd[$k]))
		bark("dictionary is missing key(s)");
	if (isset($t)) {
		if ($dd[$k]["type"] != $t)
			bark("invalid entry in dictionary");
		$ret[] = $dd[$k]["value"];
	}
	else
		$ret[] = $dd[$k];
}
return $ret;
}

function dict_get($d, $k, $t) {
if ($d["type"] != "dictionary")
	bark("not a dictionary");
$dd = $d["value"];
if (!isset($dd[$k]))
	return;
$v = $dd[$k];
if ($v["type"] != $t)
	bark("invalid dictionary entry type");
return $v["value"];
}

list($ann, $info) = dict_check($dict, "announce(string):info");
list($dname, $plen, $pieces) = dict_check($info, "name(string):piece length(integer):pieces(string)");

if (!in_array($ann, $announce_urls, 1))
bark("invalid announce url! must be <b>" . $announce_urls[0] . "</b>");

if (strlen($pieces) % 20 != 0)
bark("invalid pieces");

$filelist = array();
$totallen = dict_get($info, "length", "integer");
if (isset($totallen)) {
$filelist[] = array($dname, $totallen);
$type = "single";
}
else {
$flist = dict_get($info, "files", "list");
if (!isset($flist))
	bark("missing both length and files");
if (!count($flist))
	bark("no files");
$totallen = 0;
foreach ($flist as $fn) {
	list($ll, $ff) = dict_check($fn, "length(integer):path(list)");
	$totallen += $ll;
	$ffa = array();
	foreach ($ff as $ffe) {
		if ($ffe["type"] != "string")
			bark("filename error");
		$ffa[] = $ffe["value"];
	}
	if (!count($ffa))
		bark("filename error");
	$ffe = implode("/", $ffa);
	$filelist[] = array($ffe, $ll);
}
$type = "multi";
}

$infohash = pack("H*", sha1($info["string"]));


// Replace punctuation characters with spaces

$torrent = str_replace("_", " ", $torrent);

$nfo = sqlesc(str_replace("\x0d\x0d\x0a", "\x0d\x0a", @file_get_contents($nfofilename)));
$ret = mysql_query("INSERT INTO torrents (search_text, filename, owner, visible, info_hash, name, size, numfiles, type, descr, ori_descr, category, save_as, added, last_action, nfo) VALUES (" .
	implode(",", array_map("sqlesc", array(searchfield("$shortfname $dname $torrent"), $fname, $CURUSER["id"], "no", $infohash, $torrent, $totallen, count($filelist), $type, $descr, $descr, 0 + $_POST["type"], $dname))) .
	", '" . get_date_time() . "', '" . get_date_time() . "', $nfo)");
if (!$ret) {
if (mysql_errno() == 1062)
	bark("torrent already uploaded!");
bark("mysql puked: ".mysql_error());
}
$id = mysql_insert_id();

@mysql_query("DELETE FROM files WHERE torrent = $id");
foreach ($filelist as $file) {
@mysql_query("INSERT INTO files (torrent, filename, size) VALUES ($id, ".sqlesc($file[0]).",".$file[1].")");
}

move_uploaded_file($tmpname, "$torrent_dir/$id.torrent");

write_log("Torrent $id ($torrent) was uploaded by " . $CURUSER["username"]);



/* RSS feeds */

if (($fd1 = @fopen("rss.xml", "w")) && ($fd2 = fopen("rssdd.xml", "w")))
{
$cats = "";
$res = mysql_query("SELECT id, name FROM categories");
while ($arr = mysql_fetch_assoc($res))
	$cats[$arr["id"]] = $arr["name"];
$s = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n<rss version=\"0.91\">\n<channel>\n" .
	"<title>TorrentBits</title>\n<description>0-week torrents</description>\n<link>$DEFAULTBASEURL/</link>\n";
@fwrite($fd1, $s);
@fwrite($fd2, $s);
$r = mysql_query("SELECT id,name,descr,filename,category FROM torrents ORDER BY added DESC LIMIT 15") or sqlerr(__FILE__, __LINE__);
while ($a = mysql_fetch_assoc($r))
{
	$cat = $cats[$a["category"]];
	$s = "<item>\n<title>" . htmlspecialchars($a["name"] . " ($cat)") . "</title>\n" .
		"<description>" . htmlspecialchars($a["descr"]) . "</description>\n";
	@fwrite($fd1, $s);
	@fwrite($fd2, $s);
	@fwrite($fd1, "<link>$DEFAULTBASEURL/details.php?id=$a[id]&hit=1</link>\n</item>\n");
	$filename = htmlspecialchars($a["filename"]);
	@fwrite($fd2, "<link>$DEFAULTBASEURL/download.php/$a[id]/$filename</link>\n</item>\n");
}
$s = "</channel>\n</rss>\n";
@fwrite($fd1, $s);
@fwrite($fd2, $s);
@fclose($fd1);
@fclose($fd2);
}

header("Location: $BASEURL/details.php?id=$id&uploaded=1");
?>

and here's a basic bencoding script - I don't know if this will help, but here's how the BitTorrent docs define Bencoding:

Strings are length-prefixed base ten followed by a colon and the string. For example 4:spam corresponds to ‘spam’.

Integers are represented by an ‘i’ followed by the number in base 10 followed by an ‘e’. For example i3e corresponds to 3 and i-3e corresponds to 3. Integers have no size limitation. i0e is invalid. All encodings with a leading zero, such as i03e , are invalid, other than i0e , which of course corresponds to 0.

Lists are encoded as an ‘l’ followed by their elements (also bencoded) followed by an ‘e’. For example l4:spam4:eggse corresponds to [‘spam’, ‘eggs’].

Dictionaries are encoded as a ‘d’ followed by a list of alternating keys and their corresponding values followed by an ‘e’. For example, d3:cow3:moo4:spam4:eggse corresponds to {‘cow’: ‘moo’, ‘spam’: ‘eggs’} and d4:spaml1:a1:bee corresponds to {‘spam’: [‘a’, ‘b’]} . Keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics).

 

and another resource:

http://wiki.theory.org/BitTorrentSpecification#bencoding

 

# b(array('foo' => 42, 'bar' => array(1, 2, 3)))
function s($s){$s="$s";
return(strlen($s).":$s");
}
function b($n){
if(!isset($n))return'0:';
if(is_array($n)){$i=0;
$l=1;
foreach($n as$k=>$v){
if(!is_int($k)||$k!=$i++){$l=0;
break;
}}if($l)return('l'.join('',array_map('b',$n)).'e');
else{$s='d';
ksort($n);
foreach($n as$k=>$v)$s.=s($k).b($v);
return($s.'e');
}}elseif(is_int($n))return"i${n}e";
elseif(is_string($n))return s($n);
}

 

Thanks so much!

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.