Jump to content

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!

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.