This file is indexed.

/usr/share/pyshared/tftp/netascii.py is in python-txtftp 0.1~bzr38-0ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'''
@author: shylent
'''
# So basically, the idea is that in netascii a *newline* (whatever that is 
# on the current platform) is represented by a CR+LF sequence and a single CR
# is represented by CR+NUL.

from twisted.internet.defer import maybeDeferred, succeed
import os
import re

__all__ = ['NetasciiSenderProxy', 'NetasciiReceiverProxy',
           'to_netascii', 'from_netascii']

CR = '\x0d'
LF = '\x0a'
CRLF = CR + LF
NUL = '\x00'
CRNUL = CR + NUL

NL = os.linesep


re_from_netascii = re.compile('(\x0d\x0a|\x0d\x00)')

def _convert_from_netascii(match_obj):
    if match_obj.group(0) == CRLF:
        return NL
    elif match_obj.group(0) == CRNUL:
        return CR

def from_netascii(data):
    """Convert a netascii-encoded string into a string with platform-specific
    newlines.

    """
    return re_from_netascii.sub(_convert_from_netascii, data)

# So that I can easily switch the NL around in tests
_re_to_netascii = '(%s|\x0d)'
re_to_netascii = re.compile(_re_to_netascii % NL)

def _convert_to_netascii(match_obj):
    if match_obj.group(0) == NL:
        return CRLF
    elif match_obj.group(0) == CR:
        return CRNUL

def to_netascii(data):
    """Convert a string with platform-specific newlines into netascii."""
    return re_to_netascii.sub(_convert_to_netascii, data)

class NetasciiReceiverProxy(object):
    """Proxies an object, that provides L{IWriter}. Incoming data is transformed
    as follows:
        - CR+LF is replaced with the platform-specific newline
        - CR+NUL is replaced with CR

    @param writer: an L{IWriter} object, that will be used to perform the actual writes
    @type writer: L{IWriter} provider

    """

    def __init__(self, writer):
        self.writer = writer
        self._carry_cr = False

    def write(self, data):
        """Attempt a write, performing transformation as described in
        L{NetasciiReceiverProxy}. May write 1 byte less, than provided, if the last
        byte in the chunk is a CR.

        @param data: data to be written
        @type data: C{str}

        @return: L{Deferred}, that will be fired when the write is complete
        @rtype: L{Deferred}

        """
        if self._carry_cr:
            data = CR + data
        data = from_netascii(data)
        if data.endswith(CR):
            self._carry_cr = True
            return maybeDeferred(self.writer.write, data[:-1])
        else:
            self._carry_cr = False
            return maybeDeferred(self.writer.write, data)

    def __getattr__(self, name):
        return getattr(self.writer, name)


class NetasciiSenderProxy(object):
    """Proxies an object, that provides L{IReader}. The data that is read is
    transformed as follows:
        - platform-specific newlines are replaced with CR+LF
        - freestanding CR are replaced with CR+NUL

    @param reader: an L{IReader} object
    @type reader: L{IReader} provider

    """

    def __init__(self, reader):
        self.reader = reader
        self.buffer = ''

    def read(self, size):
        """Attempt to read C{size} bytes, transforming them as described in
        L{NetasciiSenderProxy}.

        @param size: number of bytes to read
        @type size: C{int}

        @return: L{Deferred}, that will be fired with exactly C{size} bytes,
        regardless of the transformation, that was performed if there is more data,
        or less, than C{size} bytes if there is no more data to read.
        @rtype: L{Deferred}

        """
        need_bytes = size - len(self.buffer)
        if need_bytes <= 0:
            data, self.buffer = self.buffer[:size], self.buffer[size:]
            return succeed(data)
        d = maybeDeferred(self.reader.read, need_bytes)
        d.addCallback(self._gotDataFromReader, size)
        return d

    def _gotDataFromReader(self, data, size):
        data = self.buffer + to_netascii(data)
        data, self.buffer = data[:size], data[size:]
        return data

    def __getattr__(self, name):
        return getattr(self.reader, name)